package com.njcn.csdevice.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.csdevice.api.CsLedgerFeignClient;
import com.njcn.csdevice.mapper.CsTerminalReplyMapper;
import com.njcn.csdevice.param.IcdBzReplyParam;
import com.njcn.csdevice.pojo.po.CsEquipmentDeliveryPO;
import com.njcn.csdevice.pojo.po.CsTerminalReply;
import com.njcn.csdevice.pojo.vo.CldLogsVo;
import com.njcn.csdevice.pojo.vo.CsLedgerVO;
import com.njcn.csdevice.service.CsEquipmentDeliveryService;
import com.njcn.csdevice.service.ICsTerminalLogsService;
import com.njcn.csdevice.service.ICsTerminalReplyService;
import com.njcn.csdevice.service.INodeService;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.web.factory.PageFactory;
import com.njcn.web.pojo.param.BaseParam;
import com.njcn.web.utils.RequestUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xy
 * @since 2025-10-09
 */
@Service
@RequiredArgsConstructor
public class CsTerminalReplyServiceImpl extends ServiceImpl<CsTerminalReplyMapper, CsTerminalReply> implements ICsTerminalReplyService {

    private final RedisUtil redisUtil;
    private final INodeService nodeService;
    private final CsEquipmentDeliveryService csEquipmentDeliveryService;
    private final ICsTerminalLogsService csTerminalLogsService;
    private final CsLedgerFeignClient csLedgerFeignClient;

    @Override
    public List<String> queryReplyData() {
        List<String> result = new ArrayList<>();
        Object object = redisUtil.getObjectByKey(RequestUtil.getUserIndex()+"reply");
        if (object != null) {
            List<String> redisList = Stream.of(object.toString().split(",")).collect(Collectors.toList());
            List<CsTerminalReply> list = this.lambdaQuery().in(CsTerminalReply::getReplyId,redisList).orderByAsc(CsTerminalReply::getCreateTime).list();
            if (CollectionUtil.isNotEmpty(list)) {
                list.forEach(item->{
                    String key;
                    String code = "";
                    if (Objects.equals(item.getCode(), "add_terminal")) {
                        code = "新增";
                    } else if (Objects.equals(item.getCode(), "ledger_modify")) {
                        code = "修改";
                    } else if (Objects.equals(item.getCode(), "delete_terminal")){
                        code = "删除";
                    }
                    String nodeName = nodeService.getNodeById(item.getNodeId()).getName();
                    List<CsEquipmentDeliveryPO> devList1 = csEquipmentDeliveryService.getAll();
                    List<CsEquipmentDeliveryPO> devList2 = devList1.stream().filter(item1 -> Objects.equals(item1.getId(), item.getDeviceId())).collect(Collectors.toList());
                    List<String> devNameList = devList2.stream().map(CsEquipmentDeliveryPO::getName).collect(Collectors.toList());
                    String devNameListString;
                    if (CollectionUtil.isNotEmpty(devNameList)) {
                        devNameListString = devNameList.toString();
                    } else {
                        devNameListString = "[" + item.getDeviceName() + "]";
                    }
                    if (item.getIsReceived() == 0) {
                        key = nodeName + item.getProcessNo() + "号进程下," + devNameListString + "设备未收到应答";
                        //将cs_terminal_logs数据置为未发送
                        csTerminalLogsService.updateLaterData(item.getDeviceId(),item.getCode());
                    } else if (item.getIsReceived() == 1){
                        key = nodeName + item.getProcessNo() + "号进程下," + devNameListString + "设备" + code + "数据成功";
                    } else {
                        key = nodeName + item.getProcessNo() + "号进程下," + devNameListString + "设备" + code + "数据失败";
                    }
                    result.add(key);
                });
            }

        }
        return result;
    }

//    @Override
//    public List<String> queryReplyData() {
//        List<String> result = new ArrayList<>();
//        Object object = redisUtil.getObjectByKey(RequestUtil.getUserIndex()+"reply");
//        if (object != null) {
//            List<String> redisList = Stream.of(object.toString().split(",")).collect(Collectors.toList());
//            List<CsTerminalReply> list = this.lambdaQuery().in(CsTerminalReply::getReplyId,redisList).orderByAsc(CsTerminalReply::getCreateTime).list();
//            if (CollectionUtil.isNotEmpty(list)) {
//                Map<Integer,List<CsTerminalReply>> map = list.stream().collect(Collectors.groupingBy(CsTerminalReply::getIsReceived));
//                List<CsTerminalReply> list1 = map.get(1);
//                if (CollectionUtil.isEmpty(list1)) {
//                    String key = "更新失败,未收到前置应答,请查看应答报文是否发送";
//                    result.add(key);
//                    //将cs_terminal_logs数据置为未发送
//                    list.forEach(item->{
//                        csTerminalLogsService.updateLaterData(item.getDeviceId(),item.getCode());
//                    });
//                } else {
//                    list.forEach(item->{
//                        String key;
//                        String code = "";
//                        if (Objects.equals(item.getCode(), "add_terminal")) {
//                            code = "新增";
//                        } else if (Objects.equals(item.getCode(), "ledger_modify")) {
//                            code = "修改";
//                        } else if (Objects.equals(item.getCode(), "delete_terminal")){
//                            code = "删除";
//                        }
//                        String nodeName = nodeService.getNodeById(item.getNodeId()).getName();
//                        List<CsEquipmentDeliveryPO> devList1 = csEquipmentDeliveryService.getAll();
//                        List<CsEquipmentDeliveryPO> devList2 = devList1.stream().filter(item1 -> Objects.equals(item1.getId(), item.getDeviceId())).collect(Collectors.toList());
//                        List<String> devNameList = devList2.stream().map(CsEquipmentDeliveryPO::getName).collect(Collectors.toList());
//                        String devNameListString;
//                        if (CollectionUtil.isNotEmpty(devNameList)) {
//                            devNameListString = devNameList.toString();
//                        } else {
//                            devNameListString = "[" + item.getDeviceName() + "]";
//                        }
//                        if (item.getIsReceived() == 0) {
//                            key = nodeName + item.getProcessNo() + "号进程下," + devNameListString + "设备未收到应答";
//                            //将cs_terminal_logs数据置为未发送
//                            csTerminalLogsService.updateLaterData(item.getDeviceId(),item.getCode());
//                        } else if (item.getIsReceived() == 1){
//                            key = nodeName + item.getProcessNo() + "号进程下," + devNameListString + "设备" + code + "数据成功";
//                        } else {
//                            key = nodeName + item.getProcessNo() + "号进程下," + devNameListString + "设备" + code + "数据失败";
//                        }
//                        result.add(key);
//                    });
//                }
//            }
//        }
//        return result;
//    }

    @Override
    public void updateReplyData(IcdBzReplyParam param) {
        LambdaUpdateWrapper<CsTerminalReply> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(CsTerminalReply::getIsReceived,param.getState())
                .set(CsTerminalReply::getReceivedCode,param.getCode())
                .set(CsTerminalReply::getReceivedMsg,param.getMsg())
                .eq(CsTerminalReply::getReplyId,param.getId())
                .eq(CsTerminalReply::getDeviceId,param.getDeviceId());
        this.update(wrapper);
    }

    @Override
    public List<CsTerminalReply> getBzReplyData(String lineId) {
        LambdaQueryWrapper<CsTerminalReply> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CsTerminalReply::getCode,Arrays.asList("allFile","allEvent","oneFile","harmonic"))
                .orderByDesc(CsTerminalReply::getCreateTime);
        if (!Objects.isNull(lineId) && StringUtils.isNotBlank(lineId)) {
            wrapper.like(CsTerminalReply::getLineId,lineId);
        }
        return this.list(wrapper);
    }

    @Override
    public Page<CldLogsVo> getBzLogs(BaseParam param) {
        Page<CldLogsVo> page = new Page<>(PageFactory.getPageNum(param), PageFactory.getPageSize(param));
        QueryWrapper<CsTerminalReply> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(param.getSearchValue())) {
            queryWrapper.like("cs_terminal_reply.line_id", param.getSearchValue());
        }
        queryWrapper.between("cs_terminal_reply.Create_Time"
                , DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime()))
                , DateUtil.endOfDay(DateUtil.parse(param.getSearchEndTime())));
        //排序
        queryWrapper.orderBy(true, false, "cs_terminal_reply.create_time");
        //这边不想新建字段了，用SortBy代替补召类型
        if (Objects.equals(param.getSortBy(), "harmonic")) {
            queryWrapper.in("cs_terminal_reply.code", Collections.singletonList("harmonic"));
        } else {
            queryWrapper.in("cs_terminal_reply.code", Arrays.asList("allFile", "allEvent", "oneFile"));
        }
        Page<CsTerminalReply> csTerminalReplyPage = this.baseMapper.page(new Page<>(PageFactory.getPageNum(param), PageFactory.getPageSize(param)), queryWrapper);

        List<CsTerminalReply> records = csTerminalReplyPage.getRecords();
        if (CollectionUtil.isNotEmpty(records)) {
            List<CsLedgerVO> data = csLedgerFeignClient.getAllLedger().getData();
            Map<String, CsLedgerVO> ledgerMap = data.stream().collect(Collectors.toMap(CsLedgerVO::getId, Function.identity()));
            List<CldLogsVo> cldLogsVos = new ArrayList<>();
            records.forEach(item->{
                if (Objects.isNull(ledgerMap.get(item.getDeviceId()))) {
                    return;
                }
                String pids = ledgerMap.get(item.getDeviceId()).getPids();
                String[] split = pids.split(",");
                CldLogsVo cldLogsVo = new CldLogsVo();
                cldLogsVo.setEngineeringName(ledgerMap.get(split[1]).getName());
                cldLogsVo.setProjectName(ledgerMap.get(split[2]).getName());
                cldLogsVo.setDeviceName(ledgerMap.get(item.getDeviceId()).getName());
                cldLogsVo.setLineName(ledgerMap.get(param.getSearchValue()).getName());
                cldLogsVo.setLog(getLogDescription(item.getCode()));
                cldLogsVo.setLogTime(item.getCreateTime());
                if (Objects.equals(item.getIsReceived(),0)) {
                    cldLogsVo.setStatus("补召已下发");
                    cldLogsVo.setResult("/");
                } else {
                    if (item.getReceivedCode() == 200) {
                        cldLogsVo.setStatus("补召成功");
                        cldLogsVo.setResult(item.getReceivedMsg());
                    } else {
                        cldLogsVo.setStatus("补召失败");
                        cldLogsVo.setResult(item.getReceivedMsg());
                    }
                }
                cldLogsVos.add(cldLogsVo);
            });
            page.setRecords(cldLogsVos);
        }
        page.setTotal(csTerminalReplyPage.getTotal());
        page.setPages(csTerminalReplyPage.getPages());
        return page;
    }

    @Override
    public void updateBzData(IcdBzReplyParam param) {
        LambdaUpdateWrapper<CsTerminalReply> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(CsTerminalReply::getIsReceived,param.getState())
                .set(CsTerminalReply::getReceivedCode,param.getCode())
                .set(CsTerminalReply::getReceivedMsg,param.getMsg())
                .eq(CsTerminalReply::getReplyId,param.getId())
                .eq(CsTerminalReply::getDeviceId,param.getDeviceId());
        if (Objects.nonNull(param.getLineId()) && StringUtils.isNotBlank(param.getLineId())) {
            wrapper.eq(CsTerminalReply::getLineId,param.getLineId());
        }
        this.update(wrapper);
    }

    public String getLogDescription(String code) {
        String result;
        switch (code) {
            case "allFile":
                result = "补召缺失波形文件";
                break;
            case "allEvent":
                result = "补召事件";
                break;
            case "oneFile":
                result = "补召单事件波形";
                break;
            case "harmonic":
                result = "稳态数据";
                break;
            default:
                result = "未知";
        }
        return result;
    }
}
