/*
 * /////////////////////////////////////////////////////////////////////////////////
 * //
 * // 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.fragments;


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.app.Fragment;
import android.support.design.widget.TextInputLayout;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.avaya.odonnell3.AndroidChatTemplate_2_3.R;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.activities.ChatActivity;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.model.ChatMessage;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.adapters.MessageListAdapter;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.classes.MessageParser;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.model.AgentIsTyping;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.model.NewMessageNotification;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.model.CustomerJsonWrapper;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.model.IsTyping;
import com.avaya.odonnell3.AndroidChatTemplate_2_3.model.NewMessageRequest;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class ChatActivityFragment extends Fragment {

    public final String className = this.getClass().getSimpleName();
    Context context;
    EditText editText;
    Button sendButton;
    ListView lv;
    ChatActivity chatActivity;
    public List<ChatMessage> messageList;
    public MessageListAdapter adapter;
    PagePushHandler callback;
    LinearLayout isTypingLayout;
    int lock = 0;
    boolean isLocked = false;
    View rootView;
    TextInputLayout textInputLayout;
    String greetingJson;

    public ChatActivityFragment() {

    }

    //create a method or class to set an initial welcome message,
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        Log.v("Info",className+" onCreateView()");
        rootView = inflater.inflate(R.layout.fragment_chat, container, false);
        messageList = new ArrayList<>();
        setDateHeader();
        lv = (ListView) rootView.findViewById(R.id.chat_lv);
        chatActivity = (ChatActivity) getActivity();
        chatActivity.chatUtils.closeKeyboard();
        sendButton = (Button) rootView.findViewById(R.id.send_btn);
        editText = (EditText) rootView.findViewById(R.id.message_input);
        textInputLayout = (TextInputLayout) rootView.findViewById(R.id.view);
        isTypingLayout = (LinearLayout) rootView.findViewById(R.id.is_typing_layout);
        context = inflater.getContext();
        isTypingLayout.setVisibility(View.GONE);
        greetingJson = getArguments().getString("agentGreeting");

//Send message button, will not send message if the text field is empty
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (editText.getText().length() > 0) {
                    showCustomerMessage();
                } else {
                    Toast toast = Toast.makeText(getActivity(), "Add a message", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.TOP | Gravity.CENTER, 0, 0);
                    toast.show();
                }
            }
        });
      //sending isTyping on key-press with timer to send every 3 seconds
        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                Log.v("Info", "Count: " + lock);
                sendCustomerIsTyping();
                //sending isTyping at 3 second intervals.
                Timer timer = new Timer();
                timer.scheduleAtFixedRate(new TimerTask() {
                    @Override
                    public void run() {
                        lock++;
                        if (lock == 300) {
                            Log.v("Info", "UnLocking, Lock count = " + lock);
                            isLocked = false;
                            lock = 0;
                        }
                    }
                }, 1000, 1000);
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });

        adapter = new MessageListAdapter(context, R.layout.list_item_agent, messageList);
        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() == 3) { //if is page push
                    showPagePushInBrowser(cm.getMessage());
                }
            }
        });

        setAgentGreeting();

        return rootView;
    }
//send the customer is-typing message
    private void sendCustomerIsTyping() {
        Log.v("Info",className+" sendCustomerIsTyping()");
        if (!isLocked) {
            IsTyping customerIsTyping = new IsTyping(true);
            CustomerJsonWrapper wrapper = new CustomerJsonWrapper("request");
            wrapper.setBody(customerIsTyping);
            String message = MessageParser.javaObjectToJson(wrapper);
            Log.v("Info", "Sending: " + message + " \ntoString: " + customerIsTyping.toString());
            chatActivity.wsClient.send(message);
            isLocked = true;
        }
    }

//launch the browser from
    private void showPagePushInBrowser(String pagePush) {
        Log.v("Info",className+" showPagePushInBrowser()");
        Uri uri = Uri.parse(pagePush);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(intent);
    }
//adds a header to teh top of the Chat window with the current date
    private void setDateHeader() {
        Log.v("Info",className+" setDateHeader()");
        ChatMessage cm = new ChatMessage();
        cm.setMessage(getFormattedDate());
        cm.setSenderType(4);
        messageList.add(cm);

    }
//sets the format of the date header
    private String getFormattedDate() {
        Log.v("Info",className+"  getFormattedDate()");
        Calendar c = Calendar.getInstance();
        SimpleDateFormat df = new SimpleDateFormat("EEEE, dd MMM yyyy");
        return df.format(c.getTime());
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.v("Info",className+" onStart()");
    }


    @Override
    public void onStop() {
        // callback.saveMessageHistory(messageList);
        callback.appInForeGround(false);
        Log.v("Info",className+" onStop()");
        super.onStop();
    }

    @Override
    public void onPause() {
        Log.v("Info",className+" onPause()");
        callback.saveMessageHistory(messageList);
        callback.appInForeGround(false);
        super.onPause();
    }

    @Override
    public void onResume() {
        Log.v("Info",className+" onResume()");
        super.onResume();
        adapter.notifyDataSetChanged();
        if (callback != null) {
            callback.appInForeGround(true);
        }

    }

    //sets the agent greeting as the first message in the chat
    private void setAgentGreeting() {
        Log.v("Info",className+"  setAgentGreeting()");
        if (greetingJson != null) {
            CustomerJsonWrapper wrapper = MessageParser.jsonStringToJava(greetingJson);
            NewMessageNotification in = null;
            if (wrapper != null) {
                in = (NewMessageNotification) wrapper.getBody();
            }

            assert in != null;
            Log.v("AgentMessage",in.toString());
            ChatMessage cm = new ChatMessage(in.getDisplayName(), in.getMessage(), 1);
            showAgentMessage(cm);
        }
    }
//display a message from the agent
    public void showAgentMessage(ChatMessage chatMessage) {
        Log.v("Info",className+"  showAgentMessage()");
        Log.v("Info", "showAgentMessage: " + chatMessage);
        messageList.add(chatMessage);
        adapter.notifyDataSetChanged();
        lv.setSelection(messageList.size() - 1);
    }

//display a message from the customer on screen
    public void showCustomerMessage() {
        Log.v("Info",className+"  showCustomerMessage()");
        String message = editText.getText().toString();
        ChatMessage chatMessage = new ChatMessage("Me", message, 0);
        messageList.add(chatMessage);
        adapter.notifyDataSetChanged();
        lv.setSelection(messageList.size() - 1);
        editText.setText("");

        sendCustomerMessage(chatMessage);
    }

    //get the customer message and send to agent
    public void sendCustomerMessage(ChatMessage chatMessage) {
        Log.v("Info",className+"  showCustomerMessage()");
        NewMessageRequest out = new NewMessageRequest();
        out.setMessage(chatMessage.getMessage());
        CustomerJsonWrapper wrapper = new CustomerJsonWrapper("request");
        wrapper.setBody(out);
        String message = MessageParser.javaObjectToJson(wrapper);
        Log.v("Info", "Is WsClient null: " + chatActivity.wsClient.getReadyState().toString());
        chatActivity.wsClient.send(message);

    }
//display messages entered in co-browse in the main chat window
    public void showCustomerCoBrowseMessage(String message) {
        Log.v("Info",className+"  showCustomerCoBrowseMessage()");
        ChatMessage chatMessage = new ChatMessage("Me", message, 0);
        messageList.add(chatMessage);
        adapter.notifyDataSetChanged();
        lv.setSelection(messageList.size() - 1);
        sendCustomerMessage(chatMessage);
    }


//display the Agent is-typing message to the customer
    public void showAgentIsTyping(AgentIsTyping isTyping) {
        Log.v("Info",className+"  showAgentIsTyping()");
        TextView agentName = (TextView) rootView.findViewById(R.id.is_typing_name_tv);
        agentName.setText(isTyping.getDisplayName());
        Log.v("Info", "ShowAgentIsTyping: " + isTyping.getTyping());


        if (isTyping.getTyping()) {
            isTypingLayout.setVisibility(View.VISIBLE);
            isTypingLayout.postDelayed(new Runnable() {
                @Override
                public void run() {
                    isTypingLayout.setVisibility(View.GONE);
                }
            }, 3000);
        }
    }

    @Override
    public void onAttach(Activity activity) {
        Log.v("Info",className+" onAttach()");
        super.onAttach(activity);
        callback = (PagePushHandler) activity;
    }

    public Button getSendButton() {
        return sendButton;
    }

    public TextInputLayout getTextInputLayout() {
        return textInputLayout;
    }

    //preserves the on-screen messages when app is moved to background
    public void setMessageList(List<ChatMessage> messageListStored) {
        Log.v("Info",className+"  setMessageList()");
//        this.messageList.clear();
//        this.messageList.addAll(messageListStored);
        Log.v("Info", "setMessageList():" + this.messageList.size());
        adapter.notifyDataSetChanged();
        lv.setSelection(this.messageList.size() - 1);
    }

    //interface for interacting with the Chat activity and fragment
    public interface PagePushHandler {
        void saveMessageHistory(List<ChatMessage> cm);
        void appInForeGround(boolean b);
    }
}
