/*
 * /////////////////////////////////////////////////////////////////////////////////
 * //
 * // Copyright <2015>-<2016> Avaya Inc. All Rights Reserved.
 * //
 * // Usage of this source is bound to the terms described
 * // in assets/Licence.txt
 * //
 * // Avaya - Confidential & Proprietary. Use pursuant to your signed agreement
 * // or Avaya Policy
 * //
 * /////////////////////////////////////////////////////////////////////////////
 */

package com.avaya.odonnell3.AndroidChatTemplate_2_3.activities;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

import com.avaya.odonnell3.AndroidChatTemplate_2_3.R;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.UtilClasses.WaitActivityUtils;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.adapters.MessageListAdapter;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.model.ChatMessage;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.classes.MessageParser;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.model.CustomerJsonWrapper;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.model.NewParticipant;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.services.Global;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.services.WebSocketService;

import org.java_websocket.client.WebSocketClient;

import java.util.ArrayList;
import java.util.List;


public class WaitMessageActivity extends AppCompatActivity {


    public final String activityName = this.getClass().getSimpleName();
    public boolean isBound = false;
    WebSocketService wsService;
    ListView lv;
    public WebSocketClient wsClient;
    public List<ChatMessage> chatMessageList;
    List<String> messageList;

    MessageListAdapter adapter;
    private int delay = 0;
    AsyncShowWaitMessages task;
    Context context;
    public String inMessage;
    String packageName;
    public int messageCount = 0;
    public Intent chatIntent;
    int i = 0;


    WaitActivityUtils utils;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        Log.v("Info", activityName + " onCreate()");
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_wait);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        utils = new WaitActivityUtils(this);
        context = this;
        lv = (ListView) findViewById(R.id.wait_lv);
        chatMessageList = new java.util.concurrent.CopyOnWriteArrayList<>();
        messageList = new ArrayList<>();
        packageName = getApplicationContext().getPackageName();
        Global.waitMessageActivity = this;
        adapter = new MessageListAdapter(this, R.layout.list_item_wait, new ArrayList<ChatMessage>());
        lv.setAdapter(adapter);

        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                ChatMessage cm = (ChatMessage) parent.getItemAtPosition(position);

                if (cm.getSenderType() == 5) { //if is onHold URL
                    utils.showOnHoldInBrowser(cm.getMessage());
                }
            }
        });

        bindToWebSocket();
        utils.getWaitMessages();
        chatIntent = new Intent(this, ChatActivity.class);
        task = new AsyncShowWaitMessages();
        task.execute();
    }

    // Broadcast from WebSocket Service.
    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            getAgentJoinAndGreeting(intent);
        }
    };

    //wait for both the participant-join and agent greeting messages before launching Chat Activity
    public void getAgentJoinAndGreeting(Intent intent) {
        Log.v("Info", activityName + " getAgentJoinAndGreeting()");
        inMessage = intent.getStringExtra("message");
        CustomerJsonWrapper wrapper = MessageParser.jsonStringToJava(inMessage);

        Log.v("message", "Message in wait messages" + inMessage);

        if (wrapper != null) {
            final String simpleName = wrapper.getBody().getClass().getSimpleName();
            Log.v("Info", "Object name: " + simpleName);


            if(simpleName.equals("RouteCancel")){
                Toast.makeText(getApplicationContext(),"Attribute(s) not recognised by Server",Toast.LENGTH_LONG).show();
            }

            if (simpleName.equals("NewParticipant")) {
                NewParticipant p = (NewParticipant) wrapper.getBody();
                Toast.makeText(getApplicationContext(), p.getDisplayName() + " has Joined the Chat", Toast.LENGTH_SHORT).show();
                messageCount++;

                chatIntent.putExtra("newParticipant", inMessage);
            }

            if (simpleName.equals("NewMessageNotification")|| simpleName.equals("NewAutomationMessageNotification")) {
                messageCount++;
                Log.v("Info", "adding agentGreeting");
                chatIntent.putExtra("agentGreeting", inMessage);
                startActivity(chatIntent);
                task.cancel(true);
                Log.v("Info", "task is canceled? " + task.isCancelled());
                finish();
            }
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.v("Info", activityName + " onPause()");
        appInForeGround(true);
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.v("Info", activityName + " onPause()");

        if (isBound) {
            unbindService(serviceConnection);
            isBound = false;
        }

    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.v("Info", activityName + " onPause()");
        appInForeGround(false);
        unregisterReceiver(receiver);
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.v("Info", activityName + " onResume()");
        appInForeGround(true);
        registerReceiver(receiver, new IntentFilter(packageName));

    }

    @Override
    protected void onDestroy() {
        Log.v("Info", activityName + " onDestroy()");
        super.onDestroy();
        task.cancel(true);
    }

    @Override
    public void onBackPressed() {
        Toast.makeText(this, "Connecting please wait...", Toast.LENGTH_LONG).show();
        showCloseChatDialog();
    }


    //open a dialog to close the chat
    private void showCloseChatDialog() {
        Log.v("Info", activityName + " showCloseChatDialog()");
        //add leave-chat dialog here
        AlertDialog.Builder builder = new AlertDialog.Builder(WaitMessageActivity.this);
        builder.setTitle(R.string.leave_chat_dialog);
        String yes = getString(R.string.ok);
        String no = getString(R.string.cancel);

        builder.setPositiveButton(yes, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent serviceIntent = new Intent(context, WebSocketService.class);
                getApplicationContext().stopService(serviceIntent);
                task.cancel(true);
                //TODO - not firing close message
                if (!wsService.getWsClient().getReadyState().equals("CLOSED")) {
                    utils.sendCloseChatRequest();
                }

                fireMainActivityIntent();

            }
        }).setNegativeButton(no, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        AlertDialog dialog = builder.create();
        dialog.show();
    }


    private void fireCloseIntent() {
        Intent intent = new Intent(getApplicationContext(), MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.putExtra("CLOSE", true);
        startActivity(intent);
        finish();
    }

    private void fireMainActivityIntent() {
        Intent intent = new Intent(context, MainActivity.class);
        startActivity(intent);
        finish();

    }
    private void bindToWebSocket() {
        Log.v("Info", activityName + " bindToWebSocket()");
        Intent wsIntent = new Intent(this, WebSocketService.class);
        if (!isBound) {
            bindService(wsIntent, serviceConnection, Context.BIND_AUTO_CREATE);
            isBound = true;
        }
    }

    public ServiceConnection serviceConnection = new ServiceConnection() {
        @Override

        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.v("Info", activityName + " onServiceConnected()");
            WebSocketService.LocalBinder binder = (WebSocketService.LocalBinder) service;
            wsService = binder.getService();
            isBound = true;
            wsClient = wsService.getWsClient();
            appInForeGround(true);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.v("Info", activityName + " onServiceDisconnected()");
            isBound = false;
        }
    };

    public void appInForeGround(boolean b) {
        Log.v("Info", activityName + " appInForeGround()");
        if (wsService != null) {
            wsService.setAppVisible(b, activityName);
        }
    }

    public int getDelay() {
        return delay;
    }

    public void setDelay(int delay) {
        this.delay = delay;
    }

    class AsyncShowWaitMessages extends AsyncTask<Void, ChatMessage, Void> {
        @Override
        protected Void doInBackground(Void... params) {
            while (!task.isCancelled()) {
                utils.getWaitMessages();

                for (ChatMessage cm : chatMessageList) {
                    publishProgress(cm);
                    if (getDelay() <= 0) {
                        setDelay(10);
                    }
                    SystemClock.sleep(getDelay() * 1000);
                }
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(ChatMessage... cm) {
            adapter.remove(cm[0]);
            Log.v("Info", "i: " + i++);
            adapter.add(cm[0]);
            Log.v("Info", "wait message " + cm[0]);
            lv.setSelection(chatMessageList.size() - 1);

        }

        @Override
        protected void onPostExecute(Void aVoid) {

        }
    }


}


