package org.mercury_im.messenger.android.ui.chat;

import android.content.Intent;
import android.os.Bundle;
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.mercury_im.messenger.android.MercuryImApplication;
import org.mercury_im.messenger.R;
import org.mercury_im.messenger.android.ui.MercuryActivity;
import org.mercury_im.messenger.android.util.ArgumentUtils;
import org.mercury_im.messenger.entity.contact.Peer;
import org.mercury_im.messenger.android.ui.contacts.detail.ContactDetailActivity;

import java.util.UUID;

import butterknife.BindView;
import butterknife.ButterKnife;
import io.reactivex.disposables.CompositeDisposable;
import lombok.Value;

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

    public static final String EXTRA_CHAT_ID = "CHAT_ID";

    private final MessagesRecyclerViewAdapter recyclerViewAdapter = new MessagesRecyclerViewAdapter();

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

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

    private AndroidChatViewModel androidChatViewModel;
    private UUID chatId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MercuryImApplication.getApplication().getAppComponent().inject(this);

        Arguments arguments = getArguments(savedInstanceState);
        chatId = arguments.getChatId();

        androidChatViewModel = new ViewModelProvider(this).get(AndroidChatViewModel.class);
        androidChatViewModel.init(chatId);

        bindUiComponents();
        observeViewModel(androidChatViewModel);
    }

    private void bindUiComponents() {
        setContentView(R.layout.activity_chat);
        ButterKnife.bind(this);

        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        toolbar.setOnClickListener(v -> {
            Intent intent = new Intent(ChatActivity.this, ContactDetailActivity.class);
            intent.putExtra(ContactDetailActivity.EXTRA_PEER_ID, androidChatViewModel.getContactId());
            ChatActivity.this.startActivity(intent);
        });

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

    }

    public void observeViewModel(AndroidChatViewModel viewModel) {
        viewModel.getContactDisplayName().observe(this,
                name -> getSupportActionBar().setTitle(name));
        viewModel.getContact().observe(this,
                contact -> getSupportActionBar().setSubtitle(contact.getJid()));

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

    @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:
                Peer peer = androidChatViewModel.getContact().getValue();
                Toast.makeText(this, "subscription: " + peer.getSubscriptionDirection().toString() +
                        " isApproved: " + peer.isSubscriptionApproved() + " isPending: " + peer.isSubscriptionPending(), Toast.LENGTH_SHORT).show();
                break;

            // menu_chat
            case R.id.action_delete_contact:
                androidChatViewModel.deleteContact();
                break;
            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_CHAT_ID, chatId.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;
        }

        androidChatViewModel.sendMessage(msg);
    }

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

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

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

    private Arguments getArguments(Bundle savedInstanceState) {
        savedInstanceState = requiredExtras(savedInstanceState, getIntent());
        UUID chatId = ArgumentUtils.requireUUID(savedInstanceState, EXTRA_CHAT_ID);
        return new Arguments(chatId);
    }

    @Value
    private class Arguments {
        UUID chatId;
    }
}
