package kr.co.icontrols.iotplatform.adapter;

import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.amazonaws.mobileconnectors.iot.AWSIotMqttNewMessageCallback;

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

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.LogRecord;

import kr.co.icontrols.iotplatform.AWS.AmazonBLEinfo;
import kr.co.icontrols.iotplatform.DataClass.DeviceInfo;
import kr.co.icontrols.iotplatform.DataClass.UserInfo;
import kr.co.icontrols.iotplatform.IotPlatformApplication;
import kr.co.icontrols.iotplatform.Mqtt.MqttController;
import kr.co.icontrols.iotplatform.R;
import kr.co.icontrols.iotplatform.utils.CommonUtils;

import static kr.co.icontrols.iotplatform.utils.CommonUtils.DebugLogOutput;
import static kr.co.icontrols.iotplatform.utils.Constants.MQTT_PUBLISH_DELAY_TIME;
import static kr.co.icontrols.iotplatform.utils.Constants.NOTING;
import static kr.co.icontrols.iotplatform.utils.Constants.NOT_CONNECTED;
import static kr.co.icontrols.iotplatform.utils.Constants.POWER_OFF;
import static kr.co.icontrols.iotplatform.utils.Constants.POWER_ON;

public class DeviceListAdapter extends BaseAdapter {

    private String TAG = "DeviceListAdapter";

    // Adapter에 추가된 데이터를 저장하기 위한 ArrayList
    private List<DeviceInfo> listViewItemList;
    private ArrayList<Integer> listOnOff = new ArrayList<>();
    private Activity activity;
    private String groupName;

    // ListViewAdapter의 생성자
    public DeviceListAdapter(Activity activity, List<DeviceInfo> listItem, String groupName) {
        this.activity = activity;
        listViewItemList = listItem;
        this.groupName = groupName;

        for(DeviceInfo d : listViewItemList) {
            listOnOff.add(NOT_CONNECTED);
        }
    }

    public DeviceListAdapter(Activity activity, List<DeviceInfo> listItem) {
        this.activity = activity;
        listViewItemList = listItem;
        groupName = "";
        for(DeviceInfo d : listViewItemList) {
            listOnOff.add(NOT_CONNECTED);
        }
    }

    // Adapter에 사용되는 데이터의 개수를 리턴. : 필수 구현
    @Override
    public int getCount() {
        return listViewItemList==null?0:listViewItemList.size() ;
    }

    // position에 위치한 데이터를 화면에 출력하는데 사용될 View를 리턴. : 필수 구현
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final int pos = position;
        final Context context = parent.getContext();

        // "listview_item" Layout을 inflate하여 convertView 참조 획득.
        if (convertView == null) {

        }

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.listview_device_list, parent, false);

        // 화면에 표시될 View(Layout이 inflate된)으로부터 위젯에 대한 참조 획득
        final LinearLayout layoutDevice = convertView.findViewById(R.id.layoutDevice);
        final TextView txtName = convertView.findViewById(R.id.txtName);
        final TextView txtGroupName = convertView.findViewById(R.id.txtGroupName);
        final TextView txtStatus = convertView.findViewById(R.id.txtStatus);
        final ImageView imgIcon = convertView.findViewById(R.id.imgIcon);

        // Data Set(listViewItemList)에서 position에 위치한 데이터 입력
        txtName.setText(listViewItemList.get(position).friendlyName.isEmpty()?listViewItemList.get(position).sharedFriendlyName.isEmpty()?IotPlatformApplication.getInstance().getString(R.string.no_name):listViewItemList.get(position).sharedFriendlyName:listViewItemList.get(position).friendlyName);
        txtGroupName.setText(listViewItemList.get(position).dgroupName.isEmpty()?groupName:listViewItemList.get(position).dgroupName);
        txtStatus.setText(activity.getString(R.string.not_connected));
        txtStatus.setVisibility(View.INVISIBLE);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if(txtStatus.getVisibility() != View.VISIBLE) {
                    txtStatus.setVisibility(View.VISIBLE);
                }
            }
        },2000);

        layoutDevice.setSelected(false);

        final String topicP = String.format(context.getString(R.string.topic_get_status),listViewItemList.get(position).deviceType,listViewItemList.get(position).deviceId);
        final String topicS1 = String.format(context.getString(R.string.topic_response_status),listViewItemList.get(position).deviceType,listViewItemList.get(position).deviceId);
        final String topicS2 = String.format(context.getString(R.string.topic_update_accepted),listViewItemList.get(position).deviceId);


        MqttController.getInstance().subscribeToTopic(topicS1, new AWSIotMqttNewMessageCallback() {
            @Override
            public void onMessageArrived(String topic, byte[] data) {
                DebugLogOutput(TAG, "MQTT SUB / "+topic + "\n" + new String(data));
                int power = NOT_CONNECTED;
                int dimming = NOTING;
                int colorTemp = NOTING;

                try {
                    JSONObject jsonObject = new JSONObject(new String(data));
                    if(!jsonObject.isNull("data")) {
                        JSONObject jsonState = jsonObject.getJSONObject("data");
                        if (!jsonState.isNull("state")) {
                            JSONObject jsonReported = jsonState.getJSONObject("state");
                            //Power
                            if (!jsonReported.isNull("power")) {
                                //power off
                                power = jsonReported.getInt("power");

                            }
                            //dimming
                            if (!jsonReported.isNull("dimm")) {
                                dimming = jsonReported.getInt("dimm");
                            }

                            //colorTemp
                            if (!jsonReported.isNull("temp")) {
                                colorTemp = jsonReported.getInt("temp");
                            }
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                final int powerFix = power;
                final int dimmingFix = dimming;
                final int colorTempFix = colorTemp;

                listOnOff.remove(pos);
                listOnOff.add(pos,powerFix);

                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        imgIcon.setImageResource(R.drawable.icon_add_device_light);
                        imgIcon.setBackgroundResource(R.drawable.background_circle_add_device_icon);
                        if(powerFix == 0) {
                            layoutDevice.setSelected(false);
                            txtStatus.setVisibility(View.VISIBLE);
                            txtStatus.setText(activity.getString(R.string.off));
                        } else if(powerFix == 1) {
                            layoutDevice.setSelected(true);
                            txtStatus.setVisibility(View.VISIBLE);
                            txtStatus.setText(activity.getString(R.string.on));
                        }

                        if(dimmingFix != -1) {

                        }

                        if(colorTempFix != -1) {

                        }
                    }
                });
            }
        });

        MqttController.getInstance().subscribeToTopic(topicS2, new AWSIotMqttNewMessageCallback() {
            @Override
            public void onMessageArrived(String topic, byte[] data) {
                DebugLogOutput(TAG, "MQTT SUB / "+topic + "\n" + new String(data));

                int temp_power = NOT_CONNECTED;

                try {
                    JSONObject jsonObject = new JSONObject(new String(data));

                    if(!jsonObject.isNull("data")) {//Get status topic
                        JSONObject jsonState = jsonObject.getJSONObject("data");
                        if (!jsonState.isNull("state")) {
                            JSONObject jsonReported = jsonState.getJSONObject("state");
                            //Power
                            if (!jsonReported.isNull("power")) {
                                //power off
                                temp_power = jsonReported.getInt("power");

                            }
                        }
                    } else if(!jsonObject.isNull("state")) {  //Update topic
                        JSONObject jsonState = jsonObject.getJSONObject("state");
                        if (!jsonState.isNull("reported")) {
                            JSONObject jsonReported = jsonState.getJSONObject("reported");
                            //Power
                            if (!jsonReported.isNull("power")) {
                                //power off
                                temp_power = jsonReported.getInt("power");

                            }
                        }

                        if (!jsonState.isNull("desired")) {
                            JSONObject jsonDesired = jsonState.getJSONObject("desired");
                            //Power
                            if (!jsonDesired.isNull("power")) {
                                //power off
                                temp_power = jsonDesired.getInt("power");

                            }
                        }

                        if(!jsonState.isNull("power")) {
                            temp_power = jsonState.getInt("power");
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                final int powerFix = temp_power;

                listOnOff.remove(pos);
                listOnOff.add(pos,powerFix);

                DebugLogOutput(TAG, "LIGHT_STATUS - power : "+powerFix);
                if(powerFix != NOT_CONNECTED) {
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            imgIcon.setImageResource(R.drawable.icon_add_device_light);
                            imgIcon.setBackgroundResource(R.drawable.background_circle_add_device_icon);
                            if(powerFix == 0) {
                                layoutDevice.setSelected(false);
                                txtStatus.setVisibility(View.VISIBLE);
                                txtStatus.setText(activity.getString(R.string.off));
                            } else if(powerFix == 1) {
                                layoutDevice.setSelected(true);
                                txtStatus.setVisibility(View.VISIBLE);
                                txtStatus.setText(activity.getString(R.string.on));
                            }
                        }
                    });
                }
            }
        });

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                MqttController.getInstance().publish(topicP,"{\"msgId\" : \""+UUID.randomUUID().toString()+"\"}");
                //MqttController.getInstance().publish(topicP,"{\"msgId\" : \""+listViewItemList.get(position).deviceId+"\"}");
            }
        },MQTT_PUBLISH_DELAY_TIME);

        return convertView;
    }

    // 지정한 위치(position)에 있는 데이터와 관계된 아이템(row)의 ID를 리턴. : 필수 구현
    @Override
    public long getItemId(int position) {
        return position ;
    }

    // 지정한 위치(position)에 있는 데이터 리턴 : 필수 구현
    @Override
    public Object getItem(int position) {
        return listViewItemList.get(position) ;
    }

    public boolean isAllOn() {
        boolean resault = true;
        for(Integer b : listOnOff){
            if(b == POWER_OFF){
                resault = false;
            }
        }
        return resault;
    }

    public void setOnOff() {
        long delayTime = 10;
        boolean b = isAllOn();

        for(int i = 0 ; i < listViewItemList.size() ; i++) {
            final int pos = i;
            if (listOnOff.get(pos) != NOT_CONNECTED) {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        final String topicUpdateP = String.format(activity.getString(R.string.topic_update), listViewItemList.get(pos).deviceId);
                        MqttController.getInstance().publish(topicUpdateP, "{\"state\": {\"desired\" : {\"power\" : " + (b ? "0" : "1") + "}}}");
                    }
                }, delayTime);
                delayTime += 5;
            }
        }
    }

    public void removeAll() {
        listViewItemList.clear();
        listOnOff.clear();
    }
}
