package com.yeejoin.amos.boot.module.jyjc.biz.result.processor;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
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.google.common.collect.Sets;
import com.yeejoin.amos.boot.biz.common.utils.SnowflakeIdUtil;
import com.yeejoin.amos.boot.module.common.api.enums.EquipmentClassifityEnum;
import com.yeejoin.amos.boot.module.jyjc.api.common.BizCommonConstant;
import com.yeejoin.amos.boot.module.jyjc.api.entity.JyjcInspectionResult;
import com.yeejoin.amos.boot.module.jyjc.api.entity.JyjcInspectionResultAttachment;
import com.yeejoin.amos.boot.module.jyjc.biz.event.publisher.BizEmqPublisher;
import com.yeejoin.amos.boot.module.jyjc.biz.result.factory.support.SupportableResultDataProcessor;
import com.yeejoin.amos.boot.module.jyjc.biz.service.impl.CommonServiceImpl;
import com.yeejoin.amos.boot.module.jyjc.biz.service.impl.JyjcInspectionResultAttachmentServiceImpl;
import com.yeejoin.amos.boot.module.jyjc.biz.service.impl.JyjcInspectionResultServiceImpl;
import com.yeejoin.amos.boot.module.ymt.api.entity.IdxBizJgInspectionCylinderAttachment;
import com.yeejoin.amos.boot.module.ymt.api.entity.IdxBizJgInspectionDetectionInfo;
import com.yeejoin.amos.boot.module.ymt.api.entity.TzsUserInfo;
import com.yeejoin.amos.boot.module.ymt.api.mapper.IdxBizJgInspectionCylinderAttachmentMapper;
import com.yeejoin.amos.boot.module.ymt.api.mapper.IdxBizJgInspectionDetectionInfoMapper;
import com.yeejoin.amos.boot.module.ymt.api.mapper.UseInfoMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
@Slf4j
public class SingleEquipResultDataProcessor implements SupportableResultDataProcessor {

    private final CommonServiceImpl commonService;

    private final SnowflakeIdUtil sequence;

    private final IdxBizJgInspectionDetectionInfoMapper inspectionDetectionInfoMapper;

    private final BizEmqPublisher bizEmqPublisher;

    private final UseInfoMapper useInfoMapper;

    private final JyjcInspectionResultServiceImpl inspectionResultService;

    private final JyjcInspectionResultAttachmentServiceImpl attachmentService;

    private final IdxBizJgInspectionCylinderAttachmentMapper inspectionCylinderAttachmentMapper;

    private static final Set<String> SUPPORTED_TYPES = Sets.newHashSet(
            EquipmentClassifityEnum.GL.getCode(),
            EquipmentClassifityEnum.YLRQ.getCode(),
            EquipmentClassifityEnum.DT.getCode(),
            EquipmentClassifityEnum.QZJX.getCode(),
            EquipmentClassifityEnum.CC.getCode(),
            EquipmentClassifityEnum.YLSS.getCode(),
            EquipmentClassifityEnum.KYSD.getCode()
    );

    @Override
    public boolean support(String equList) {
        return SUPPORTED_TYPES.contains(equList);
    }

    @Override
    public void process(JyjcInspectionResult jyjcInspectionResult) {
        IdxBizJgInspectionDetectionInfo info = new IdxBizJgInspectionDetectionInfo();
        QueryWrapper<IdxBizJgInspectionDetectionInfo> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(IdxBizJgInspectionDetectionInfo::getResultSeq, jyjcInspectionResult.getSequenceNbr());
        List<IdxBizJgInspectionDetectionInfo> list = inspectionDetectionInfoMapper.selectList(wrapper);
        String record;
        //1.检验信息插入或者高新
        if (CollectionUtils.isEmpty(list)) {
            fillInspectionFields(jyjcInspectionResult, info);
            info.setSequenceNbr(sequence.nextId() + "");
            inspectionDetectionInfoMapper.insert(info);
            record = info.getRecord();
            bizEmqPublisher.sendInspectionMsgAfterSave(info, "insert");
        } else {
            info = list.get(0);
            fillInspectionFields(jyjcInspectionResult, info);
            inspectionDetectionInfoMapper.updateById(info);
            record = info.getRecord();
            bizEmqPublisher.sendInspectionMsgAfterSave(info, "update");
        }
        // 2.设备技术参数更新
        inspectionResultService.updateTechParam(jyjcInspectionResult.getSequenceNbr(), record);
        // 3.更新使用信息表最新的检验信息
        useInfoMapper.updateByRecord(jyjcInspectionResult.getEquipUnicode(), jyjcInspectionResult.getNextInspectionDate(), jyjcInspectionResult.getInspectionType(), jyjcInspectionResult.getApplicationNo());
        // 4.es更新下次检验日期
        commonService.updateEquipNextInspectDate(jyjcInspectionResult, jyjcInspectionResult.getEquipUnicode());
        // 5.气瓶时记录气瓶附件表
        this.saveOrUpdateCylinderAttachment(jyjcInspectionResult, info);
        // 发送数据刷新消息
        inspectionResultService.sendDataRefreshMsg(Collections.singleton(record));
    }

    private void saveOrUpdateCylinderAttachment(JyjcInspectionResult jyjcInspectionResult, IdxBizJgInspectionDetectionInfo info) {
        // 气瓶时记录气瓶附件信息
        if (BizCommonConstant.EQU_CATEGORY_CYLINDER.equals(jyjcInspectionResult.getEquCategory())) {
            List<IdxBizJgInspectionCylinderAttachment> attachments = inspectionCylinderAttachmentMapper.selectList(new LambdaQueryWrapper<IdxBizJgInspectionCylinderAttachment>()
                    .eq(IdxBizJgInspectionCylinderAttachment::getResultSeq, jyjcInspectionResult.getSequenceNbr()));
            LambdaQueryWrapper<JyjcInspectionResultAttachment> fileWrapper = new LambdaQueryWrapper<>();
            fileWrapper.eq(JyjcInspectionResultAttachment::getResultSeq, jyjcInspectionResult.getSequenceNbr());
            List<JyjcInspectionResultAttachment> fileList = attachmentService.list(fileWrapper);
            JSONObject attKv = new JSONObject();
            fileList.forEach(item -> attKv.put(this.buildAttKey(item), item.getAttachmentUrl()));
            IdxBizJgInspectionCylinderAttachment attachment = new IdxBizJgInspectionCylinderAttachment();
            BeanUtil.copyProperties(attKv, attachment, true);
            if (attachments.isEmpty()) {
                attachment.setInspectSeq(info.getSequenceNbr());
                attachment.setRecDate(new Date());
                attachment.setRecord(info.getRecord());
                attachment.setResultSeq(info.getResultSeq());
                inspectionCylinderAttachmentMapper.insert(attachment);
            } else {
                LambdaUpdateWrapper<IdxBizJgInspectionCylinderAttachment> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(IdxBizJgInspectionCylinderAttachment::getResultSeq, jyjcInspectionResult.getSequenceNbr());
                updateWrapper.set(IdxBizJgInspectionCylinderAttachment::getFacePic, attachment.getFacePic());
                updateWrapper.set(IdxBizJgInspectionCylinderAttachment::getRecord, info.getRecord());
                updateWrapper.set(IdxBizJgInspectionCylinderAttachment::getJtPic, attachment.getJtPic());
                updateWrapper.set(IdxBizJgInspectionCylinderAttachment::getNyCurve, attachment.getNyCurve());
                updateWrapper.set(IdxBizJgInspectionCylinderAttachment::getQmxPic, attachment.getQmxPic());
                updateWrapper.set(IdxBizJgInspectionCylinderAttachment::getRecordForm, attachment.getRecordForm());
                updateWrapper.set(IdxBizJgInspectionCylinderAttachment::getWgCheckPic, attachment.getWgCheckPic());
                updateWrapper.set(IdxBizJgInspectionCylinderAttachment::getWsPic, attachment.getWsPic());
                updateWrapper.set(IdxBizJgInspectionCylinderAttachment::getWgPic, attachment.getWgPic());
                updateWrapper.set(IdxBizJgInspectionCylinderAttachment::getNyPic, attachment.getNyPic());
                updateWrapper.set(IdxBizJgInspectionCylinderAttachment::getQmxCurve, attachment.getQmxCurve());
                updateWrapper.set(IdxBizJgInspectionCylinderAttachment::getInspectSeq, info.getSequenceNbr());
                updateWrapper.set(IdxBizJgInspectionCylinderAttachment::getRecDate, new Date());
                inspectionCylinderAttachmentMapper.update(null, updateWrapper);
            }
        }
    }

    private String buildAttKey(JyjcInspectionResultAttachment item) {
        return item.getAttachmentType().replace("JYJC_", "");
    }

    private void fillInspectionFields(JyjcInspectionResult jyjcInspectionResult, IdxBizJgInspectionDetectionInfo info) {
        info.setInspectOrgName(jyjcInspectionResult.getInspectionUnitName());
        info.setInspectType(jyjcInspectionResult.getInspectionType());
        info.setRecord(jyjcInspectionResult.getEquipUnicode());
        info.setInspectReport(this.getReport(jyjcInspectionResult));
        info.setInspectDate(jyjcInspectionResult.getInspectionDate());
        info.setInspectStaff(getInspectUserName(jyjcInspectionResult));
        info.setInspectStaffCode(jyjcInspectionResult.getInspector());
        info.setInspectConclusion(jyjcInspectionResult.getInspectionConclusion());
        info.setProblemRemark(jyjcInspectionResult.getNonConformance());
        info.setNextInspectDate(jyjcInspectionResult.getNextInspectionDate());
        info.setSequenceCode(jyjcInspectionResult.getEquipUnicode());
        info.setResultSeq(jyjcInspectionResult.getSequenceNbr() + "");
        info.setInspectOrgCode(jyjcInspectionResult.getInspectionUnitCode());
        info.setInspectReportNo(jyjcInspectionResult.getResultNo());
        info.setRecDate(new Date());
    }

    private String getReport(JyjcInspectionResult jyjcInspectionResult) {
        JyjcInspectionResultAttachment jybgFile = inspectionResultService.getReportAttachment(jyjcInspectionResult.getSequenceNbr());
        return jybgFile.getAttachmentUrl();
    }

    private String getInspectUserName(JyjcInspectionResult model) {
        List<TzsUserInfo> userInfos = commonService.getUserInfosByUnitCode(model.getInspectionUnitCode());
        return userInfos.stream().filter(u -> model.getInspector().contains(u.getSequenceNbr() + "")).map(TzsUserInfo::getName).collect(Collectors.joining(","));
    }
}
