/*
 * Copyright (c) 2015. Ncomz. All Rights Reserved
 */

package com.ntels.onecable.view.mainmore;

import com.ntels.onecable.R;
import com.ntels.onecable.common.AppConfig;
import com.ntels.onecable.common.Constants;
import com.ntels.onecable.common.c_interface.OnDataSendToReslut;
import com.ntels.onecable.common.broadcast.KneetMessageLocalBroadCast;
import com.ntels.onecable.common.http.HttpSend;
import com.ntels.onecable.common.http.Response;
import com.ntels.onecable.common.util.Dlog;
import com.ntels.onecable.common.util.LogUtil;
import com.ntels.onecable.common.util.Util;
import com.ntels.onecable.common.websocket.OnWebSocketResponse;
import com.ntels.onecable.common.websocket.WebSocketService;
import com.ntels.onecable.common.widget.CustomActionBarActivity;
import com.ntels.onecable.view.dialog.CustomDialog;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import java.util.HashMap;

public class Homehub extends CustomActionBarActivity implements View.OnClickListener,
    CustomDialog.OnMsgAlterToResult {

  private static final String TAG = Homehub.class.getSimpleName();

  private static final int MSG_COM_G_DEVICES_NODES = 1;
  private static final int MSG_COM_WS_DEVICE_COMMAND = 2;
  private static final int MSG_COM_WS_DEVICE_DELETE = 3;
  private static final int MSG_COM_WS_NODE_REGISTER = 4;

  /*통신 관련*/
  private int type = 0;

  /*공통*/
  private Activity act;
  private AppConfig appConfig;
  private Intent intent;
  private Util util = new Util();
  private CustomDialog customDialog = new CustomDialog();
  private SwipeRefreshLayout swipeRefreshLayout;
  private boolean loading = false;
  private WebSocketService webSocketService;
  private boolean isBound = false;
  private String cameraSn = "";

  @Override
  protected void onNewIntent(Intent saveIntent) {

    super.onNewIntent(saveIntent);
    if (null != saveIntent) {
      Boolean isTemp = saveIntent.getBooleanExtra(
          KneetMessageLocalBroadCast.INTENT_ACTION_HOMEHUB_STATE_CHANGE, false);
      Dlog.v("isTemp", isTemp);
      setHomeHubState();
    }
  }

  @Override
  public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    act = Homehub.this;
    appConfig = (AppConfig) act.getApplicationContext();
    customDialog.setOnMsgAlterToResultEvent(this);

    Intent serviceIntent = new Intent(act, WebSocketService.class);
    act.bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);

    View viewToLoad = LayoutInflater.from(act).inflate(R.layout.homehub, null);
    this.setContentView(viewToLoad);

    setToolbar();
    displayListView();

    boolean isHiddenEnable = true;
    if (isHiddenEnable) {
      util.getView(act, R.id.llModelName).setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View view) {
          AlertDialog.Builder alert = new AlertDialog.Builder(act);
          alert.setTitle("카메라 등록");
          alert.setMessage("카메라번호-유저번호");
          final EditText number = new EditText(act);
          number.setHint("ex) 07077775021-07077775028");
          alert.setView(number);
          alert.setPositiveButton("확인", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
              cameraSn = number.getText().toString();
              comHandler.sendMessageDelayed(comHandler.obtainMessage(MSG_COM_WS_NODE_REGISTER), 10);
              dialog.dismiss();
            }
          });
          alert.setNegativeButton("취소", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
              dialog.dismiss();
            }
          });
          alert.show();
          return false;
        }
      });
    }
  }

  private ServiceConnection serviceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
      LogUtil.i(TAG, "onServiceConnected");
      WebSocketService.WebSocketBinder binder = (WebSocketService.WebSocketBinder) service;
      webSocketService = binder.getService();
      webSocketService.addWebSocketResponse(webSocketResponse);
      isBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
      isBound = false;
    }
  };

  private OnWebSocketResponse webSocketResponse = new OnWebSocketResponse() {
    @Override
    public void onResponse(String result) {
      try {

        JSONObject jsonObject = new JSONObject(result);
        String messageType = util.null2string(jsonObject.get(Constants.KEY_MESSAGE_TYPE));
        LogUtil.i(TAG, "websocket message type : " + messageType);

        switch (messageType) {
          case Constants.WEBSOCKET_TYPE_DEVICE_DELETE:
            resultWsDeviceDelete(jsonObject);
            break;
          case Constants.WEBSOCKET_TYPE_DEVICE_COMMAND:
            resultWsDeviceCommand(jsonObject);
            break;
          default:
            break;
        }
      } catch (JSONException ex) {
        ex.printStackTrace();
      }
    }

    @Override
    public void onError(int code, String message) {
      switch (code) {
        case Constants.WEBSOCKET_ERROR_NOT_CONNECTED:
          customDialog.msgAlert(act, Constants.MSG807);
          break;
        default:
          break;
      }
    }
  };

  /**
   * 툴바 셋팅.
   */
  private void setToolbar() {

    Toolbar toolbar = (Toolbar) act.findViewById(R.id.toolbar);
    util.setKeyboardHide(act, toolbar);
    util.getTextView(toolbar, R.id.tvToolbarTitle1).setVisibility(View.VISIBLE);
    util.getTextView(toolbar, R.id.tvToolbarTitle2).setVisibility(View.GONE);
    util.getTextView(toolbar, R.id.tvToolbarTitleDivider).setVisibility(View.GONE);
    util.getTextView(toolbar, R.id.tvToolbarTitle3).setVisibility(View.GONE);
    util.getTextView(toolbar, R.id.tvToolbarTitle4).setVisibility(View.GONE);
    util.getTextView(toolbar, R.id.btnToolbarDel).setVisibility(View.GONE);
    util.getTextView(toolbar, R.id.btnToolbarClose).setVisibility(View.GONE);
    util.getTextView(toolbar, R.id.btnToolbarMore).setVisibility(View.GONE);

    util.getTextView(toolbar, R.id.tvToolbarTitle1)
        .setText(util.getString(act, R.string.layout_homehub_01));

    setHomeHubState();
  }

  /**
   * 홈허브 상태에 따라 UI display.
   */
  private void setHomeHubState() {

    if (appConfig.getsSelect_Homegrp_Homehub_Conn_State().equalsIgnoreCase("connect")) {
      util.getView(act, R.id.llState_Online).setVisibility(View.VISIBLE);
      util.getView(act, R.id.llState_Offline).setVisibility(View.GONE);
    } else {
      util.getView(act, R.id.llState_Online).setVisibility(View.GONE);
      util.getView(act, R.id.llState_Offline).setVisibility(View.VISIBLE);
    }

    if (appConfig.getsSelect_Homegrp_Homehub_Dongle_State().equalsIgnoreCase("ON")) {
      util.getView(act, R.id.llState_Dongle_Online).setVisibility(View.VISIBLE);
      util.getView(act, R.id.llState_Dongle_Offline).setVisibility(View.GONE);
    } else {
      util.getView(act, R.id.llState_Dongle_Online).setVisibility(View.GONE);
      util.getView(act, R.id.llState_Dongle_Offline).setVisibility(View.VISIBLE);
      if (!appConfig.getsSelect_Homegrp_Homehub_Dongle_Online_Last_Datetime().equals("")) {
        util.getTextView(act, R.id.tvRecentDate).setVisibility(View.VISIBLE);
        util.getTextView(act, R.id.tvRecentDate).setText(act.getString(R.string.layout_homehub_15,
            util.UTCtoLocal5(appConfig.getsSelect_Homegrp_Homehub_Dongle_Online_Last_Datetime())));
      } else {
        util.getTextView(act, R.id.tvRecentDate).setVisibility(View.GONE);
      }
    }
  }

  /**
   * List display.
   */
  private void displayListView() {

    swipeRefreshLayout = (SwipeRefreshLayout) act.findViewById(R.id.swiperefreshlayou);
    swipeRefreshLayout.setColorSchemeResources(android.R.color.holo_red_light,
        android.R.color.holo_green_light, android.R.color.holo_blue_bright,
        android.R.color.holo_orange_light);
    swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
      @Override
      public void onRefresh() {

        if (!loading) {
          loading = true;
          comHandler.sendMessageDelayed(comHandler.obtainMessage(MSG_COM_G_DEVICES_NODES), 10);
        }
      }
    });
    setDisp();
    comHandler.sendMessageDelayed(comHandler.obtainMessage(MSG_COM_G_DEVICES_NODES), 10);
  }

  /**
   * UI display.
   */
  private void setDisp() {

    util.getView(act, R.id.btnKeyChange).setOnClickListener(this);
    util.getView(act, R.id.llBtn1).setOnClickListener(this);
    util.getView(act, R.id.btnHomehubDelete).setOnClickListener(this);

    if (appConfig.getSelect_Homegrp_Grade_Code().equals("MAS")) {
      util.getView(act, R.id.llKeyChange).setVisibility(View.VISIBLE);
      util.getView(act, R.id.llHomehubDelete).setVisibility(View.VISIBLE);
      util.getView(act, R.id.vLastDivider).setVisibility(View.VISIBLE);
      util.getView(act, R.id.vLast_Section).setVisibility(View.VISIBLE);
    } else {
      util.getView(act, R.id.llKeyChange).setVisibility(View.GONE);
      util.getView(act, R.id.llHomehubDelete).setVisibility(View.GONE);
      util.getView(act, R.id.vLastDivider).setVisibility(View.GONE);
      util.getView(act, R.id.vLast_Section).setVisibility(View.GONE);
    }
  }

  @Override
  public void onConfigurationChanged(Configuration newConfig) {

    super.onConfigurationChanged(newConfig);
  }

  @Override
  public void onClick(View view) {

    switch (view.getId()) {
      case R.id.llBtn1:
        onBackPressed();
        break;
      case R.id.btnKeyChange:
        intent = new Intent(act, HomehubPasswordChange.class);
        util.callActivityForResultNoAnim(act, intent, Constants.ACT_HOMEHUB_PASSWORD_CHANGE);
        break;
      case R.id.btnHomehubDelete:
        customDialog.msgAlert(act, Constants.MSG904);
        break;
      default:
        break;
    }
  }

  Handler comHandler = new Handler(new IncomingHandlerCallBack());

  class IncomingHandlerCallBack implements Handler.Callback {

    @Override
    public boolean handleMessage(Message msg) {

      type = msg.what;
      switch (msg.what) {
        case MSG_COM_G_DEVICES_NODES:
          sendGetDevicesDetail();
          break;
        case MSG_COM_WS_DEVICE_COMMAND:
          sendWsDeviceCommand();
          break;
        case MSG_COM_WS_DEVICE_DELETE:
          sendWsDeviceDelete();
          break;
        case MSG_COM_WS_NODE_REGISTER:
          sendWsNodeRegister();
          break;

        default:
          break;
      }
      return true;
    }
  }

  /**
   * 서비스허브에 노드 등록 요청.
   */
  private void sendWsNodeRegister() {
    HashMap<String, Object> sendParams = new HashMap<>();
    sendParams.put(Constants.KEY_MESSAGE_TYPE, Constants.WEBSOCKET_TYPE_NODE_REGISTER);
    sendParams.put(Constants.KEY_DEVICE_ID,
        appConfig.getSelect_Homegrp_Homehub_Device_Id());
    sendParams.put(Constants.KEY_NODE_MANUFACTURER, "NTels");
    sendParams.put(Constants.KEY_NODE_MODEL_NUMBER, "OnVifCamera");
    sendParams.put(Constants.KEY_NODE_SERIAL_NUMBER, cameraSn);
    sendParams.put(Constants.KEY_NODE_PROFILE_VERSION, "v3");
    sendParams.put(Constants.KEY_REQUEST_ID,
        appConfig.getiSelect_Servicehub_Request_Id());

    webSocketService.send(Constants.WEBSOCKET_SEND_NODE_REGISTER, sendParams);
  }

  /**
   * <pre>
   * 노드 상세 조회(해당 장치의 상세 정보를 조회한다) 요청.
   * (장치가 보유한 모든 커맨드 클래스 리스트를 보여준다.)
   * </pre>
   */
  private void sendGetDevicesDetail() {
    try {
      HttpSend httpSend;

      httpSend = new HttpSend(act, !swipeRefreshLayout.isRefreshing());

      httpSend.setOnDataSendToReslutEvent(new OnDataSendToReslut() {
        @Override
        public void resultResponse(Response result) {

          resultGetDevicesDetail(result);
        }
      });
      httpSend.getNodeDetail(appConfig.getSelect_Homegrp_Homehub_Device_Id(), "");
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  /**
   * {@link #sendGetDevicesDetail()} 요청 결과.
   *
   * @param response 결과 data
   */
  private void resultGetDevicesDetail(Response response) {

    try {
      if (response.getStatusCode() == 200) {
        String deviceConn = "";
        String deviceOnline = "";
        String deviceOnlineLastDatetime = "";
        JSONObject joResult = new JSONObject(response.getContent());
        if (joResult.has(Constants.KEY_DEVICE_CONN)) {
          deviceConn = util.null2string(joResult.get(Constants.KEY_DEVICE_CONN));
        }
        if (joResult.has(Constants.KEY_DEVICE_ONLINE_LAST_DATETIME)) {
          deviceOnlineLastDatetime = util.null2string(
              joResult.get(Constants.KEY_DEVICE_ONLINE_LAST_DATETIME));
        }
        if (joResult.has(Constants.KEY_DEVICE_ONLINE)) {
          deviceOnline = util.null2string(joResult.get(Constants.KEY_DEVICE_ONLINE));
        }
        String deviceId = util.null2string(joResult.get(Constants.KEY_DEVICE_ID));
        String deviceKey = util.null2string(joResult.get(Constants.KEY_DEVICE_KEY));

        appConfig.setsSelect_Homegrp_Homehub_Conn_State(deviceConn);
        appConfig.setsSelect_Homegrp_Homehub_Dongle_State(deviceOnline);
        appConfig.setsSelect_Homegrp_Homehub_Dongle_Online_Last_Datetime(deviceOnlineLastDatetime);
        appConfig.setSelect_Homegrp_Homehub_Device_Id(deviceId);
        appConfig.setsSelect_Homegrp_Homehub_Device_Key(deviceKey);
        String tempDeviceOnline = appConfig.getsSelect_Homegrp_Homehub_Dongle_State();
        if (!tempDeviceOnline.equals(deviceOnline)) {
          //상태가 변경되었을때만 브로드캐스트를 날려준다
          Intent intent = new Intent(KneetMessageLocalBroadCast.INTENT_ACTION);
          intent.putExtra(KneetMessageLocalBroadCast.INTENT_NAME_TYPE,
              KneetMessageLocalBroadCast.INTENT_ACTION_HOMEHUB_STATE_CHANGE);
          intent.putExtra(KneetMessageLocalBroadCast.INTENT_ACTION_HOMEHUB_STATE_CHANGE, true);
          LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
        }

        setHomeHubState();
        String deviceSn = util.null2string(joResult.get(Constants.KEY_DEVICE_SN));
        util.getTextView(act, R.id.tvDeviceSN).setText(deviceSn);
        String deviceModelName = util.null2string(joResult.get(Constants.KEY_DEVICE_MODEL_ID))
            + " | " + util.null2string(joResult.get(Constants.KEY_DEVICE_MF_ID));
        util.getTextView(act, R.id.tvModelName).setText(deviceModelName);

        loading = false;
        swipeRefreshLayout.setRefreshing(false);
      } else {
        JSONObject joResult = new JSONObject(response.getContent());
        Dlog.v(joResult.toString());
        String errorCode = util.null2string(joResult.get(Constants.KEY_ERR_CODE));
        String errorMsg = util.null2string(joResult.get(Constants.KEY_ERR_MSG));

        if (errorCode.equals("401")) {
          customDialog.msgAlert(act, Constants.MSG998, errorMsg);
        } else if (errorCode.equals("401-106")) {
          customDialog.msgAlert(act, Constants.MSG997, errorMsg);
        } else {
          if (errorCode.equals("400-404")) {
            appConfig.setsSelect_Homegrp_Homehub_Dongle_State("");
            //상태가 변경되었을때만 브로드캐스트를 날려준다
            Intent intent = new Intent(KneetMessageLocalBroadCast.INTENT_ACTION);
            intent.putExtra(KneetMessageLocalBroadCast.INTENT_NAME_TYPE,
                KneetMessageLocalBroadCast.INTENT_ACTION_HOMEHUB_STATE_CHANGE);
            intent.putExtra(KneetMessageLocalBroadCast.INTENT_ACTION_HOMEHUB_STATE_CHANGE, true);
            LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
          }
        }
      }
    } catch (Exception ex) {
      ex.printStackTrace();
      customDialog.msgAlert(act, Constants.MSG807);
    }
  }

  @Override
  public void onBackPressed() {

    intent = new Intent();
    act.setResult(RESULT_CANCELED, intent);
    finish();
  }

  @Override
  public void resultCustomDialogResponse(int msgId, int btnResult) {

    switch (msgId) {
      case Constants.MSG998:
        util.callApp_Start(act, "LOGOUT");
        break;
      case Constants.MSG997:
        util.callApp_Start(act, "HOME_RELOAD");
        break;
      case Constants.MSG807:
        if (btnResult == 1) {
          comHandler.sendMessageDelayed(comHandler.obtainMessage(type), 10);
        }
        break;
      case Constants.MSG904:
        if (btnResult == 1) {
          if (appConfig.getsSelect_Homegrp_Homehub_Conn_State().equalsIgnoreCase("connect")) {
            comHandler.sendMessageDelayed(comHandler.obtainMessage(MSG_COM_WS_DEVICE_COMMAND), 10);
          } else {
            // 홈허브가 disconnect상태일때는 profile_reset 커맨드를 보내지 않고 바로 삭제 요청한다.
            resultWsDeviceCommand(null);
          }
        }
        break;
      default:
        break;
    }
  }

  @Override
  protected void onDestroy() {
    if (isBound) {
      webSocketService.removeWebSocketResponse(webSocketResponse);
      unbindService(serviceConnection);
      isBound = false;
    }
    super.onDestroy();
  }

  /**
   * 서비스 허브에 디바이스 제어(프로필 리셋)를 요청한다.
   */
  private void sendWsDeviceCommand() {
    HashMap<String, Object> sendParams = new HashMap<>();
    sendParams.put(Constants.KEY_MESSAGE_TYPE, Constants.WEBSOCKET_TYPE_DEVICE_COMMAND);
    sendParams.put(Constants.KEY_DEVICE_ID,
        appConfig.getSelect_Homegrp_Homehub_Device_Id());
    sendParams.put(Constants.KEY_COMMAND_TYPE,
        Constants.WEBSOCKET_COMM_TYPE_PROFILE_RESET);
    sendParams.put(Constants.KEY_REQUEST_ID,
        appConfig.getiSelect_Servicehub_Request_Id());

    webSocketService.send(Constants.WEBSOCKET_SEND_DEVICE_COMMAND, sendParams);
  }

  /**
   * {@link #sendWsDeviceCommand()} 요청 결과.
   *
   * @param joResult 결과 data
   */
  private void resultWsDeviceCommand(JSONObject joResult) {

    comHandler.sendMessageDelayed(comHandler.obtainMessage(MSG_COM_WS_DEVICE_DELETE), 10);

    try {
      util.getView(act, R.id.llBtn1).setEnabled(true);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  /**
   * 서비스 허브에 등록된 홈허브 디바이스를 삭제한다.
   */
  private void sendWsDeviceDelete() {
    HashMap<String, Object> sendParams = new HashMap<>();
    sendParams.put(Constants.KEY_MESSAGE_TYPE, Constants.WEBSOCKET_TYPE_DEVICE_DELETE);
    sendParams.put(Constants.KEY_DEVICE_ID,
        appConfig.getSelect_Homegrp_Homehub_Device_Id());
    sendParams.put(Constants.KEY_DEVICE_KEY,
        appConfig.getsSelect_Homegrp_Homehub_Device_Key());
    sendParams.put(Constants.KEY_REQUEST_ID,
        appConfig.getiSelect_Servicehub_Request_Id());

    webSocketService.send(Constants.WEBSOCKET_SEND_DEVICE_REGISTER, sendParams);
  }

  /**
   * {@link #sendWsDeviceDelete()} 요청 결과.
   *
   * @param joResult 결과 data
   * @throws JSONException json parsing exception
   */
  private void resultWsDeviceDelete(JSONObject joResult) throws JSONException {
    String resultCode = util.null2string(joResult.get(Constants.KEY_RESULT_CODE));
    String resultMsg = "";
    String myDeviceId = appConfig.getSelect_Homegrp_Homehub_Device_Id();
    String deleteDeviceId = joResult.getString(Constants.KEY_DEVICE_ID);
    if (joResult.has(Constants.KEY_RESULT_MSG)) {
      resultMsg = util.null2string(joResult.get(Constants.KEY_RESULT_MSG));
    }
    if (resultCode.equals("00") && myDeviceId.equalsIgnoreCase(deleteDeviceId)) {
      appConfig.setSelect_Homegrp_Homehub_Device_Id("");
      appConfig.setsSelect_Homegrp_Homehub_Device_Key("");
      appConfig.setsSelect_Homegrp_Homehub_Dongle_State("");
      appConfig.setsSelect_Homegrp_Homehub_Conn_State("");

      intent = new Intent();
      intent.putExtra(Constants.EXTRA_RELOAD_FLAG, true);
      act.setResult(RESULT_OK, intent);
      finish();
    } else {
      util.setShowToast(act, resultMsg, Toast.LENGTH_SHORT);
    }
  }
}
