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

package com.ntels.onecable.view.things;

import com.android.volley.Response;
import com.android.volley.VolleyError;
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.http.HttpSend;
import com.ntels.onecable.common.netatmo.NetatmoHttpClientImpl;
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.widget.CustomActivity;
import com.ntels.onecable.view.dialog.CustomDialog;

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

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.RadioButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.HashMap;

import static com.ntels.onecable.common.http.Response.OK;

/**
 * <pre>
 * 1. ClassName :   ThingsDeviceNetatmoCameraList
 * 2. FileName  :   ThingsDeviceNetatmoCameraList.java
 * 3. Package   :   com.ntels.onecable.view.things
 * 4. Date      :   2016-11-25
 * 5. Author    :   aaron
 * 6. Comment   :   Initialize
 * </pre>
 */
public class ThingsDeviceNetatmoCameraList extends CustomActivity implements View.OnClickListener,
        CustomDialog.OnMsgAlterToResult {

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

    private static final int DEFAULT_ANIMATION_DURATION = 800;
    private static final int DEFAULT_ANIMATION_TIMEOUT = 15000;
    private static final int MSG_COM_P_NETATMO_HOMEDATA = 1;
    private static final int MSG_COM_P_CLOUD_NODE_REGISTER = 2;
    private static final String NODE_MANUFACTURER = "Netatmo";
    private static final String NODE_MODEL_NUMBER = "Welcome";
    private static final String NODE_PROFILE_VERSION = "v3";
    Handler comHandler = new Handler(new IncomingHandlerCallBack());
    /*통신 관련*/
    private int mType = 0;
    /*공통*/
    private Activity mActivity;
    private AppConfig mAppConfig;
    private Intent mIntent;
    private Util mUtil = new Util();
    private CustomDialog mCustomDialog = new CustomDialog();
    private ArrayList<HashMap<String, Object>> mCameraList = new ArrayList<>();
    private ThingsNetatmoCameraAdapter mCameraListAdapter = null;
    private RadioButton mLastCameraSelect = null;
    private boolean mIsLoading = false;
    private Animation mLoadingAnimation;
    private NetatmoHttpClientImpl mNetatmoHttpClientImpl;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        mActivity = ThingsDeviceNetatmoCameraList.this;
        mAppConfig = (AppConfig) mActivity.getApplicationContext();
        mCustomDialog.setOnMsgAlterToResultEvent(this);
        mNetatmoHttpClientImpl = new NetatmoHttpClientImpl(mActivity);

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

        mUtil.getView(mActivity, R.id.llBtn1).setOnClickListener(this);
        mUtil.getView(mActivity, R.id.llBtn2).setOnClickListener(this);
        startLoading();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case Constants.ACT_THINGS_DEVICE_ADD_3RD:
                    setResult(RESULT_OK, data);
                    finish();
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    public void onClick(View view) {
        LogUtil.i(TAG, "onClick!!");
        switch (view.getId()) {
            case R.id.llBtn1:
                if (mLastCameraSelect == null) {
                    mUtil.setShowToast(mActivity, mUtil.getString(mActivity, R.string.MSG912),
                            Toast.LENGTH_SHORT);
                    return;
                }
                comHandler.sendEmptyMessageDelayed(MSG_COM_P_CLOUD_NODE_REGISTER, Constants.HANDLER_DELAY_MILLIS);
                break;
            case R.id.llBtn2:
                onBackPressed();
                break;
            default:
                break;
        }
    }

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

        switch (msgId) {

            case Constants.MSG807:
                if (btnResult == 1) {
                    if (mType == MSG_COM_P_NETATMO_HOMEDATA) {
                        startLoading();
                    } else {
                        comHandler.sendMessageDelayed(comHandler.obtainMessage(mType),
                                Constants.HANDLER_DELAY_MILLIS);
                    }
                }
                break;

            default:
                break;
        }
    }

    /**
     * UI display.
     */
    private void setDisp() {
        mCameraListAdapter = new ThingsNetatmoCameraAdapter();
        LinearLayoutManager llManager = new LinearLayoutManager(mActivity);
        RecyclerView rvCameraList = (RecyclerView) findViewById(R.id.rvCameraList);
        rvCameraList.setLayoutManager(llManager);
        rvCameraList.setAdapter(mCameraListAdapter);
    }

    /**
     * 넷타모 사용자 계정에 있는 카메라 정보를 읽어온다.
     */
    private void netatmoHomeData() {

        mNetatmoHttpClientImpl.getHomeData(
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        JSONObject jsonObject;
                        try {
                            jsonObject = new JSONObject(response);
                            LogUtil.i(TAG, "Homedata response : " + jsonObject.toString());
                            mCameraList = mNetatmoHttpClientImpl.parseNetatmoCamera(jsonObject);
                            if (mIsLoading) {
                                mLoadingAnimation.cancel();
                            }
                            setDisp();
                        } catch (JSONException ex) {
                            ex.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.e(TAG, error.toString());
                        if (mIsLoading) {
                            mLoadingAnimation.cancel();
                        }
                        comHandler.sendEmptyMessageDelayed(Constants.MSG807, Constants.HANDLER_DELAY_MILLIS);
                    }
                }


        );

    }

    /**
     * 로딩 애니메이션 시작.
     */
    private void startLoading() {
        mIsLoading = true;
        mLoadingAnimation = AnimationUtils.loadAnimation(mActivity, R.anim.progress_anim);
        mLoadingAnimation.setDuration(DEFAULT_ANIMATION_DURATION);
        mLoadingAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                LogUtil.i(TAG, "onAnimationStart");
                comHandler.sendEmptyMessageDelayed(MSG_COM_P_NETATMO_HOMEDATA,
                        Constants.HANDLER_DELAY_MILLIS);
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mLoadingAnimation.cancel();
                    }
                }, DEFAULT_ANIMATION_TIMEOUT);
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                LogUtil.i(TAG, "onAnimationEnd");
                mIsLoading = false;
                mUtil.getImageView(mActivity, R.id.ivLoadingProgress).clearAnimation();
                mUtil.getImageView(mActivity, R.id.ivLoadingProgress).setVisibility(View.GONE);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                LogUtil.i(TAG, "onAnimationRepeat");
            }
        });
        mUtil.getImageView(mActivity, R.id.ivLoadingProgress).bringToFront();
        mUtil.getImageView(mActivity, R.id.ivLoadingProgress).setVisibility(View.VISIBLE);
        mUtil.getImageView(mActivity, R.id.ivLoadingProgress).startAnimation(mLoadingAnimation);
    }

    /**
     * Cloud to Cloud 연동 Node 등록 요청.
     */
    private void sendPostCloudNode() {
        try {
            HttpSend httpSend;

            httpSend = new HttpSend(mActivity, !mIsLoading);

            httpSend.setOnDataSendToReslutEvent(new OnDataSendToReslut() {
                @Override
                public void resultResponse(com.ntels.onecable.common.http.Response result) {

                    resultPostCloudNode(result);
                }
            });
            HashMap<String, Object> item = mCameraList.get((int) (mLastCameraSelect.getTag()));

            HashMap<String, Object> cloudConfig = new HashMap<>();
            HashMap<String, Object> cloudContents = new HashMap<>();

            cloudConfig.put(Constants.KEY_CLIENT_ID, getString(R.string.client_id));
            cloudConfig.put(Constants.KEY_CLIENT_SECRET, getString(R.string.client_secret));
            cloudConfig.put(Constants.KEY_REFRESH_TOKEN, mNetatmoHttpClientImpl.getRefreshToken());
            cloudConfig.put(Constants.KEY_ACCESS_TOKEN, mNetatmoHttpClientImpl.getAccessToken());
            cloudConfig.put(Constants.KEY_VPN_URL, item.get(Constants.KEY_VPN_URL));
            cloudConfig.put(Constants.KEY_CAMERA_ID, item.get("id"));

            if (mUtil.null2string(item.get("status")) != "") {
                cloudContents.put(Constants.KEY_ONLINE, item.get("status"));
                cloudContents.put(Constants.KEY_LIVESHARE,
                        mUtil.null2string(item.get("status")).toUpperCase());
            }

            HashMap<String, Object> tempMap = new HashMap<>();
            String deviceId = mAppConfig.getSelect_Homegrp_Homehub_Device_Id();
            String deviceKey = mAppConfig.getsSelect_Homegrp_Homehub_Device_Key();

            tempMap.put(Constants.KEY_NODE_MANUFACTURER, NODE_MANUFACTURER);
            tempMap.put(Constants.KEY_NODE_MODEL_NUMBER, NODE_MODEL_NUMBER);
            tempMap.put(Constants.KEY_NODE_PROFILE_VERSION, NODE_PROFILE_VERSION);
            tempMap.put(Constants.KEY_NODE_SERIAL_NUMBER,
                    (mAppConfig.getSelect_Homegrp_Homehub_Device_Id() + "-" + item.get("id")));
            tempMap.put(Constants.KEY_HOMEGROUP_ID, mAppConfig.getCtrtGroupId());
            tempMap.put(Constants.KEY_MEMBER_ID, mAppConfig.getLogin_Member_Id());
            tempMap.put(Constants.KEY_DEVICE_ID, deviceId);
            tempMap.put(Constants.KEY_DEVICE_KEY, deviceKey);
            tempMap.put(Constants.KEY_CLOUD_TYPE, NODE_MANUFACTURER);
            tempMap.put(Constants.KEY_CLOUD_CONFIG, cloudConfig);
            tempMap.put(Constants.KEY_CLOUD_CONTENTS, cloudContents);

            String bodyVal = mUtil.MapToJson(tempMap);

            httpSend.P_cloud_devices_device_id_nodes(deviceId, bodyVal);
        } catch (Exception ex) {
            ex.printStackTrace();
            mCustomDialog.msgAlert(mActivity, Constants.MSG807);
        }
    }

    /**
     * Cloud to Cloud 연동 Node 등록 결과.
     *
     * @param result 결과 data
     */
    private void resultPostCloudNode(com.ntels.onecable.common.http.Response result) {
        String resultCode = "";
        String resultMsg = "";
        try {
            JSONObject joResult = new JSONObject(result.getContent());
            if (!joResult.isNull(Constants.KEY_RESULT_CODE)) {
                resultCode = mUtil.null2string(joResult.get(Constants.KEY_RESULT_CODE));
            }
            if (!joResult.isNull(Constants.KEY_RESULT_MSG)) {
                resultMsg = mUtil.null2string(joResult.get(Constants.KEY_RESULT_MSG));
            }
            if (result.getStatusCode() == OK) {
                LogUtil.i(TAG, "cloud node register result code : " + resultCode);
                if ("00".equals(resultCode)) {
                    mIntent = new Intent(mActivity, ThingsDeviceAdd3rd.class);
                    mUtil.callActivityForResultNoAnim(mActivity, mIntent,
                            Constants.ACT_THINGS_DEVICE_ADD_3RD);
                } else {
                    mCustomDialog.msgAlert(mActivity, Constants.MSG000, "[" + resultCode + "] "
                            + resultMsg);
                }
            } else {
                Dlog.v(joResult.toString());
                mCustomDialog.msgAlert(mActivity, Constants.MSG807);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            mCustomDialog.msgAlert(mActivity, Constants.MSG807);
        }
    }

    /**
     * 서버 요청 핸들러.
     */
    class IncomingHandlerCallBack implements Handler.Callback {

        @Override
        public boolean handleMessage(Message msg) {

            mType = msg.what;
            switch (msg.what) {
                case MSG_COM_P_NETATMO_HOMEDATA:
                    netatmoHomeData();
                    break;
                case MSG_COM_P_CLOUD_NODE_REGISTER:
                    sendPostCloudNode();
                    break;

                default:
                    break;
            }
            return true;
        }
    }

    /**
     * 넷타모 카메라 선택 리스트 아답터.
     *
     * @author aaron
     */
    public class ThingsNetatmoCameraAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

        ThingsNetatmoCameraAdapter() {
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(
                    R.layout.row_netatmo_camera_list, parent, false);
            return new CameraItem(view);
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            HashMap<String, Object> hmItem = new HashMap<String, Object>();
            hmItem = mCameraList.get(position);
            CameraItem cameraItemView = (CameraItem) holder;

            //final String id = mUtil.null2string(hmItem.get("id"));
            //final String mType = mUtil.null2string(hmItem.get("mType"));
            //final String status = mUtil.null2string(hmItem.get("status"));
            //final String sd_status = mUtil.null2string(hmItem.get("sd_status"));
            //final String alim_status = mUtil.null2string(hmItem.get("alim_status"));
            final String name = mUtil.null2string(hmItem.get("name"));
            //final String vpn_url = mUtil.null2string(hmItem.get("vpn_url"));

            cameraItemView.tvCameraName.setText(name);
            cameraItemView.rbCameraSelect.setTag(position);
            final HashMap<String, Object> finalHmItem = hmItem;
            cameraItemView.rbCameraSelect.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (mLastCameraSelect != null) {
                        mLastCameraSelect.setChecked(false);
                    }
                    mLastCameraSelect = (RadioButton) view;
                    mLastCameraSelect.setChecked(true);
                }
            });
        }

        @Override
        public int getItemCount() {
            return mCameraList.size();
        }
    }

    /**
     * 넷타모 카메라 리스트 아이템 뷰홀더.
     *
     * @author aaron
     */
    public class CameraItem extends RecyclerView.ViewHolder {

        public RelativeLayout rlRoot;
        public TextView tvCameraName;
        public RadioButton rbCameraSelect;

        /**
         * Recyclerview viewholder 생성.
         *
         * @param itemView recyclerview에 보여줄 view
         */
        public CameraItem(View itemView) {
            super(itemView);
            rlRoot = (RelativeLayout) itemView.findViewById(R.id.rlRoot);
            tvCameraName = (TextView) itemView.findViewById(R.id.tvCameraName);
            rbCameraSelect = (RadioButton) itemView.findViewById(R.id.rbCameraSelect);
        }
    }

}
