package com.pwt.web.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.pwt.cloud.domin.CloudBattery;
import com.pwt.cloud.domin.CurrentAccountInfo;
import com.pwt.cloud.domin.Device;
import com.pwt.cloud.enums.CloudUrlEnum;
import com.pwt.cloud.params.ChangeFinishParam;
import com.pwt.cloud.params.ChargeFinishParam;
import com.pwt.common.utils.CacheMap;
import com.pwt.common.utils.spring.SpringUtils;
import com.pwt.netty.BusinessException;
import com.pwt.system.domain.PwtConfig;
import com.pwt.system.service.IPwtConfigService;
import com.pwt.web.service.ICloudService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 云平台业务处理类
 *
 * @author hanshuangxi
 * @date 2023/8/22 9:31
 */
@Service
@Slf4j
public class CloudServiceImpl implements ICloudService {

    private static String CLOUD_ADDRESS = "";

    private static String CLOUD_ACCOUNT = "";

    private static String CLOUD_PASSWORD = "";

    private static boolean CLOUD_ENABLED = false;
    private static String TOKEN = "";

    private static int COUNT = 0;

    static {
        try {
            getCloudInfo();
        } catch (BusinessException e) {
            log.error("云平台相关配置加载失败，{}", e.getMessage());
            throw new RuntimeException(e);
        }
    }

    @Override
    public void getToken() throws BusinessException {
        Map<String, Object> param = new HashMap<>();
        param.put("account", CLOUD_ACCOUNT);
        param.put("password", CLOUD_PASSWORD);
        TOKEN = sendHttp(CloudUrlEnum.LOGIN, param);
    }

    @Override
    public CurrentAccountInfo getCurrentAccountInfo() throws BusinessException {
        return JSONObject.parseObject(sendHttp(CloudUrlEnum.CURRENT_ACCOUNT, null), CurrentAccountInfo.class);
    }

    @Override
    public List<Device> deviceList() throws BusinessException {
        return JSON.parseArray(sendHttp(CloudUrlEnum.DEVICE_LIST, null), Device.class);
    }

    @Override
    public List<CloudBattery> batteryList() throws BusinessException {
        return JSON.parseArray(sendHttp(CloudUrlEnum.BATTERY_LIST, null), CloudBattery.class);
    }

    @Override
    public List<CloudBattery> changeStart(String vehicleCode, String deviceCode) throws BusinessException {
        Map<String, Object> map = new HashMap<>();
        map.put("vehicleCode", vehicleCode);
        map.put("deviceCode", deviceCode);
        return JSON.parseArray(sendHttp(CloudUrlEnum.CHANGE_START, map), CloudBattery.class);
    }

    @Override
    public void changeFinish(ChangeFinishParam changeFinishParam) throws BusinessException {
        Map<String, Object> map = BeanUtil.beanToMap(changeFinishParam);
        sendHttp(CloudUrlEnum.CHANGE_FINISH, map);
    }

    @Override
    public void chargeStart(String vehicleCode, String deviceCode) throws BusinessException {
        Map<String, Object> map = new HashMap<>();
        map.put("vehicleCode", vehicleCode);
        map.put("deviceCode", deviceCode);
        sendHttp(CloudUrlEnum.CHARGE_START, map);
    }

    @Override
    public void chargeFinish(ChargeFinishParam chargeFinishParam) throws BusinessException {
        Map<String, Object> map = BeanUtil.beanToMap(chargeFinishParam);
        sendHttp(CloudUrlEnum.CHARGE_FINISH, map);
    }

    @Override
    public void powerStart(String batteryCode, String deviceCode) throws BusinessException {
        Map<String, Object> map = new HashMap<>();
        map.put("batteryCode", batteryCode);
        map.put("deviceCode", deviceCode);
        sendHttp(CloudUrlEnum.POWER_START, map);
    }

    @Override
    public void powerFinish(String batteryCode, String deviceCode, double level) throws BusinessException {
        Map<String, Object> map = new HashMap<>();
        map.put("batteryCode", batteryCode);
        map.put("deviceCode", deviceCode);
        map.put("level", level);
        sendHttp(CloudUrlEnum.POWER_FINISH, map);
    }

    @Override
    public void alarmStart(String deviceCode, String faultCode, String grade) throws BusinessException {
        Map<String, Object> map = new HashMap<>();
        map.put("deviceCode", deviceCode);
        map.put("grade", grade);
        sendHttp(CloudUrlEnum.ALARM_START, map);
    }

    @Override
    public void alarmFinish(String deviceCode, String faultCode) throws BusinessException {
        Map<String, Object> map = new HashMap<>();
        map.put("deviceCode", deviceCode);
        map.put("faultCode", faultCode);
        sendHttp(CloudUrlEnum.ALARM_FINISH, map);
    }

    @Override
    public void stationStatus(String status) throws BusinessException {
        Map<String, Object> map = new HashMap<>();
        map.put("status", status);
        sendHttp(CloudUrlEnum.STATION_STATUS, map);
    }

    @Override
    public void stationWait(String wait) throws BusinessException {
        Map<String, Object> map = new HashMap<>();
        map.put("wait", wait);
        sendHttp(CloudUrlEnum.STATION_WAIT, map);
    }

    @Override
    public void deviceMeasure(String code, Map<String, Object>[] maps) throws BusinessException {
        Map<String, Object> map = new HashMap<>();
        map.put("code", code);
        map.put("maps", maps);
        sendHttp(CloudUrlEnum.DEVICE_MEASURE, map);
    }

    @Override
    public void vehicleLocation(String code, String location) throws BusinessException {
        Map<String, Object> map = new HashMap<>();
        map.put("code", code);
        map.put("location", location);
        sendHttp(CloudUrlEnum.VEHICLE_LOCATION, map);
    }

    public static void getCloudInfo() throws BusinessException {
        IPwtConfigService pwtConfigService = SpringUtils.getBean(IPwtConfigService.class);
        PwtConfig pwtConfig = pwtConfigService.selectPwtConfigById(1L);
        if (Objects.isNull(pwtConfig)) {
            log.error("缺少云平台相关配置");
            throw new BusinessException("缺少云平台相关配置");
        }
        String cloudAddress = pwtConfig.getCloudAddress();
        if (StrUtil.isEmpty(cloudAddress)) {
            log.error("缺少云平台地址配置");
            throw new BusinessException("缺少云平台地址配置");
        }
        String cloudAccount = pwtConfig.getCloudAccount();
        if (StrUtil.isEmpty(cloudAccount)) {
            log.error("缺少云平台账号信息");
            throw new BusinessException("缺少云平台账号信息");
        }

        String cloudPassword = pwtConfig.getCloudPassword();
        if (StrUtil.isEmpty(cloudPassword)) {
            log.error("缺少云平台密码信息");
            throw new BusinessException("缺少云平台密码信息");
        }

        CLOUD_ENABLED = pwtConfig.getCloudEnabled();
        CLOUD_ADDRESS = cloudAddress;
        CLOUD_ACCOUNT = cloudAccount;
        CLOUD_PASSWORD = cloudPassword;
    }

    private String analysisResult(String result, CloudUrlEnum cloudUrlEnum, Map<String, Object> map) throws BusinessException {
        JSONObject jsonObject = JSONObject.parseObject(result);
        boolean success = jsonObject.getBooleanValue("success");
        if (success) {
            return jsonObject.getString("data");
        } else {
            Integer status = jsonObject.getInteger("status");
            if (Objects.nonNull(status) && status.equals(401)) {
                TOKEN = "";
                //获取token重新发送请求
                tryGetToken();
                return sendHttp(cloudUrlEnum, map);
            } else {
                log.error("{},返回数据异常，{}", cloudUrlEnum.getUrl(), jsonObject.getString("errorMessage"));
                throw new BusinessException(cloudUrlEnum.getUrl() + ",返回数据异常，" + jsonObject.getString("errorMessage"));
            }
        }
    }

    private String sendHttp(CloudUrlEnum cloudUrlEnum, Map<String, Object> param) throws BusinessException {
        //如果未开启云平台，则直接结束
        if (!CLOUD_ENABLED) return null;
        log.info("云平台发送了：{},参数{}", cloudUrlEnum.getUrl(), Objects.nonNull(param) ? param.toString() : "无");
        String url = CLOUD_ADDRESS + cloudUrlEnum.getUrl();
        HttpRequest httpRequest = "get".equals(cloudUrlEnum.getMethod()) ? HttpRequest.get(url) : HttpRequest.post(url);
        httpRequest.body(JSON.toJSONString(param)).timeout(10 * 1000);
        if (cloudUrlEnum.isAuthentication()) {
            tryGetToken();
            httpRequest.header(Header.AUTHORIZATION, "Bearer " + TOKEN);
        }
        String result = httpRequest.execute().body();
        return analysisResult(result, cloudUrlEnum, param);
    }

    private void tryGetToken() {
        if (StrUtil.isNotEmpty(TOKEN)) {
            COUNT = 0;
            return;
        }
        if (StrUtil.isEmpty(TOKEN) && COUNT > 5) {
            COUNT = 0;
            log.error("多次获取云平台token失败！！");
            return;
        }
        try {
            COUNT++;
            getToken();
            if (StrUtil.isEmpty(TOKEN)) tryGetToken();
        } catch (Exception e) {
            log.error(e.getMessage());
            tryGetToken();
        }

    }

}