package aicare.net.cn.sdk.ailinksdkdemoandroid;

import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

import androidx.annotation.Nullable;

import com.pingwang.bluetoothlib.bean.BleValueBean;
import com.pingwang.bluetoothlib.device.BleDevice;
import com.pingwang.bluetoothlib.listener.OnCallbackBle;
import com.pingwang.bluetoothlib.utils.BleStrUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import aicare.net.cn.sdk.ailinksdkdemoandroid.base.BleBaseActivity;
import aicare.net.cn.sdk.ailinksdkdemoandroid.utils.TimeUtils;
import cn.net.aicare.modulelibrary.module.TempHumidity.TempHumidityBleUtils;

/**
 * 温湿度计
 */
public class TempHumidityActivity extends BleBaseActivity implements OnCallbackBle, TempHumidityBleUtils.BleDataCallBack, View.OnClickListener {
    private String mAddress = "";
    private List<String> logList;
    private List<Long> historyLogListId;
    private ListView listView;
    private ArrayAdapter listAdapter;
    private EditText et_history;
    private TextView tv_result;
    private Button btn_find_device;
    private Button btn_set_sound;
    private Button btn_set_tell_time;
    private Button btn_set_night_light;
    private Button btn_set_backlight;

    private boolean isFinding;
    private boolean soundOpen = true;
    private boolean tellTimeOpen;
    private boolean nightLightOpen;
    private boolean backlightOpen;


    @Override
    public void onServiceSuccess() {
        addLog("绑定服务成功");
        if (mAILinkBleManager != null) {
            mAILinkBleManager.setOnCallbackBle(this);
            mAILinkBleManager.deviceConnectListener(mAddress, true);
            BleDevice bleDevice = mAILinkBleManager.getBleDevice(mAddress);
            if (bleDevice != null) {
                TempHumidityBleUtils.init(bleDevice);
                TempHumidityBleUtils.getInstance().setBleDataCallBack(this);
            } else {
                mAILinkBleManager.disconnectAll();
                startScanBle(0);
            }
        }
    }

    @Override
    public void onServiceErr() {
    }

    @Override
    public void unbindServices() {
        if (mAILinkBleManager != null) {
            mAILinkBleManager.removeOnCallbackBle(this);
        }
    }


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_temp_humidity);
        mAddress = getIntent().getStringExtra("mac");
        logList = new ArrayList<>();
        historyLogListId = new ArrayList<>();

        listView = findViewById(R.id.listView);
        tv_result = findViewById(R.id.tv_result);
        et_history = findViewById(R.id.et_history);
        btn_find_device = findViewById(R.id.btn_find_device);
        btn_set_sound = findViewById(R.id.btn_set_sound);
        btn_set_tell_time = findViewById(R.id.btn_set_tell_time);
        btn_set_night_light = findViewById(R.id.btn_set_night_light);
        btn_set_backlight = findViewById(R.id.btn_set_backlight);

        int[] clickIds = {
                R.id.btn_support_fun, R.id.btn_device_status, R.id.btn_app_info, R.id.btn_syn_time,
                R.id.btn_device_alarm, R.id.btn_set_alarm, R.id.btn_get_unit, R.id.btn_set_unit_c,
                R.id.btn_set_unit_f, R.id.btn_find_device,
                R.id.btn_get_calibration, R.id.btn_set_calibration, R.id.btn_get_sound, R.id.btn_set_sound,
                R.id.btn_check_alarm_clock, R.id.btn_set_alarm_clock, R.id.btn_get_tell_time, R.id.btn_set_tell_time,
                R.id.btn_get_night_light, R.id.btn_set_night_light, R.id.btn_get_backlight, R.id.btn_set_backlight,
                R.id.btn_history, R.id.btn_history_next, R.id.btn_history_done, R.id.btn_clear_history, R.id.btn_ota,
                R.id.btn_clear_log
        };
        for (int id : clickIds) {
            findViewById(id).setOnClickListener(this);
        }

        listAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, logList);
        listView.setAdapter(listAdapter);
    }

    @Override
    public void onStartScan() {
    }

    @Override
    public void onScanning(BleValueBean data) {
        if (data.getMac().equalsIgnoreCase(mAddress)) {
            stopScanBle();
            mAILinkBleManager.connectDevice(mAddress);
        }
    }

    @Override
    public void onScanTimeOut() {
    }

    @Override
    public void onConnecting(String mac) {
    }

    @Override
    public void onDisConnected(String mac, int code) {
        if (mac.equals(mAddress)) {
            isFinding = false;
            updateFindButton();
            addLog("连接已经断开");
        }
    }

    @Override
    public void onConnectionSuccess(String mac) {
        stopScanBle();
        addLog("连接成功" + mac);
    }

    @Override
    public void onServicesDiscovered(String mac) {
        if (mac.equalsIgnoreCase(mAddress)) {
            stopScanBle();
            BleDevice bleDevice = mAILinkBleManager.getBleDevice(mAddress);
            if (bleDevice != null) {
                TempHumidityBleUtils.init(bleDevice);
                TempHumidityBleUtils.getInstance().setBleDataCallBack(this);
            }
        }
    }

    @Override
    public void bleOpen() {
    }

    @Override
    public void bleClose() {
    }


    @Override
    public void onClick(View v) {
        TempHumidityBleUtils utils = TempHumidityBleUtils.getInstance();
        if (utils == null) {
            addLog("设备未连接");
            return;
        }

        int id = v.getId();
        if (id == R.id.btn_support_fun) {
            utils.getSupportFunction();
            addLog("获取支持功能");
        } else if (id == R.id.btn_device_status) {
            utils.getDeviceStatus();
            addLog("读取设备状态");
        } else if (id == R.id.btn_app_info) {
            utils.getAppInfo();
            addLog("获取设备信息");
        } else if (id == R.id.btn_syn_time) {
            utils.synTime();
            addLog("同步UTC时间");
        } else if (id == R.id.btn_device_alarm) {
            utils.getDeviceAlarm();
            addLog("获取设备报警");
        } else if (id == R.id.btn_set_alarm) {
            // 示意: 温度10~35℃开, 湿度20~80%开
            utils.setWarmConfig(true, 35f, 10f, true, 80, 20);
            addLog("设置报警 温度10~35℃ 湿度20~80%");
        } else if (id == R.id.btn_get_unit) {
            utils.getUnit();
            addLog("读取单位");
        } else if (id == R.id.btn_set_unit_c) {
            utils.setUnit(TempHumidityBleUtils.UNIT_C);
            addLog("设置单位: ℃");
        } else if (id == R.id.btn_set_unit_f) {
            utils.setUnit(TempHumidityBleUtils.UNIT_F);
            addLog("设置单位: ℉");
        } else if (id == R.id.btn_find_device) {
            isFinding = !isFinding;
            utils.findDevice(isFinding);
            updateFindButton();
            addLog(isFinding ? "开启APP寻物" : "关闭APP寻物");
        } else if (id == R.id.btn_get_calibration) {
            utils.getCalibration();
            addLog("读取校准");
        } else if (id == R.id.btn_set_calibration) {
            utils.setCalibration(1f, 1f, 1f);
            addLog("设置校准 +1℃ +1℉ +1%");
        } else if (id == R.id.btn_get_sound) {
            utils.getSound();
            addLog("读取蜂鸣器");
        } else if (id == R.id.btn_set_sound) {
            soundOpen = !soundOpen;
            utils.setSound(soundOpen);
            updateToggleButton(btn_set_sound, "蜂鸣器", soundOpen);
            addLog(soundOpen ? "打开蜂鸣器" : "关闭蜂鸣器");
        } else if (id == R.id.btn_check_alarm_clock) {
            utils.checkAlarmClock();
            addLog("查询闹钟");
        } else if (id == R.id.btn_set_alarm_clock) {
            // 编号1, 每天, 8:00, 激活
            int seconds = 8 * 3600;
            utils.setAlarmClock(TempHumidityBleUtils.ALARM_CLOCK_ADD, 1, 0x01, seconds, 0x01);
            addLog("设置闹钟 编号1 每天 08:00");
        } else if (id == R.id.btn_get_tell_time) {
            utils.getTellTime();
            addLog("读取整点报时");
        } else if (id == R.id.btn_set_tell_time) {
            tellTimeOpen = !tellTimeOpen;
            utils.setTellTime(tellTimeOpen);
            updateToggleButton(btn_set_tell_time, "整点报时", tellTimeOpen);
            addLog(tellTimeOpen ? "打开整点报时" : "关闭整点报时");
        } else if (id == R.id.btn_get_night_light) {
            utils.getNightLight();
            addLog("读取夜灯");
        } else if (id == R.id.btn_set_night_light) {
            nightLightOpen = !nightLightOpen;
            utils.setNightLight(nightLightOpen);
            updateToggleButton(btn_set_night_light, "夜灯", nightLightOpen);
            addLog(nightLightOpen ? "打开夜灯" : "关闭夜灯");
        } else if (id == R.id.btn_get_backlight) {
            utils.getBacklight();
            addLog("读取背光");
        } else if (id == R.id.btn_set_backlight) {
            backlightOpen = !backlightOpen;
            utils.setBacklight(backlightOpen, 50);
            updateToggleButton(btn_set_backlight, "背光50%", backlightOpen);
            addLog(backlightOpen ? "打开背光亮度50" : "关闭背光");
        } else if (id == R.id.btn_history) {
            String s = et_history.getText().toString().trim();
            long maxId = 0;
            if (!s.isEmpty()) {
                try {
                    maxId = Long.parseLong(s);
                } catch (NumberFormatException e) {
                    addLog("历史时间Id格式错误");
                    return;
                }
            }
            utils.getOffLineRecord(maxId);
            addLog("获取历史记录 时间Id:" + maxId);
            tv_result.setText("");
            historyLogListId.clear();
        } else if (id == R.id.btn_history_next) {
            utils.sendOfflineRecordStatus(0x01);
            addLog("请求下一组历史");
        } else if (id == R.id.btn_history_done) {
            utils.sendOfflineRecordStatus(0x00);
            addLog("历史接收完毕");
        } else if (id == R.id.btn_clear_history) {
            utils.removeData();
            addLog("清除设备历史");
        } else if (id == R.id.btn_ota) {
            utils.ota();
            addLog("请求OTA");
        } else if (id == R.id.btn_clear_log) {
            logList.clear();
            historyLogListId.clear();
            tv_result.setText("");
            listAdapter.notifyDataSetChanged();
        }
    }

    private void updateFindButton() {
        if (btn_find_device != null) {
            btn_find_device.setText(isFinding ? "寻物中(点关)" : "APP寻物");
        }
    }

    private void updateToggleButton(Button button, String name, boolean open) {
        if (button != null) {
            button.setText(name + (open ? "(开)" : "(关)"));
        }
    }

    @Override
    public void onDeviceStatus(int battery, long time, float temp, int unit, float humidity, int status) {
        String unitStr = unit == TempHumidityBleUtils.UNIT_F ? "℉" : "℃";
        String statusStr;
        if (status == 0x00) {
            statusStr = "APP读取";
        } else if (status == 0x01) {
            statusStr = "普通上报";
        } else if (status == 0x02) {
            statusStr = "报警上报";
        } else {
            statusStr = "0x" + String.format("%02X", status);
        }
        String timeStr = TimeUtils.getTime(time * 1000);
        addLog("设备状态:\n电量:" + battery + "% 时间:" + timeStr
                + " 时间戳:" + time
                + " 温度:" + temp + unitStr + " 湿度:" + humidity + "%"
                + " 上报:" + statusStr);
    }

    @Override
    public void onOffLineRecordNum(long total, long sendNum) {
        addLog("历史记录 总量:" + total + " 发送量:" + sendNum);
        if (total == sendNum) {
            if (!historyLogListId.isEmpty()) {
                Collections.sort(historyLogListId);
                tv_result.setText("总:" + historyLogListId.size()
                        + " 开:" + historyLogListId.get(0)
                        + " 结:" + historyLogListId.get(historyLogListId.size() - 1));
            } else {
                tv_result.setText("");
            }
        }
    }

    @Override
    public void onOffLineRecord(long time, float temp, int unit, float humidity) {
        historyLogListId.add(time);
        String unitStr = unit == TempHumidityBleUtils.UNIT_F ? "℉" : "℃";
        addLog("历史 时间戳:" + time + " 温度:" + temp + unitStr + " 湿度:" + humidity);
    }

    @Override
    public void onSupportFunction(int calibration, int buzzerAlarm, int alarmFunction,
                                  int reportPunctually, int nightLight, int bgLight,
                                  int findDevice, int bindDevice, byte[] bytes) {
        addLog("支持功能 raw:" + BleStrUtils.byte2HexStr(bytes)
                + "\n校准:" + (calibration == 1)
                + " 蜂鸣器:" + (buzzerAlarm == 1)
                + " 闹钟:" + (alarmFunction == 1)
                + "\n整点报时:" + (reportPunctually == 1)
                + " 夜灯:" + (nightLight == 1)
                + " 背光:" + (bgLight == 1)
                + "\n寻物:" + (findDevice == 1)
                + " 绑定:" + (bindDevice == 1));
    }

    @Override
    public void onDeviceAlarm(boolean openTemp, float tempHigh, float tempLow,
                              boolean openHumidity, float humidityHigh, float humidityLow) {
        addLog("设备报警 温度开关:" + openTemp + " 上限:" + tempHigh + " 下限:" + tempLow
                + "\n湿度开关:" + openHumidity + " 上限:" + humidityHigh + " 下限:" + humidityLow);
    }

    @Override
    public void onUnit(int unit) {
        String unitStr = unit == TempHumidityBleUtils.UNIT_F ? "℉" : "℃";
        addLog("当前单位:" + unitStr + "(0x" + String.format("%02X", unit) + ")");
    }

    @Override
    public void onFindDevice(int status) {
        isFinding = status == 0x00;
        updateFindButton();
        addLog("寻物状态:" + (isFinding ? "正在报警" : "停止报警"));
    }

    @Override
    public void onCalibration(float tempC, float tempF, float humidity) {
        addLog("校准偏置 ℃:" + tempC + " ℉:" + tempF + " 湿度:" + humidity);
    }

    @Override
    public void onBuzzerState(boolean isOpen) {
        soundOpen = isOpen;
        updateToggleButton(btn_set_sound, "蜂鸣器", soundOpen);
        addLog("蜂鸣器:" + (isOpen ? "打开" : "关闭"));
    }

    @Override
    public void onAlarmClock(int type, int no, int mode, int second, int state) {
        int hour = second / 3600;
        int min = (second % 3600) / 60;
        addLog("闹钟 type:" + type + " 编号:" + no
                + " 模式:" + (mode == 1 ? "每天" : "一次")
                + " 时间:" + String.format("%02d:%02d", hour, min)
                + " 状态:" + (state == 1 ? "激活" : "关闭"));
    }

    @Override
    public void onTellTimeState(boolean isOpen) {
        tellTimeOpen = isOpen;
        updateToggleButton(btn_set_tell_time, "整点报时", tellTimeOpen);
        addLog("整点报时:" + (isOpen ? "打开" : "关闭"));
    }

    @Override
    public void onNightLightState(boolean isOpen) {
        nightLightOpen = isOpen;
        updateToggleButton(btn_set_night_light, "夜灯", nightLightOpen);
        addLog("小夜灯:" + (isOpen ? "打开" : "关闭"));
    }

    @Override
    public void onBgLightState(boolean isOpen, int value) {
        backlightOpen = isOpen;
        updateToggleButton(btn_set_backlight, "背光50%", backlightOpen);
        addLog("背光:" + (isOpen ? "打开" : "关闭") + " 亮度:" + value);
    }

    @Override
    public void onClearHistoryData(int result) {
        addLog("清除历史结果:" + (result == 0x00 ? "成功" : result));
    }

    @Override
    public void onSupportHistoryData(boolean support) {
        addLog("是否支持历史:" + support);
    }

    @Override
    public void onDeviceType(int deviceType) {
        String typeStr;
        if (deviceType == 0x00) {
            typeStr = "单BLE";
        } else if (deviceType == 0x01) {
            typeStr = "BLE+WiFi";
        } else if (deviceType == 0x02) {
            typeStr = "BLE+4G";
        } else {
            typeStr = "未知(" + deviceType + ")";
        }
        addLog("设备类型:" + typeStr);
    }

    @Override
    public void onReportTime(int time) {
        addLog("例行上报时间:" + time + "s");
    }

    @Override
    public void onSyncTimeSuccess(boolean status) {
        addLog("同步UTC时间:" + status);
    }

    private void addLog(String msg) {
        logList.add(0, msg);
        listAdapter.notifyDataSetChanged();
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mAILinkBleManager != null)
            mAILinkBleManager.disconnectAll();
    }
}
