package kr.co.icontrols.iotplatform;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;

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

import java.io.IOException;
import java.util.ArrayList;

import kr.co.icontrols.iotplatform.DataClass.DeviceInfo;
import kr.co.icontrols.iotplatform.DataClass.UserInfo;
import kr.co.icontrols.iotplatform.Database.DBUtil;
import kr.co.icontrols.iotplatform.Mqtt.MqttController;
import kr.co.icontrols.iotplatform.adapter.DeviceListAdapter;
import kr.co.icontrols.iotplatform.utils.GetSessionCallback;
import kr.co.icontrols.iotplatform.utils.HttpApi;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

import static kr.co.icontrols.iotplatform.Database.DatabaseHelper.TABLE_DEVICE_RANK;
import static kr.co.icontrols.iotplatform.PopupActivity.POPUP_BUNDLE;
import static kr.co.icontrols.iotplatform.PopupActivity.POPUP_IMG_INDEX;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.DismissConnectDialog;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.ErrorLogOutput;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.ForceDismissConnectDialog;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.WarnLogOutput;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.cancelToExit;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.displayProgress;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.getCognitoSession;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.isExpiredSession;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.isRestartAppForBackgroundWaitTime;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.resetBackgroundWaitTime;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.restartApp;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.setBackgroundWaitTime;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.showNotiMsg;
import static kr.co.icontrols.iotplatform.utils.Constants.DEFAULT_RANK;
import static kr.co.icontrols.iotplatform.utils.Constants.EXTRA_DEVICE_INFO;
import static kr.co.icontrols.iotplatform.utils.Constants.EXTRA_DEVICE_LIST;
import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_CHANGE_GROUP_IMG;
import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_INPUT_GROUP_NAME;
import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_UPDATE_DATA;
import static kr.co.icontrols.iotplatform.utils.HttpApi.HTTP_OK;

public class DeviceActivity extends AppCompatActivity implements View.OnClickListener {

    private String TAG = "DeviceActivity";

    private ListView mListView;
    private DeviceListAdapter mDeviceListAdapter;

    private Handler mConnectedHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_device);

        mListView = findViewById(R.id.listView);

        if(!UserInfo.confirmed) {
            showNotiMsg(this, "인증 후 사용 가능합니다.");
        } else if(isExpiredSession()) {
            getCognitoSession(new GetSessionCallback() {
                @Override
                public void successed() {
                    getDeviceList();
                }

                @Override
                public void failed() {
                    showNotiMsg(DeviceActivity.this, "세션을 갱신하지 못하였습니다.");
                    System.exit(0);
                }
            });
        } else {
            getDeviceList();
        }

        mConnectedHandler = new Handler() {
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                WarnLogOutput(TAG, "mConnectedHandler : is mqtt connect ? " + MqttController.getInstance().isConneted());
                if(MqttController.getInstance().isConneted()) {
                    if(mDeviceListAdapter != null) {
                        MqttController.getInstance().allUnsubscribeToTopics();
                        mDeviceListAdapter.notifyDataSetChanged();
                    }
                } else {
                    mConnectedHandler.sendEmptyMessageDelayed(1,1000);
                }
            }
        };

    }

    @Override
    protected void onResume() {
        super.onResume();

        if(isRestartAppForBackgroundWaitTime()) {
            restartApp(this);
            return;
        }

        if(mDeviceListAdapter != null) {
            MqttController.getInstance().allUnsubscribeToTopics();
            mDeviceListAdapter.notifyDataSetChanged();

            if(!MqttController.getInstance().isConneted()) {
                mConnectedHandler.sendEmptyMessageDelayed(1,1000);
            }
        }
    }

    @Override
    public void onBackPressed() {
        if(findViewById(R.id.layoutMore).getVisibility() == View.VISIBLE) {
            findViewById(R.id.layoutMore).setVisibility(View.GONE);
        } else {
            //super.onBackPressed();
            cancelToExit(this);
        }
    }

    @Override
    protected void onPause() {
        mConnectedHandler.removeCallbacksAndMessages(null);
        MqttController.getInstance().allUnsubscribeToTopics();
        ForceDismissConnectDialog();
        setBackgroundWaitTime();
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        resetBackgroundWaitTime();
        super.onDestroy();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case RESULT_UPDATE_DATA:
                if(resultCode == RESULT_OK) {
                    MqttController.getInstance().allUnsubscribeToTopics();
                    if(UserInfo.devices.size() == 0) {
                        findViewById(R.id.layoutRegisterDevice).setVisibility(View.VISIBLE);
                        findViewById(R.id.layoutDeviceList).setVisibility(View.GONE);
                    } else {
                        findViewById(R.id.layoutRegisterDevice).setVisibility(View.GONE);
                        findViewById(R.id.layoutDeviceList).setVisibility(View.VISIBLE);
                        mDeviceListAdapter.notifyDataSetChanged();
                        UserInfo.deviceCount = UserInfo.devices.size();
                        ((TextView)findViewById(R.id.txtDeviceCount)).setText(String.format(getString(R.string.string_format_device_count),UserInfo.deviceCount));
                    }
                }
                break;
        }
    }

    @Override
    public void onClick(View v) {
        /*
        final View fv = v;
        fv.setEnabled(false);
        Timer buttonTimer = new Timer();
        buttonTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            fv.setEnabled(true);
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {

                        }
                    }
                });
            }
        }, 500);
        */

        if(!UserInfo.confirmed) {
            showNotiMsg(this, "인증 후 사용 가능합니다.");
            return;
        }

        switch (v.getId()) {
            case R.id.btnBack:
                onBackPressed();
                break;
            case R.id.btnRight2:
                findViewById(R.id.layoutMore).setVisibility(View.VISIBLE);
                break;
            case R.id.btnRight:
            case R.id.btnRegisterDevice:
                //startActivity(new Intent(this, AddDeviceListActivity.class));
                startActivity(new Intent(this,LightRegisterGuideActivity.class));
                break;
            case R.id.btnCloseMore:
                findViewById(R.id.layoutMore).setVisibility(View.GONE);
                break;
            case R.id.layoutMoreRank:
                if(UserInfo.devices.size() > 1) {
                    Intent intent = new Intent(DeviceActivity.this, DeviceChangeRankActivity.class);
                    intent.putExtra(EXTRA_DEVICE_LIST, UserInfo.devices);
                    intent.putExtra("MODE","DEVICE_RANK");
                    startActivity(intent);
                } else {
                    showNotiMsg(DeviceActivity.this,"스마트 조명 갯수가 2개 이상에만 변경 가능합니다.");
                }
                findViewById(R.id.layoutMore).setVisibility(View.GONE);
                break;
            case R.id.layoutMoreDelete:
                if(UserInfo.devices.size() > 0) {
                    UserInfo.setUnSelectAllDevices();
                    Intent intent = new Intent(DeviceActivity.this, DeviceSelectActivity.class);
                    intent.putExtra("MODE","AWS");
                    intent.putExtra(EXTRA_DEVICE_LIST, UserInfo.devices);
                    startActivityForResult(intent,RESULT_UPDATE_DATA);
                } else {
                    showNotiMsg(DeviceActivity.this,"삭제할 스마트 조명이 존재하지 않습니다.");
                }
                findViewById(R.id.layoutMore).setVisibility(View.GONE);
                break;
        }
    }

    private void getDeviceList() {
        UserInfo.getDevice(this, new UserInfo.CallbackForUpdate() {
            @Override
            public void updateData() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if(UserInfo.devices.size() == 0) {
                            findViewById(R.id.layoutRegisterDevice).setVisibility(View.VISIBLE);
                            findViewById(R.id.layoutDeviceList).setVisibility(View.GONE);
                        } else {

                            mDeviceListAdapter = new DeviceListAdapter(DeviceActivity.this, UserInfo.devices);
                            mListView.setAdapter(mDeviceListAdapter);
                            mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                                @Override
                                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                                    final DeviceInfo item = (DeviceInfo) parent.getItemAtPosition(position);
                                    Intent intent = new Intent(DeviceActivity.this,LightDetailActivity.class);
                                    intent.putExtra(EXTRA_DEVICE_INFO, (Parcelable) item);
                                    startActivityForResult(intent,RESULT_UPDATE_DATA);
                                }
                            });

                            findViewById(R.id.layoutRegisterDevice).setVisibility(View.GONE);
                            findViewById(R.id.layoutDeviceList).setVisibility(View.VISIBLE);
                            ((TextView)findViewById(R.id.txtDeviceCount)).setText(String.format(getString(R.string.string_format_device_count),UserInfo.deviceCount));
                        }
                    }
                });
            }
        });

        /*
        UserInfo.devices.clear();
        displayProgress(this, null,null);
        try{
            HttpApi.getAllDevice(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    e.printStackTrace();
                    ErrorLogOutput(TAG, "HttpApi.getAllDevice(onFailure)\n" + e.toString());
                    DismissConnectDialog();
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if(response.code() == HTTP_OK) {
                        WarnLogOutput(TAG, "HttpApi.getAllDevice(onResponse) : HTTP_OK");
                        try {
                            JSONObject json_data = new JSONObject(response.body().string());

                            UserInfo.deviceCount = json_data.isNull("count") ? 0 : json_data.getInt("count");

                            if(UserInfo.deviceCount > 0) {
                                JSONArray jarrayAll = new JSONArray(json_data.getString("results"));
                                for (int i = 0; i < jarrayAll.length(); i++) {
                                    JSONObject jObject = jarrayAll.getJSONObject(i);
                                    DeviceInfo item = new DeviceInfo(
                                            jObject.isNull("deviceId") ? "" : jObject.getString("deviceId"),
                                            jObject.isNull("deviceType") ? "" : jObject.getString("deviceType"),
                                            jObject.isNull("friendlyName") ? "" : jObject.getString("friendlyName"),
                                            jObject.isNull("sharedFriendlyName") ? "" : jObject.getString("sharedFriendlyName"),
                                            jObject.isNull("dgroupId") ? "" : jObject.getString("dgroupId"),
                                            jObject.isNull("dgroupName") ? "" : jObject.getString("dgroupName"),
                                            jObject.isNull("ownerId") ? "" : jObject.getString("ownerId"),
                                            DEFAULT_RANK
                                    );

                                    DeviceInfo localDbItem = DBUtil.getDeviceInfoForId(TABLE_DEVICE_RANK, item.deviceId);
                                    if (localDbItem == null) {
                                        DBUtil.putDeviceInfo(TABLE_DEVICE_RANK, item);
                                    } else {
                                        item.rank = localDbItem.rank;
                                        DBUtil.updateDeviceItem(TABLE_DEVICE_RANK, item);
                                    }
                                }

                                ArrayList<DeviceInfo> deviceInfos = DBUtil.getAllDeviceInfos(TABLE_DEVICE_RANK);
                                for (DeviceInfo d : deviceInfos) {
                                    UserInfo.devices.add(d);
                                }
                                deviceInfos.clear();
                            }

                            //UI 업데이트
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    if(UserInfo.devices.size() == 0) {
                                        findViewById(R.id.layoutRegisterDevice).setVisibility(View.VISIBLE);
                                        findViewById(R.id.layoutDeviceList).setVisibility(View.GONE);
                                    } else {
                                        findViewById(R.id.layoutRegisterDevice).setVisibility(View.GONE);
                                        findViewById(R.id.layoutDeviceList).setVisibility(View.VISIBLE);
                                        MqttController.getInstance().allUnsubscribeToTopics();
                                        mDeviceListAdapter.notifyDataSetChanged();
                                        ((TextView)findViewById(R.id.txtDeviceCount)).setText(String.format(getString(R.string.string_format_device_count),UserInfo.deviceCount));
                                    }
                                    DismissConnectDialog();
                                }
                            });

                        } catch (JSONException e) {
                            e.printStackTrace();
                            ErrorLogOutput(TAG, "HttpApi.getAllDevice(JSONException)\n" + e.toString());
                            DismissConnectDialog();
                        }
                    } else {
                        ErrorLogOutput(TAG, "HttpApi.getAllDevice(onResponse) Error code : " + response.code() + "\nresponse : " + response.toString());
                        DismissConnectDialog();
                        try {
                            JSONObject json_data = new JSONObject(response.body().string());
                            ErrorLogOutput(TAG, "HttpApi.getAllDevice(onResponse) body : " + json_data.toString());
                        } catch (JSONException e) {
                            ErrorLogOutput(TAG, "HttpApi.getAllDevice(onResponse) JSONException : " + e.toString());
                        }
                    }
                }
            });
        } catch(Exception e){
            e.printStackTrace();
            ErrorLogOutput(TAG, "HttpApi.getDeviceListInDeviceGroup(Exception)\n" + e.toString());
            DismissConnectDialog();
        }
         */
    }
}