package com.njcn.device.device.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.device.biz.enums.DeviceResponseEnum;
import com.njcn.device.device.mapper.PqDevTypeMapper;
import com.njcn.device.device.service.IDeviceService;
import com.njcn.device.device.service.PqDevTypeService;
import com.njcn.device.line.mapper.LineMapper;
import com.njcn.device.pq.constant.Param;
import com.njcn.device.pq.pojo.param.PqDevTypeParam;
import com.njcn.device.pq.pojo.po.Device;
import com.njcn.device.pq.pojo.po.Line;
import com.njcn.device.pq.pojo.po.PqDevType;
import com.njcn.device.pq.pojo.po.PqsTerminalLogs;
import com.njcn.device.terminal.mapper.PqsTerminalLogsMapper;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.user.api.UserFeignClient;
import com.njcn.user.pojo.po.User;
import com.njcn.web.pojo.param.BaseParam;
import com.njcn.web.utils.RequestUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.njcn.device.pq.enums.LineBaseEnum.SUB_LEVEL;


/**
 * Description:
 * Date: 2024/11/5  11:24【需求编号】
 *
 * @author clam
 * @version V1.0.0
 */
@Service
@RequiredArgsConstructor
public class PqDevTypeServiceImpl extends ServiceImpl<PqDevTypeMapper, PqDevType> implements PqDevTypeService {

    private final UserFeignClient userFeignClient;
    private final IDeviceService deviceService;
    private final PqsTerminalLogsMapper pqsTerminalLogsMapper;
    private final DicDataFeignClient dicDataFeignClient;
    private  final LineMapper lineMapper;

    @Override
    public Page<PqDevType> pageDevTypeList(BaseParam param) {
        Page<PqDevType> page = this.page(new Page<>(param.getPageNum(), param.getPageSize())
                , new LambdaQueryWrapper<PqDevType>()
                        .like(StrUtil.isNotBlank(param.getSearchValue()), PqDevType::getName, param.getSearchValue())
                        .eq(PqDevType::getState, DataStateEnum.ENABLE.getCode())
                        .orderByDesc(PqDevType::getCreateTime)
        );
        List<PqDevType> records = page.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            List<String> userIds = new ArrayList<>();
            userIds.addAll(records.stream().map(PqDevType::getCreateBy).filter(x -> StrUtil.isNotBlank(x)).distinct().collect(Collectors.toList()));
            userIds.addAll(records.stream().map(PqDevType::getUpdateBy).filter(x -> StrUtil.isNotBlank(x)).distinct().collect(Collectors.toList()));
            List<String> collect = userIds.stream().distinct().collect(Collectors.toList());
            if (CollUtil.isNotEmpty(collect)) {
                List<User> users = userFeignClient.getUserByIdList(collect).getData();
                Map<String, String> userMap = users.stream().collect(Collectors.toMap(User::getId, User::getName));
                for (PqDevType record : records) {
                    if (userMap.containsKey(record.getCreateBy())) {
                        record.setCreateBy(userMap.get(record.getCreateBy()));
                    }
                    if (userMap.containsKey(record.getUpdateBy())) {
                        record.setUpdateBy(userMap.get(record.getUpdateBy()));
                    }
                }
            }
        }
        return page;
    }

    @Override
    public Boolean addDevType(PqDevTypeParam param) {
        Integer count = this.lambdaQuery()
                .eq(PqDevType::getState, DataStateEnum.ENABLE.getCode())
                .eq(PqDevType::getName, param.getName()).count();
        if (count > 0) {
            throw new BusinessException(DeviceResponseEnum.MODEL_NAME_REPEAT);
        }
        PqDevType devType = new PqDevType();
        devType.setName(param.getName());
        devType.setIcdId(param.getIcdId());
        devType.setState(DataStateEnum.ENABLE.getCode());
        return this.save(devType);
    }

    @Override
    public Boolean updateDevType(PqDevTypeParam.PqDevTypeUpdateParam param) {
        int count = this.count(new LambdaQueryWrapper<PqDevType>()
                .ne(PqDevType::getId, param.getId())
                .eq(PqDevType::getState, DataStateEnum.ENABLE.getCode())
                .and(wrapper ->
                        wrapper.eq(PqDevType::getName, param.getName())
                )
        );
        if (count > 0) {
            throw new BusinessException(DeviceResponseEnum.MODEL_NAME_REPEAT);
        }
        PqDevType pqDevType = BeanUtil.copyProperties(param, PqDevType.class);
        //修改icd文件记录日志重启前置
        PqDevType byId = this.getById(param.getId());
        if(!Objects.equals(byId.getIcdId(),param.getId())){
            List<Device> list = deviceService.lambdaQuery().eq(Device::getDevType, param.getId()).eq(Device::getRunFlag, 0).list();
            list.forEach(temp->{
                //记录日志
                DictData dataDic = dicDataFeignClient.getDicDataByCodeAndType(DicDataEnum.DEV_PARAMETER.getCode(), DicDataTypeEnum.DEV_OPS.getCode()).getData();
                String name = RequestUtil.getUserNickname();
                PqsTerminalLogs pqsTerminalLogs = new PqsTerminalLogs();
                pqsTerminalLogs.setLogsType(dataDic.getId());
                //终端为4
                pqsTerminalLogs.setTerminalType(4);

                List<Line> subList = lineMapper.selectList(null);
                Map<String,Line> subMap = subList.stream().collect(Collectors.toMap(Line::getId, Function.identity()));
                Line dev = subMap.get(temp.getId());

                String subName = subMap.get(dev.getPids().split(StrUtil.COMMA)[SUB_LEVEL.getCode()]).getName();
                String temLos = "%s进行更新终端进程操作;终端名称 ：%s,修改了icd文件";
                String tem = String.format(temLos,name,subName+"_"+dev.getName());
                pqsTerminalLogs.setTerminalDescribe(tem);
                pqsTerminalLogs.setState(DataStateEnum.ENABLE.getCode());
                pqsTerminalLogs.setIsPush(0);
                pqsTerminalLogs.setOperateType(Param.UPDATE);
                pqsTerminalLogs.setObjIndex(temp.getId());
                pqsTerminalLogsMapper.insert(pqsTerminalLogs);
            });

        }
        return this.updateById(pqDevType);
    }

    @Override
    public Boolean delIDevType(List<String> ids) {
        if (CollUtil.isNotEmpty(ids)) {
            int count = deviceService.count(new LambdaQueryWrapper<Device>()
                    .in(Device::getDevType, ids));
            if (count > 0) {
                throw new BusinessException("装置类型已绑定装置无法删除！");
            }
            return this.update(new LambdaUpdateWrapper<PqDevType>()
                    .set(PqDevType::getState, DataStateEnum.DELETED.getCode())
                    .in(PqDevType::getId, ids)
            );
        }
        return false;
    }

    @Override
    public void batchTerminal(MultipartFile file, HttpServletResponse response) {
        List<PqDevTypeParam.A> list = EasyExcel.read(new File("C:\\Users\\web2023\\Desktop\\sys_dict_data.xlsx"))
                .head(PqDevTypeParam.A.class)
                .sheet(0).doReadSync();
        List<PqDevType> info = new ArrayList<>();
        for (PqDevTypeParam.A a : list) {
            PqDevType pqDevType = new PqDevType();
            pqDevType.setId(a.getId());
            pqDevType.setName(a.getName());
            pqDevType.setState(DataStateEnum.ENABLE.getCode());
            info.add(pqDevType);
        }
        this.saveBatch(info);
    }
}
