package org.mercury_im.messenger.ui.chat;

import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.impl.JidCreate;
import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.R;

import java.util.UUID;

import butterknife.BindView;
import butterknife.ButterKnife;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;

public class ChatActivity extends AppCompatActivity
        implements ChatInputFragment.OnChatInputActionListener, SearchView.OnQueryTextListener {

    public static final String EXTRA_JID = "JID";
    public static final String EXTRA_ACCOUNT = "ACCOUNT";

    @BindView(R.id.toolbar)
    Toolbar toolbar;

    @BindView(R.id.recyclerView)
    RecyclerView recyclerView;

    private final MessagesRecyclerViewAdapter recyclerViewAdapter = new MessagesRecyclerViewAdapter();

    private ChatViewModel chatViewModel;

    private final CompositeDisposable disposable = new CompositeDisposable();

    private EntityBareJid jid;

    private UUID accountId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("Mercury", "onCreate");
        setContentView(R.layout.activity_chat);
        ButterKnife.bind(this);

        MercuryImApplication.getApplication().getAppComponent().inject(this);

        if (savedInstanceState == null) {
            savedInstanceState = getIntent().getExtras();
            if (savedInstanceState == null) return;
        }

        setSupportActionBar(toolbar);
        // Show back arrow
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        recyclerView.setAdapter(recyclerViewAdapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        String jidString = savedInstanceState.getString(EXTRA_JID);
        if (jidString != null) {
            jid = JidCreate.entityBareFromOrThrowUnchecked(jidString);
            // JID will never change, so just set it once
            getSupportActionBar().setSubtitle(jid.asUnescapedString());
            accountId = UUID.fromString(savedInstanceState.getString(EXTRA_ACCOUNT));

            chatViewModel = new ViewModelProvider(this).get(ChatViewModel.class);
            chatViewModel.init(accountId, jid);
            // Listen for updates to contact information and messages
            observeViewModel(chatViewModel);
        }
    }

    public void observeViewModel(ChatViewModel viewModel) {
        viewModel.getContactDisplayName().observe(this,
                name -> getSupportActionBar().setTitle(name));

        viewModel.getMessages().observe(this, messageModels -> {
            recyclerViewAdapter.updateMessages(messageModels);
            recyclerView.scrollToPosition(messageModels.size() - 1);
        });
    }

    public void onStop() {
        super.onStop();
        disposable.clear();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_chat, menu);

        final MenuItem searchItem = menu.findItem(R.id.action_search);
        final SearchView searchView = (SearchView) searchItem.getActionView();
        searchView.setOnQueryTextListener(this);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_debug:
                Log.d("CHATACTIVITY", "Fetch MAM messages!");
                chatViewModel.requestMamMessages()
                        .subscribeOn(Schedulers.io())
                        .subscribe();
                break;

            // menu_chat
            case R.id.action_call:
            case R.id.action_clear_history:
            case R.id.action_notification_settings:
            case R.id.action_delete_chat:

                // long_click_message
            case R.id.action_edit_message:
            case R.id.action_reply_message:
            case R.id.action_copy_message:
            case R.id.action_forward_message:
            case R.id.action_delete_message:
            case R.id.action_message_details:

                // short_click_message
            case R.id.action_react_message:

                Toast.makeText(this, R.string.not_yet_implemented, Toast.LENGTH_SHORT).show();
                return true;
        }
        return false;
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        outState.putString(EXTRA_JID, jid.toString());
        outState.putString(EXTRA_ACCOUNT, accountId.toString());
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onButtonEmojiClicked() {
        Toast.makeText(this, R.string.not_yet_implemented, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onButtonMediaClicked() {
        Toast.makeText(this, R.string.not_yet_implemented, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onComposingBodyChanged(String body) {

    }

    @Override
    public void onComposingBodySend(String body) {
        String msg = body.trim();
        if (msg.isEmpty()) {
            return;
        }

        /*
        // TODO: Improve by using rx
        new Thread() {
            @Override
            public void run() {
                try {
                    ChatManager.getInstanceFor(connectionCenter.getConnection(accountId).getConnection())
                            .chatWith(jid).send(msg);
                } catch (SmackException.NotConnectedException e) {
                    Logger.getAnonymousLogger().log(Level.SEVERE,"NotConnectedException : \n" + e.getStackTrace().toString());
                } catch (InterruptedException e) {
                    Logger.getAnonymousLogger().log(Level.SEVERE,"InterruptedException" + e.getStackTrace().toString());
                }
            }
        }.start();

         */
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        // Ignore. Logic is in onQueryTextChange.
        return false;
    }

    @Override
    public boolean onQueryTextChange(String query) {
        chatViewModel.queryTextChanged(query);
        return false;
    }

    @Override
    public boolean onSupportNavigateUp() {
        // Go back when left arrow is pressed in toolbar
        onBackPressed();
        return true;
    }
}
