package com.zt.plat.module.qms.resource.device.service;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.qms.enums.QmsCommonConstant;
import com.zt.plat.module.qms.resource.device.common.DeviceConstant;
import com.zt.plat.module.qms.resource.device.controller.vo.DevicePeriodCheckPageReqVO;
import com.zt.plat.module.qms.resource.device.controller.vo.DevicePeriodCheckRespVO;
import com.zt.plat.module.qms.resource.device.controller.vo.DevicePeriodCheckSaveReqVO;
import com.zt.plat.module.qms.resource.device.dal.dataobject.DeviceConfigBusinessRuleDO;
import com.zt.plat.module.qms.resource.device.dal.dataobject.DeviceInfoWithBizConfigVO;
import com.zt.plat.module.qms.resource.device.dal.dataobject.DevicePeriodCheckPlanDO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialInfoWithBizConfigVO;
import com.zt.plat.module.qms.resource.material.service.MaterialInfomationService;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.*;

import com.zt.plat.module.qms.resource.device.dal.dataobject.DevicePeriodCheckDO;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;

import com.zt.plat.module.qms.resource.device.dal.mapper.DevicePeriodCheckMapper;

import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.framework.common.util.collection.CollectionUtils.convertList;
import static com.zt.plat.module.qms.enums.ErrorCodeConstants.DEVICE_PERIOD_CHECK_NOT_EXISTS;

/**
 * 设备-期间核查 Service 实现类
 *
 * @author 后台管理-1
 */
@Service
@Validated
public class DevicePeriodCheckServiceImpl implements DevicePeriodCheckService {

    @Resource private DevicePeriodCheckMapper devicePeriodCheckMapper;
    @Resource private DeviceInfomationService deviceInfomationService;
    @Resource private MaterialInfomationService materialInfomationService;

    /*
     * 创建本年度的期间核查列表
     * 1、取所有需要期间核查的设备、物料
     * 2、计算下次日期
     * 3、标识不能计算下次日期的数据
     * 4、保存数据
     * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createListByPlan(DevicePeriodCheckPlanDO plan) {
        Long planId = plan.getId();
        String checkYear = plan.getCheckYear();
        JSONObject ruleParam = new JSONObject();
        ruleParam.put("businessType", DeviceConstant.PERIOD_TYPE);
        List<DevicePeriodCheckDO> checkList = new ArrayList<>();
        String wfStatus = QmsCommonConstant.COMPLETED;
        //处理设备
        List<DeviceInfoWithBizConfigVO> deviceList = deviceInfomationService.getListNeedByRule(ruleParam);
        List<Long> deviceIds = convertList(deviceList, DeviceInfoWithBizConfigVO::getId);
        List<DevicePeriodCheckDO> lastDeviceDataList = getLastDataCheckList(deviceIds, wfStatus).getData();
        for (DeviceInfoWithBizConfigVO device : deviceList) {
            DeviceConfigBusinessRuleDO rule = device.getRule();
            Long deviceId = device.getId();
            initPeriodCheckData(planId, checkList, lastDeviceDataList, rule, deviceId);
        }

        //处理物料试剂
        List<MaterialInfoWithBizConfigVO> materialList = materialInfomationService.getListNeedByRule(ruleParam);
        List<Long> materialIds = convertList(materialList, MaterialInfoWithBizConfigVO::getId);
        List<DevicePeriodCheckDO> lastMaterialDataList = getLastDataCheckList(materialIds, wfStatus).getData();
        for (MaterialInfoWithBizConfigVO material : materialList) {
            DeviceConfigBusinessRuleDO rule = material.getRule();
            Long deviceId = material.getId();
            initPeriodCheckData(planId, checkList, lastMaterialDataList, rule, deviceId);
        }
        devicePeriodCheckMapper.insertBatch(checkList);
    }

    private void initPeriodCheckData(Long planId, List<DevicePeriodCheckDO> checkList, List<DevicePeriodCheckDO> lastCheckList, DeviceConfigBusinessRuleDO rule, Long deviceId) {
        DevicePeriodCheckDO data = new DevicePeriodCheckDO();
        DevicePeriodCheckDO lastCheck = lastCheckList.stream().filter(item -> item.getDeviceId().equals(deviceId)).findFirst().orElse(null);
        if(lastCheck != null)
            data.setLastCheckDate(lastCheck.getCheckDate());
        //todo 计算计划执行日期
        //todo 过滤当前年度已执行过期间核查的数据
        data.setPlanId(planId);
        data.setDeviceId(deviceId);
        data.setCheckPersonRemark(rule.getTreatmentUser());
        data.setCheckAccording(rule.getTreatmentMethod());
        data.setFrequencyRemark(rule.getFrequencyRemark());
        checkList.add(data);
    }

    @Override
    public CommonResult<List<DevicePeriodCheckDO>> getLastDataCheckList(List<Long> deviceIds, String flowStatus) {
        JSONObject param = new JSONObject();
        param.put("deviceIds", deviceIds);
        param.put("flowStatus", flowStatus);
        List<DevicePeriodCheckDO> list = devicePeriodCheckMapper.getLastDataCheckList(param);
        return CommonResult.success(list);
    }

    @Override
    public DevicePeriodCheckRespVO createDevicePeriodCheck(DevicePeriodCheckSaveReqVO createReqVO) {
        // 插入
        DevicePeriodCheckDO devicePeriodCheck = BeanUtils.toBean(createReqVO, DevicePeriodCheckDO.class);
        devicePeriodCheckMapper.insert(devicePeriodCheck);
        // 返回
        return BeanUtils.toBean(devicePeriodCheck, DevicePeriodCheckRespVO.class);
    }

    @Override
    public void updateDevicePeriodCheck(DevicePeriodCheckSaveReqVO updateReqVO) {
        // 校验存在
        validateDevicePeriodCheckExists(updateReqVO.getId());
        // 更新
        DevicePeriodCheckDO updateObj = BeanUtils.toBean(updateReqVO, DevicePeriodCheckDO.class);
        devicePeriodCheckMapper.updateById(updateObj);
    }

    @Override
    public void deleteDevicePeriodCheck(Long id) {
        // 校验存在
        validateDevicePeriodCheckExists(id);
        // 删除
        devicePeriodCheckMapper.deleteById(id);
    }

    @Override
        public void deleteDevicePeriodCheckListByIds(List<Long> ids) {
        // 校验存在
        validateDevicePeriodCheckExists(ids);
        // 删除
        devicePeriodCheckMapper.deleteByIds(ids);
        }

    private void validateDevicePeriodCheckExists(List<Long> ids) {
        List<DevicePeriodCheckDO> list = devicePeriodCheckMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(DEVICE_PERIOD_CHECK_NOT_EXISTS);
        }
    }

    private void validateDevicePeriodCheckExists(Long id) {
        if (devicePeriodCheckMapper.selectById(id) == null) {
            throw exception(DEVICE_PERIOD_CHECK_NOT_EXISTS);
        }
    }

    @Override
    public DevicePeriodCheckDO getDevicePeriodCheck(Long id) {
        return devicePeriodCheckMapper.selectById(id);
    }

    @Override
    public PageResult<DevicePeriodCheckDO> getDevicePeriodCheckPage(DevicePeriodCheckPageReqVO pageReqVO) {
        return devicePeriodCheckMapper.selectPage(pageReqVO);
    }

}