package com.fastbee.data.controller.sse;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.fastbee.common.core.controller.BaseController;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.core.domain.AjaxResultPro;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.domain.DeviceReportInfo;
import com.fastbee.iot.domain.UtilDeviceNumberAdd;
import com.fastbee.iot.mapper.DeviceMapper;
import com.fastbee.iot.mapper.DeviceReportInfoMapper;
import com.fastbee.iot.mapper.UtilDeviceNumberAddMapper;
import com.fastbee.iot.model.dto.DevicePowerDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 设备审核前上电基本信息
 */
@RestController
@RequestMapping("/sse")
@Slf4j
@CrossOrigin(origins = "*")
public class DeviceReportSSEController extends BaseController {
    private final Map<String, SseEmitter> emitters = new ConcurrentHashMap<>();//用户消息推送集合

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private DeviceReportInfoMapper deviceReportInfoMapper;

    @Autowired
    private UtilDeviceNumberAddMapper numberAddMapper ;


    @Autowired
    private DeviceMapper deviceMapper;

    /**
     * 与客户端建立http长链接
     */
    @PostMapping(value = "/device/init",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter getReport() throws IOException {
        SseEmitter emitter= new SseEmitter(0L);
        emitters.put("device-init",emitter);
        emitter.send(JSONUtil.toJsonStr(Message.builder().event(1).content("连接成功！").build()));
        return emitter;
    }

    @PostMapping("/device/init/new")
    public AjaxResultPro sendMsg(@RequestBody DevicePowerDTO reportInfo)  {
//            checkDeviceReportInfo(reportInfo);
        if(StringUtils.isBlank(reportInfo.getImei())){
            return AjaxResultPro.success(1102,"imei不能为空",null);
        }
        if(StringUtils.isBlank(reportInfo.getIccid())){
            return AjaxResultPro.success(1102,"iccid不能为空!",null);
        }
        if(StringUtils.isBlank(reportInfo.getMcuId())){
            return AjaxResultPro.success(1102,"mcuId不能为空!",null);
        }
        if(StringUtils.isBlank(reportInfo.getBspType())){
            return AjaxResultPro.success(1102,"bspType不能为空!",null);
        }
        if(StringUtils.isBlank(reportInfo.getLteType())){
            return AjaxResultPro.success(1102,"lteType不能为空!",null);
        }
        if(StringUtils.isBlank(reportInfo.getMcuType())){
            return AjaxResultPro.success(1102,"mcuType不能为空!",null);
        }
        if(StringUtils.isBlank(reportInfo.getMcuFw())){
            return AjaxResultPro.success(1102,"mcuFw不能为空!",null);
        }
        if(StringUtils.isBlank(reportInfo.getLteFw())){
            return AjaxResultPro.success(1102,"lteFw不能为空!",null);
        }
        if(StringUtils.isBlank(reportInfo.getLcdType())){
            return AjaxResultPro.success(1102,"lcdType不能为空!",null);
        }
        if(StringUtils.isBlank(reportInfo.getVoiceType())){
            return AjaxResultPro.success(1102,"voiceType不能为空!",null);
        }
        if(StringUtils.isBlank(reportInfo.getFacType())){
            return AjaxResultPro.success(111,"facType不能为空!",null);

        }
        if(StringUtils.isBlank(reportInfo.getTestRecord())){
            return AjaxResultPro.success(111,"testRecord不能为空!",null);
        }
            SseEmitter emitter = emitters.get("device-init");

//            String deviceNumber = generateDeviceNumber();
            //映射字段
            DeviceReportInfo deviceReportInfo= new DeviceReportInfo();
            deviceReportInfo.setImei(reportInfo.getImei());
            deviceReportInfo.setIccid(reportInfo.getIccid());
            deviceReportInfo.setMcuId(reportInfo.getMcuId());
            deviceReportInfo.setBspType(reportInfo.getBspType());
            deviceReportInfo.setLteType(reportInfo.getLteType());
            deviceReportInfo.setMcuType(reportInfo.getMcuType());
            deviceReportInfo.setMcuFw(reportInfo.getMcuFw());
            deviceReportInfo.setLteFw(reportInfo.getLteFw());
            deviceReportInfo.setLcdManufacturer(Long.valueOf(reportInfo.getLcdType()));
            deviceReportInfo.setVoiceManufacturer(Long.valueOf(reportInfo.getVoiceType()));
            deviceReportInfo.setReplaceManufacturer(Long.valueOf(reportInfo.getFacType()));
            deviceReportInfo.setTestRecord(reportInfo.getTestRecord());
            //设置状态为未审核
            deviceReportInfo.setStatus(1);
        //设备编码查重
        List<DeviceReportInfo> list = new LambdaQueryChainWrapper<>(deviceReportInfoMapper)
                .select(DeviceReportInfo::getSerialNumber,DeviceReportInfo::getImei,DeviceReportInfo::getStatus)
                .eq(DeviceReportInfo::getSerialNumber, deviceReportInfo.getSerialNumber())
                .or()
                .eq(DeviceReportInfo::getImei, deviceReportInfo.getImei())
                .list();
        if (!list.isEmpty()) {
            if (list.get(0).getImei().equals(deviceReportInfo.getImei())) {
                //如果已经审核通过了就更新信息进行覆盖，如果未审核就提示信息已提交待审核
                if(list.get(0).getStatus()==0){
                    return AjaxResultPro.success(1100,"设备注册信息已提交待审核，请勿重复提交!",null);
                }
                if (list.get(0).getStatus()==1) {
                    boolean update = new LambdaUpdateChainWrapper<>(deviceReportInfoMapper)
                            .set(DeviceReportInfo::getImei, reportInfo.getImei())
                            .set(DeviceReportInfo::getIccid, reportInfo.getIccid())
                            .set(DeviceReportInfo::getMcuId, reportInfo.getMcuId())
                            .set(DeviceReportInfo::getBspType,reportInfo.getBspType())
                            .set(DeviceReportInfo::getLteType, reportInfo.getLteType())
                            .set(DeviceReportInfo::getMcuType, reportInfo.getMcuType())
                            .set(DeviceReportInfo::getMcuFw, reportInfo.getMcuFw())
                            .set(DeviceReportInfo::getLteFw, reportInfo.getLteFw())
                            .set(DeviceReportInfo::getLcdManufacturer, Long.valueOf(reportInfo.getLcdType()))
                            .set(DeviceReportInfo::getVoiceManufacturer, Long.valueOf(reportInfo.getVoiceType()))
                            .set(DeviceReportInfo::getReplaceManufacturer, Long.valueOf(reportInfo.getFacType()))
                            .set(DeviceReportInfo::getTestRecord,reportInfo.getTestRecord())
                            .eq(DeviceReportInfo::getImei, deviceReportInfo.getImei())
                            .update();
                    if (update) {
                        Map<String,Object> map=new HashMap<>();
                        map.put("regSn",list.get(0).getSerialNumber());
                        return AjaxResultPro.success(1210, "设备注册信息更新!", map);
                    }
                }
                return AjaxResultPro.success(1105, "IMEI号重复!", null);
            }
        }
        //自动生成设备编码
        List<UtilDeviceNumberAdd> numberAdds = new LambdaQueryChainWrapper<>(numberAddMapper).list();
        System.err.println("累加列表："+numberAdds);
        if (numberAdds.isEmpty()) {
            return AjaxResultPro.success(1103,"未查询到设备编码排序信息！",null);
        }
        new LambdaUpdateChainWrapper<>(numberAddMapper).set(UtilDeviceNumberAdd::getSuffix, numberAdds.get(0).getSuffix() + 1).update();

        String genDeviceNumber= numberAdds.get(0).getPrefix()+padZero(numberAdds.get(0).getSuffix()+1);

        if(!list.isEmpty()){
            if (list.get(0).getSerialNumber().equals(deviceReportInfo.getSerialNumber())) {

                return AjaxResultPro.success(1103,"设备编号重复!",null);
            }
        }
        deviceReportInfo.setSerialNumber(genDeviceNumber);
        deviceReportInfo.setName(genDeviceNumber);
        deviceReportInfo.setType(1);
        int inserted = deviceReportInfoMapper.insertDeviceReportInfo(deviceReportInfo);
        if(inserted==0){
            return AjaxResultPro.success(1104,"设备上电审核信息插入失败！",null);
        }
        //插入成功后，插入设备信息
        Device device= new Device();
        device.setDeviceName(genDeviceNumber);
        device.setProductName("内乡县水电双计设备02");
        device.setFirmwareVersion(BigDecimal.valueOf(1));
        device.setSerialNumber(deviceReportInfo.getSerialNumber());
        device.setCreateTime(DateUtils.getNowDate());
        device.setProductId(147L);
        device.setStatus(1);//未激活
        device.setCreateTime(deviceReportInfo.getPowersTime());
        device.setTenantId(1L);//默认总管理员
        device.setLocationWay(3);
        device.setIsShadow(0);
        int inserted1 = deviceMapper.insert(device);
        if(inserted1<1){
            throw new ServiceException("插入设备信息失败！");
        }
        //当开启自动审核，也就是打开自动审核页面的时候需要推送到前端
        if(emitter!=null){
            try {
                emitter.send(JSONUtil.toJsonStr(Message.builder().event(2).content("新的消息").data(reportInfo).build()));
            } catch (IOException e) {
                return AjaxResultPro.success(1104,"推送上电基本信息失败！",null);
            }
        }

        Map<String,Object> map=new HashMap<>();
        map.put("regSn",deviceReportInfo.getSerialNumber());
        return AjaxResultPro.success(1200,"设备审核通过！",map);

    }

    @PostMapping("/device/init/new/remove")
    public AjaxResultPro removeMsg(){
        emitters.clear();
      return AjaxResultPro.success();
    }

    /**
     * 生成当前批次的设备编码
     */
    @GetMapping("/device/init/deviceNumber")
    public AjaxResultPro getDeviceNumber() {
        return AjaxResultPro.success(generateDeviceNumber());
    }


    /**
     * 上电审核前参数校验
     */
    private void checkDeviceReportInfo(DevicePowerDTO reportInfo){
        if(StringUtils.isBlank(reportInfo.getImei())){
            throw new ServiceException("imei不能为空");
        }
        if(StringUtils.isBlank(reportInfo.getIccid())){
            throw new ServiceException("iccid不能为空");
        }
        if(StringUtils.isBlank(reportInfo.getMcuId())){
            throw new ServiceException("mcuId不能为空");
        }
        if(StringUtils.isBlank(reportInfo.getBspType())){
            throw new ServiceException("bspType不能为空");
        }
        if(StringUtils.isBlank(reportInfo.getLteType())){
            throw new ServiceException("lteType不能为空");
        }
        if(StringUtils.isBlank(reportInfo.getMcuType())){
            throw new ServiceException("mcuType不能为空");
        }
        if(StringUtils.isBlank(reportInfo.getMcuFw())){
            throw new ServiceException("mcuFw不能为空");
        }
        if(StringUtils.isBlank(reportInfo.getLteFw())){
            throw new ServiceException("lteFw不能为空");
        }
        if(StringUtils.isBlank(reportInfo.getLcdType())){
            throw new ServiceException("lcdType不能为空");
        }
        if(StringUtils.isBlank(reportInfo.getVoiceType())){
            throw new ServiceException("voiceType不能为空");
        }
        if(StringUtils.isBlank(reportInfo.getFacType())){
            throw new ServiceException("facType不能为空");

        }
        if(StringUtils.isBlank(reportInfo.getTestRecord())){
            throw new ServiceException("testRecord不能为空");
        }

    }



    /**
     * 根据给定规则生成当前批次的起始设备编号
     * @return 生成的设备编号字符串
     */
    public  String generateDeviceNumber() {
        StringBuilder deviceNumber = new StringBuilder();
        // 添加固定的第一个字符'H'
        deviceNumber.append("H");
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        int year = currentDate.getYear();
        int month = currentDate.getMonthValue();
        // 根据年份确定对应的字符，以2024年对应'A'为起始，依次往后按字母顺序
        char yearChar = (char) ('A' + (year - 2024));
        deviceNumber.append(yearChar);
        // 月份转换为两位字符串格式，不足两位前面补0
        String monthStr = String.format("%02d", month);
        deviceNumber.append(monthStr);
        return deviceNumber.toString()+"00001";
    }

    public  String padZero(Long num) {
        return String.format("%05d", num);
    }
}
