package com.lemenzo.contacts;
import android.content.Intent;

import android.app.*;
import android.content.*;
import android.os.*;
import android.view.*;
import android.widget.*;
import java.util.*;
import java.util.concurrent.*;

public class GroupDetailActivity extends Activity {
    private static final int REQ_ADD_MEMBERS=531;
    private long groupId;
    private String groupTitle;
    private ContactsRepository repo;
    private LinearLayout root;
    private ContactAdapter adapter;
    private final ExecutorService io=Executors.newSingleThreadExecutor(r->new Thread(r,"LemenzoContacts-Group"));
    private final Handler main=new Handler(Looper.getMainLooper());
    private volatile boolean destroyed;
    private int generation;

    @Override public void onCreate(Bundle b){
        super.onCreate(b);
        groupId=getIntent().getLongExtra("group_id",-1);
        groupTitle=getIntent().getStringExtra("group_title");
        repo=new ContactsRepository(this);
        renderShell();
        reload();
    }

    private void renderShell(){
        if(adapter!=null){adapter.close();adapter=null;}
        root=new LinearLayout(this);root.setOrientation(LinearLayout.VERTICAL);root.setBackgroundColor(Ui.BG);
        Ui.applySafeInsets(this,root);
        root.addView(Ui.subHeader(this,groupTitle==null?getString(R.string.group_contacts):groupTitle));
        LinearLayout actions=new LinearLayout(this);
        actions.setPadding(Ui.dp(this,16),0,Ui.dp(this,16),Ui.dp(this,10));
        Button add=Ui.button(this,getString(R.string.add_member),true);add.setOnClickListener(v->pickMember());
        actions.addView(add,new LinearLayout.LayoutParams(0,Ui.dp(this,46),1));
        Button rename=Ui.button(this,getString(R.string.rename),false);rename.setOnClickListener(v->rename());
        LinearLayout.LayoutParams rp=new LinearLayout.LayoutParams(0,Ui.dp(this,46),1);rp.leftMargin=Ui.dp(this,8);actions.addView(rename,rp);
        Button del=Ui.button(this,getString(R.string.delete),false);del.setTextColor(Ui.DANGER);del.setOnClickListener(v->delete());
        LinearLayout.LayoutParams dp=new LinearLayout.LayoutParams(0,Ui.dp(this,46),1);dp.leftMargin=Ui.dp(this,8);actions.addView(del,dp);
        root.addView(actions);
        TextView loading=Ui.text(this,getString(R.string.loading),15,Ui.SECONDARY);loading.setGravity(Gravity.CENTER);
        root.addView(loading,new LinearLayout.LayoutParams(-1,0,1));
        setContentView(root);
    }

    private void reload(){
        final int g=++generation;
        io.execute(()->{
            List<ContactSummary> data;
            try{data=repo.listByGroup(groupId);}catch(Exception e){data=Collections.emptyList();}
            final List<ContactSummary> result=data;
            main.post(()->{if(destroyed||g!=generation)return;showContacts(result);});
        });
    }

    private void showContacts(List<ContactSummary> data){
        while(root.getChildCount()>2)root.removeViewAt(2);
        if(adapter!=null){adapter.close();adapter=null;}
        if(data.isEmpty()){
            TextView e=Ui.text(this,getString(R.string.no_contacts),15,Ui.SECONDARY);e.setGravity(Gravity.CENTER);
            root.addView(e,new LinearLayout.LayoutParams(-1,0,1));return;
        }
        ListView list=new ListView(this);list.setDivider(null);list.setDividerHeight(Ui.dp(this,8));
        list.setPadding(Ui.dp(this,16),0,Ui.dp(this,16),Ui.dp(this,16));list.setClipToPadding(false);
        list.setBackgroundColor(Ui.BG);list.setFastScrollEnabled(data.size()>=200);
        adapter=new ContactAdapter(this);adapter.setData(data);list.setAdapter(adapter);
        list.setOnItemClickListener((p,v,pos,id)->startActivity(new Intent(this,ContactDetailActivity.class).putExtra("contact_id",id)));
        list.setOnItemLongClickListener((p,v,pos,id)->{
            Ui.DialogParts dialog=Ui.showDialog(
                    this,
                    getString(R.string.remove_member_title),
                    getString(R.string.remove_member_confirm),
                    null,
                    getString(R.string.cancel),
                    getString(R.string.remove),
                    true);
            dialog.positive.setOnClickListener(x->{
                dialog.dialog.dismiss();
                runMutation(()->repo.removeFromGroup(id,groupId),true);
            });
            return true;
        });
        root.addView(list,new LinearLayout.LayoutParams(-1,0,1));
    }

    private void pickMember(){
        Intent i=new Intent(this,GroupMemberPickerActivity.class)
                .putExtra(GroupMemberPickerActivity.EXTRA_GROUP_ID,groupId);
        startActivityForResult(i,REQ_ADD_MEMBERS);
    }

    @Override protected void onActivityResult(int requestCode,int resultCode,Intent data){
        super.onActivityResult(requestCode,resultCode,data);
        if(requestCode!=REQ_ADD_MEMBERS||resultCode!=RESULT_OK||data==null)return;
        long[] ids=data.getLongArrayExtra(GroupMemberPickerActivity.EXTRA_SELECTED_IDS);
        if(ids==null||ids.length==0)return;

        io.execute(()->{
            boolean changed=false;
            try{
                for(long id:ids){
                    repo.addToGroup(id,groupId);
                    changed=true;
                }
                final boolean didChange=changed;
                main.post(()->{
                    if(destroyed)return;
                    if(didChange)reload();
                });
            }catch(Exception e){
                main.post(()->{
                    if(!destroyed){
                        Toast.makeText(this,R.string.group_update_failed,Toast.LENGTH_LONG).show();
                        reload();
                    }
                });
            }
        });
    }

    private void runMutation(Runnable action,boolean refresh){
        io.execute(()->{
            try{action.run();if(refresh)main.post(()->{if(!destroyed)reload();});}
            catch(Exception e){main.post(()->{if(!destroyed)Toast.makeText(this,R.string.group_update_failed,Toast.LENGTH_LONG).show();});}
        });
    }

    private void rename(){
        EditText e=Ui.input(this,getString(R.string.group_name));
        e.setText(groupTitle);
        Ui.DialogParts dialog=Ui.showDialog(
                this,
                getString(R.string.rename_group),
                getString(R.string.rename_group_desc),
                e,
                getString(R.string.cancel),
                getString(R.string.save),
                false);
        dialog.positive.setOnClickListener(v->{
            String n=e.getText().toString().trim();
            if(n.isEmpty())return;
            dialog.dialog.dismiss();
            groupTitle=n;
            runMutation(()->repo.renameGroup(groupId,n),false);
            renderShell();
            reload();
        });
    }

    private void delete(){
        Ui.DialogParts dialog=Ui.showDialog(
                this,
                getString(R.string.delete_group_title),
                getString(R.string.delete_group_confirm),
                null,
                getString(R.string.cancel),
                getString(R.string.delete),
                true);
        dialog.positive.setOnClickListener(v->{
            dialog.dialog.dismiss();
            io.execute(()->{
                try{repo.deleteGroup(groupId);main.post(()->{if(!destroyed)finish();});}
                catch(Exception e){main.post(()->{if(!destroyed)Toast.makeText(this,R.string.group_update_failed,Toast.LENGTH_LONG).show();});}
            });
        });
    }

    @Override protected void onDestroy(){
        destroyed=true;++generation;if(adapter!=null)adapter.close();io.shutdownNow();super.onDestroy();
    }
}
