package com.ktg.iscs.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ktg.common.utils.SecurityUtils;
import com.ktg.common.utils.StringUtils;
import com.ktg.iscs.domain.IsMaterials;
import com.ktg.iscs.domain.IsMaterialsCheckPlan;
import com.ktg.iscs.domain.IsMaterialsCheckRecord;
import com.ktg.iscs.domain.IsMaterialsPlanCabinet;
import com.ktg.iscs.domain.dto.checkRecord.CheckRecordPageDTO;
import com.ktg.iscs.domain.dto.checkRecord.CheckRecordParamDTO;
import com.ktg.iscs.domain.vo.checkRecord.IsMaterialsCheckRecordVO;
import com.ktg.iscs.mapper.IsMaterialsCheckRecordMapper;
import com.ktg.iscs.service.IIsMaterialsCheckPlanService;
import com.ktg.iscs.service.IIsMaterialsCheckRecordService;
import com.ktg.iscs.service.IIsMaterialsPlanCabinetService;
import com.ktg.iscs.service.IIsMaterialsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 物资检查记录Service业务层处理
 *
 * @author cgj
 * @date 2025-01-14
 */
@Service
public class IsMaterialsCheckRecordServiceImpl extends ServiceImpl<IsMaterialsCheckRecordMapper, IsMaterialsCheckRecord> implements IIsMaterialsCheckRecordService {

    @Autowired
    private IsMaterialsCheckRecordMapper isMaterialsCheckRecordMapper;
    @Autowired
    private IIsMaterialsService iIsMaterialsService;
    @Autowired
    private IIsMaterialsCheckPlanService iIsMaterialsCheckPlanService;
    @Autowired
    private IIsMaterialsPlanCabinetService iIsMaterialsPlanCabinetService;

    @Override
    public Page<IsMaterialsCheckRecordVO> getIsMaterialsCheckRecordPage(Page<IsMaterialsCheckRecord> page, CheckRecordPageDTO dto) {
        Page<IsMaterialsCheckRecordVO> result = isMaterialsCheckRecordMapper.getIsMaterialsCheckRecordPage(page, dto);
        return result;
    }

    @Transactional
    @Override
    public Boolean insertIsMaterialsCheckRecord(CheckRecordParamDTO dto) {
        if (!dto.getList().isEmpty()) {
            Long userId = SecurityUtils.getUserId();
            // 0.检查是否已经提交，如果已经提交则不允许再次提交
            List<Long> cabinetIds = dto.getList().stream().map(IsMaterialsCheckRecord::getCabinetId).collect(Collectors.toList());
            List<IsMaterialsCheckRecord> oldRecords = list(Wrappers.<IsMaterialsCheckRecord>lambdaQuery()
                    .eq(IsMaterialsCheckRecord::getPlanId, dto.getList().get(0).getPlanId())
                    .isNotNull(IsMaterialsCheckRecord::getStatus)
                    .in(IsMaterialsCheckRecord::getCabinetId, cabinetIds));
            Assert.isTrue(oldRecords.isEmpty(), "存在重复提的提交检查记录，请检查！");
            // 因为硬件逻辑更改，生成了初始化数据，可能会干扰，所以先清除，排除干扰
            remove(Wrappers.<IsMaterialsCheckRecord>lambdaQuery().eq(IsMaterialsCheckRecord::getPlanId, dto.getList().get(0).getPlanId()));
            for (IsMaterialsCheckRecord isMaterialsCheckRecord : dto.getList()) {
                Assert.notNull(isMaterialsCheckRecord.getPlanId(), "计划id不能为空!");
                Assert.notNull(isMaterialsCheckRecord.getMaterialsId(), "物资id不能为空!");
                isMaterialsCheckRecord.setCheckDate(new Date());
                isMaterialsCheckRecord.setCheckUserId(userId);
                save(isMaterialsCheckRecord);
                // 2.开始更新物资本身状态
                if ("1".equals(isMaterialsCheckRecord.getStatus()) && StringUtils.isNotBlank(isMaterialsCheckRecord.getReason())) {
                    //  reason字典值exceptions_status 对应调整material_info_status  损坏和过期时对应的，所以直接set
                    iIsMaterialsService.update(Wrappers.<IsMaterials>lambdaUpdate()
                            .eq(IsMaterials::getMaterialsId, isMaterialsCheckRecord.getMaterialsId())
                            .set(IsMaterials::getStatus, isMaterialsCheckRecord.getReason()));
                }
            }
            // 2.1更新IsMaterialsPlanCabinet数据
            iIsMaterialsPlanCabinetService.update(Wrappers.<IsMaterialsPlanCabinet>lambdaUpdate()
                    .eq(IsMaterialsPlanCabinet::getPlanId, dto.getList().get(0).getPlanId())
                    .in(IsMaterialsPlanCabinet::getCabinetId, cabinetIds)
                    .set(IsMaterialsPlanCabinet::getSignatureImg, dto.getSignatureImg())
                    .set(IsMaterialsPlanCabinet::getSignatureTime, new Date()));
            // 3.如果该计划中的所有物资柜都有提交，则自动更新完成该检查计划
            List<IsMaterialsPlanCabinet> list = iIsMaterialsPlanCabinetService.list(Wrappers.<IsMaterialsPlanCabinet>lambdaQuery()
                    .eq(IsMaterialsPlanCabinet::getPlanId, dto.getList().get(0).getPlanId())
                    .isNull(IsMaterialsPlanCabinet::getSignatureTime));
            iIsMaterialsCheckPlanService.update(Wrappers.<IsMaterialsCheckPlan>lambdaUpdate()
                    .eq(IsMaterialsCheckPlan::getPlanId, dto.getList().get(0).getPlanId())
                    .set(IsMaterialsCheckPlan::getStatus, list.isEmpty() ? "1" : "2"));
        }
        return true;
    }

    @Override
    public List<IsMaterialsCheckRecord> getCheckMaterialsByCabinetCode(Long planId, Long cabinetId) {
        return isMaterialsCheckRecordMapper.getCheckMaterialsByCabinetCode(planId, cabinetId);
    }

}
