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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
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.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
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.pms.enums.PmsDeviceResponseEnum;
import com.njcn.device.pq.constant.Param;
import com.njcn.device.pq.pojo.dto.PqIcdPathDTO;
import com.njcn.device.pq.pojo.param.PqIcdPathParam;
import com.njcn.device.pq.pojo.po.*;
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 java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.device.pq.mapper.PqIcdPathMapper;
import com.njcn.device.pq.service.PqIcdPathService;
import org.springframework.transaction.annotation.Transactional;

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 PqIcdPathServiceImpl extends ServiceImpl<PqIcdPathMapper, PqIcdPath> implements PqIcdPathService {

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

    @Override
    public List<PqIcdPathDTO> icdPathList(List<String> devType) {
        List<PqDevType> list = devTypeService.list(
                new LambdaQueryWrapper<PqDevType>()
                        .in(CollUtil.isNotEmpty(devType), PqDevType::getName, devType)
                        .eq(PqDevType::getState, DataStateEnum.ENABLE.getCode())
        );
        List<PqIcdPathDTO> info = new ArrayList<>();
        if (CollUtil.isNotEmpty(list)) {
            List<String> icdIDS = list.stream().map(PqDevType::getIcdId).distinct().collect(Collectors.toList());
            List<PqIcdPath> pqIcdPaths = this.listByIds(icdIDS);
            Map<String, PqIcdPath> pqIcdPathMap = pqIcdPaths.stream().collect(Collectors.toMap(PqIcdPath::getId, Function.identity()));
            for (PqDevType pqDevType : list) {
                if (pqIcdPathMap.containsKey(pqDevType.getIcdId())) {
                    PqIcdPath pqIcdPath = pqIcdPathMap.get(pqDevType.getIcdId());
                    PqIcdPathDTO pqIcdPathDTO = new PqIcdPathDTO();
                    pqIcdPathDTO.setId(pqDevType.getId());
                    pqIcdPathDTO.setDevType(pqDevType.getName());
                    pqIcdPathDTO.setFileName(pqIcdPath.getName());
                    pqIcdPathDTO.setFilePath(pqIcdPath.getPath());
                    pqIcdPathDTO.setUpdateTime(LocalDateTimeUtil.format(pqDevType.getUpdateTime(), DatePattern.NORM_DATETIME_PATTERN));
                    info.add(pqIcdPathDTO);
                }
            }
        }
        return info;
    }

    @Override
    public Page<PqIcdPath> pageIcdList(BaseParam param) {
        Page<PqIcdPath> page = this.page(new Page<>(param.getPageNum(), param.getPageSize())
                , new LambdaQueryWrapper<PqIcdPath>()
                        .like(StrUtil.isNotBlank(param.getSearchValue()), PqIcdPath::getName, param.getSearchValue())
                        .eq(PqIcdPath::getState, DataStateEnum.ENABLE.getCode())
                        .orderByDesc(PqIcdPath::getCreateTime)
        );
        List<PqIcdPath> records = page.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            List<String> userIds = new ArrayList<>();
            userIds.addAll(records.stream().map(PqIcdPath::getCreateBy).filter(x -> StrUtil.isNotBlank(x)).distinct().collect(Collectors.toList()));
            userIds.addAll(records.stream().map(PqIcdPath::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 (PqIcdPath 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
    @Transactional(rollbackFor = Exception.class)
    public Boolean addIcdPath(PqIcdPathParam pqIcdPathParam) {
        Integer count = this.lambdaQuery()
                .eq(PqIcdPath::getState, DataStateEnum.ENABLE.getCode())
                .eq(PqIcdPath::getName, pqIcdPathParam.getFileName()).count();
        if (count > 0) {
            throw new BusinessException(PmsDeviceResponseEnum.MODEL_NAME_REPEAT);
        }
        PqIcdPath pqIcdPath = new PqIcdPath();
        pqIcdPath.setName(pqIcdPathParam.getFileName());
        pqIcdPath.setPath(pqIcdPathParam.getFilePath());
        pqIcdPath.setState(DataStateEnum.ENABLE.getCode());
        return this.save(pqIcdPath);
    }

    @Override
    public Boolean updateIcdPath(PqIcdPathParam.PqIcdPathUpdateParam param) {
        int count = this.count(new LambdaQueryWrapper<PqIcdPath>()
                .ne(PqIcdPath::getId, param.getId())
                .eq(PqIcdPath::getState, DataStateEnum.ENABLE.getCode())
                .and(wrapper ->
                        wrapper.eq(PqIcdPath::getName, param.getFileName())
                )
        );
        if (count > 0) {
            throw new BusinessException(PmsDeviceResponseEnum.MODEL_NAME_REPEAT);
        }
        PqIcdPath icdPath = BeanUtil.copyProperties(param, PqIcdPath.class);
        icdPath.setName(param.getFileName());
        icdPath.setPath(param.getFilePath());
        //查询绑定的icd的设备型号
        List<PqDevType> pqDevTypeList = devTypeService.lambdaQuery().eq(PqDevType::getIcdId, param.getId()).eq(PqDevType::getState, 1).list();
        if (!CollectionUtil.isEmpty(pqDevTypeList)) {
            List<String> collect = pqDevTypeList.stream().map(PqDevType::getId).collect(Collectors.toList());
            List<Device> list = deviceService.lambdaQuery().in(Device::getDevType, collect).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(icdPath);
    }

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

    }
}
