package com.bonus.material.devchange.service;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.bonus.common.biz.enums.ApprovalStatusEnum;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.approval.annotation.ApprovalRequired;
import com.bonus.material.approval.domain.ApprovalInstance;
import com.bonus.material.approval.domain.ApprovalRecord;
import com.bonus.material.approval.mapper.ApprovalInstanceMapper;
import com.bonus.material.approval.mapper.ApprovalRecordMapper;
import com.bonus.material.common.constants.TypeConstants;
import com.bonus.material.common.enums.TypeEnums;
import com.bonus.material.devchange.domain.*;
import com.bonus.material.devchange.mapper.DevChangeMapper;
import com.bonus.material.device.domain.vo.DevInfoPropertyVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static com.bonus.common.biz.constant.MaterialConstants.ADMIN_ID;
import static com.bonus.common.biz.constant.MaterialConstants.PROVINCE_COMPANY_DEPT_ID;

@Service
@Slf4j
public class DevChangeServiceImpl implements DevChangeService {

    @Autowired
    private DevChangeMapper mapper;

    @Resource
    private ApprovalInstanceMapper instanceMapper;

    @Resource
    private ApprovalRecordMapper recordMapper;

    /**
     * 查询设备 最大的数据
     *
     * @return
     */
    @Override
    public AjaxResult getMaxFeature() {
        try {
            Integer num = mapper.getMaxFeature();
            if (num == null || num == 0) {
                return AjaxResult.success(8);
            } else {
                return AjaxResult.success(num);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return AjaxResult.success(8);
    }

    @Override
    public List<DevChangeVo> selectDevInfoList(DevChangeVo devInfo) {
        try {

            List<DevChangeVo> list = mapper.selectDevInfoList(devInfo);
            for (DevChangeVo vo : list) {
                List<DevInfoPropertyVo> devInfoPropertyVos = mapper.getDevPropertyList(vo);
                if (devInfoPropertyVos != null && !devInfoPropertyVos.isEmpty()) {
                    String json = JSON.toJSONString(devInfoPropertyVos);
                    vo.setJsonData(json);
                    mapper.updateJson(vo);
                    vo.setPropertyVoList(devInfoPropertyVos);
                }
            }
            return list;
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return new ArrayList<>();
    }

    /**
     * 维修
     *
     * @param vo
     * @return
     */
    @Override
    public AjaxResult updateDevChangeInfo(CsDeviceChangeVo vo) {
        try {
            String username = SecurityUtils.getLoginUser().getSysUser().getNickName();
            vo.setCreateUser(username);
            String proCode = vo.getProCode();
            if (StringUtils.isBlank(proCode)) {
                return AjaxResult.error("请选择工程");
            }
            if (StringUtils.isBlank(vo.getType())) {
                return AjaxResult.error("请上传类型type:1入库 2出库 3 退役  4 维修");
            }
            String json = vo.getJsonData();
            if (StringUtils.isBlank(json)) {
                return AjaxResult.error("请选择变更的设备");
            }
            List<CsDeviceChangeDetailsVo> list = JSON.parseArray(json, CsDeviceChangeDetailsVo.class);
            if (list == null || list.isEmpty()) {
                return AjaxResult.error("请选择变更的设备");
            }

            //出库
            if ("2".equals(vo.getType())) {
                String changeUnit = mapper.getChangeUnit(list.get(0).getDevId());
                vo.setChangeUnit(changeUnit);
            } else {
                //
                String changeUnit = mapper.getChangeUnitById(list.get(0).getDevId());
                vo.setChangeUnit(changeUnit);
            }
            if ("1".equals(vo.getType())) {
                //入库厂家
                String changeUnit = mapper.getChangeUnit(list.get(0).getDevId());
                vo.setUseUint(changeUnit);
            }
            //变更前状态查询
            String changeStatus = mapper.getChangeStatus(list.get(0).getDevId());
            vo.setChangeStatus(changeStatus);
            vo.setDevNum(list.size() + "");
            int num = mapper.addChangeInfo(vo);
            if (num > 0) {
                for (CsDeviceChangeDetailsVo deviceChangeDetailsVo : list) {
                    if ("1".equals(deviceChangeDetailsVo.getChangeStatus())) {
                        updateDevDetails(deviceChangeDetailsVo.getDevId(), null, "1", deviceChangeDetailsVo.getNum());
                        deviceChangeDetailsVo.setStatus("1");
                    } else {
                        updateDevDetails(deviceChangeDetailsVo.getDevId(), null, "5", deviceChangeDetailsVo.getNum());
                        deviceChangeDetailsVo.setStatus("5");
                    }
                    //新增设备列表数据
                    deviceChangeDetailsVo.setChangeId(vo.getId());
                    //新增设备详情
                    int isSuccess = mapper.addDetailsInfo(deviceChangeDetailsVo);
                    if (isSuccess > 0) {
                        vo.setDevId(deviceChangeDetailsVo.getDevId());
                        vo.setChangeStatus(deviceChangeDetailsVo.getChangeStatus());
                        vo.setUseUint(null);
                        vo.setUserName(null);
                        vo.setUserPhone(null);
                        vo.setProCode(null);
                        mapper.updateDevInfo(vo);
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return AjaxResult.success();
    }

    /**
     * 报废接口
     *
     * @param vo
     * @return
     */
    @Override
    public AjaxResult updateDevChangeInfo3(CsDeviceChangeVo vo) {
        try {
            String username = SecurityUtils.getLoginUser().getSysUser().getNickName();
            vo.setCreateUser(username);
            if (StringUtils.isBlank(vo.getType())) {
                return AjaxResult.error("请上传类型type:1入库 2出库 3 退役  4 维修");
            }
            String json = vo.getJsonData();
            if (StringUtils.isBlank(json)) {
                return AjaxResult.error("请选择变更的设备");
            }
            List<CsDeviceChangeDetailsVo> list = JSON.parseArray(json, CsDeviceChangeDetailsVo.class);
            if (list == null || list.isEmpty()) {
                return AjaxResult.error("请选择变更的设备");
            }
            //入库厂家
            String usUnit = mapper.getChangeUnit(list.get(0).getDevId());
            vo.setUseUint(usUnit);
            vo.setChangeUnit(usUnit);
            vo.setChangeStatus("4");
            vo.setDevNum(list.size() + "");
            String proId = vo.getProCode();
            int num = mapper.addChangeInfo(vo);
            if (num > 0) {
                for (CsDeviceChangeDetailsVo deviceChangeDetailsVo : list) {
                    updateDevDetails(deviceChangeDetailsVo.getDevId(), proId, "4", deviceChangeDetailsVo.getNum());
                    //新增设备列表数据
                    deviceChangeDetailsVo.setChangeId(vo.getId());
                    deviceChangeDetailsVo.setReasonVal(vo.getReasonVal());
                    deviceChangeDetailsVo.setReasonId(vo.getReasonId());
                    deviceChangeDetailsVo.setStatus("4");
                    //新增设备详情
                    int isSuccess = mapper.addDetailsInfo(deviceChangeDetailsVo);
                    if (isSuccess > 0) {
                        vo.setDevId(deviceChangeDetailsVo.getDevId());
                        vo.setChangeStatus(vo.getStatus());
                        vo.setUseUint(null);
                        vo.setUserName(null);
                        vo.setUserPhone(null);
                        vo.setProCode(null);
                        mapper.updateDevInfo(vo);
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return AjaxResult.success();
    }

    /**
     * 获取添加设备详情
     *
     * @param dto
     * @return
     */
    @Override
    public List<CsDeviceDetails> getDevDetailsInfo(CsDeviceDetails dto) {
        try {
            Long thisLoginUserDeptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
            dto.setCompanyId(thisLoginUserDeptId);
            return mapper.getDevDetailsInfo(dto);

        } catch (Exception e) {
            log.error(e.getMessage());
            return new ArrayList<>();
        }
    }

    /**
     * 新增出库申请（自用）
     *
     * @param csDeviceVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @ApprovalRequired(
            businessType = "EQUIPMENT_OUT",
            businessIdExpr = "#result['data']",
            businessDataExpr = "#csDeviceVo"
    )
    public AjaxResult addDevDetails(CsDeviceVo csDeviceVo) {
        try {
            if (csDeviceVo == null || csDeviceVo.getDevInfo() == null || CollectionUtils.isEmpty(csDeviceVo.getDevDetailsList())) {
                return AjaxResult.error("请选择需要添加的设备", AjaxResult.class);
            }
            // 判断提交的数据csDeviceVo.getDevDetailsList()中是否存在相同编号或者数量设备typeId相同的数据
            Set<String> devCodeSet = new HashSet<>();
            Set<Long> typeIdSet = new HashSet<>();

            for (CsDeviceDetails details : csDeviceVo.getDevDetailsList()) {
                if (details == null) {
                    continue;
                }
                // 编码重复
                String devCode = details.getDevCode();
                if (!devCode.equals("/") && StringUtils.isNotBlank(devCode) && devCodeSet.contains(devCode)) {
                    return AjaxResult.error("添加的列表中设备编号存在重复：" + devCode, AjaxResult.class);
                } else if (StringUtils.isNotBlank(devCode)) {
                    devCodeSet.add(devCode);
                }
                // typeId重复
                Long typeId = details.getTypeId();
                if (typeId != null && typeIdSet.contains(typeId)) {
                    return AjaxResult.error("添加的列表中设备类型存在重复！", AjaxResult.class);
                } else if (typeId != null && "1".equals(details.getManageType())) {
                    typeIdSet.add(typeId);
                }
            }

            String nickName = SecurityUtils.getLoginUser().getSysUser().getNickName();
            // 获取申请编号
            int thisMonthMaxOrder = mapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TypeEnums.TM_TASK_LEASE.getTaskTypeId());
            String code = genderTaskCode(thisMonthMaxOrder);
            CsDeviceInfo devInfo = csDeviceVo.getDevInfo();
            devInfo.setCode(code);
            devInfo.setCreateBy(nickName);
            devInfo.setTaskStatus("0");
            devInfo.setCompanyId(SecurityUtils.getLoginUser().getSysUser().getDeptId());
            // 添加主任务
            int num = mapper.addChangeInfoNew(devInfo);
            if (num < 1) {
                throw new RuntimeException("添加主任务失败");
            }
            csDeviceVo.getDevDetailsList().forEach(devDetails -> {
                devDetails.setChangeId(devInfo.getId());
                devDetails.setCreateBy(nickName);
                devDetails.setCreateTime(DateUtils.getNowDate());
            });
            // 添加设备详情
            num = mapper.addDetails(csDeviceVo.getDevDetailsList());
            if (num < 1) {
                throw new RuntimeException("添加设备详情失败");
            }

            // 设置任务ID到devInfo中（用于审批流）
            csDeviceVo.getDevInfo().setId(devInfo.getId());

        } catch (Exception e) {
            log.error(e.getMessage());
            throw new RuntimeException("添加失败");
        }
        return AjaxResult.success("出库申请提交成功，等待审批", csDeviceVo.getDevInfo().getId());
    }

    /**
     * 修改出库申请
     *
     * @param csDeviceVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateDevDetails(CsDeviceVo csDeviceVo) {
        try {
            if (csDeviceVo == null || csDeviceVo.getDevInfo() == null || csDeviceVo.getDevInfo().getId() == null
                    || CollectionUtils.isEmpty(csDeviceVo.getDevDetailsList())) {
                return AjaxResult.error("请选择需要修改的设备");
            }

            // 判断提交的数据csDeviceVo.getDevDetailsList()中是否存在相同编号或者数量设备typeId相同的数据
            Set<String> devCodeSet = new HashSet<>();
            Set<Long> typeIdSet = new HashSet<>();

            for (CsDeviceDetails details : csDeviceVo.getDevDetailsList()) {
                if (details == null) {
                    continue;
                }
                // 编码重复
                String devCode = details.getDevCode();
                if (!devCode.equals("/") && StringUtils.isNotBlank(devCode) && devCodeSet.contains(devCode)) {
                    return AjaxResult.error("添加的列表中设备编号存在重复：" + devCode);
                } else if (StringUtils.isNotBlank(devCode)) {
                    devCodeSet.add(devCode);
                }
                // typeId重复
                Long typeId = details.getTypeId();
                if (typeId != null && typeIdSet.contains(typeId)) {
                    return AjaxResult.error("添加的列表中设备类型存在重复！");
                } else if (typeId != null && "1".equals(details.getManageType())) {
                    typeIdSet.add(typeId);
                }
            }

            String nickName = SecurityUtils.getLoginUser().getSysUser().getNickName();
            csDeviceVo.getDevInfo().setUpdateBy(nickName);
            // 修改主任务
            csDeviceVo.getDevInfo().setTaskStatus("0");
            csDeviceVo.getDevInfo().setCompanyId(SecurityUtils.getLoginUser().getSysUser().getDeptId());
            int num = mapper.updateCsDevInfo(csDeviceVo.getDevInfo());
            if (num < 1) {
                throw new RuntimeException("修改主任务失败");
            }
            // 先将设备详情删除，重新添加
            num = mapper.deleteChangeDetails(csDeviceVo.getDevInfo().getId());
            if (num < 1) {
                throw new RuntimeException("删除设备详情失败");
            }
            csDeviceVo.getDevDetailsList().forEach(devDetails -> {
                devDetails.setChangeId(csDeviceVo.getDevInfo().getId());
                devDetails.setUpdateBy(nickName);
                devDetails.setCreateBy(nickName);
                devDetails.setCreateTime(DateUtils.getNowDate());
                devDetails.setUpdateTime(DateUtils.getNowDate());
            });
            num = mapper.addDetails(csDeviceVo.getDevDetailsList());
            if (num < 1) {
                throw new RuntimeException("添加设备详情失败");
            }
            // 根据id，针对编辑进行审批流重置修改
            // 根据主id查询目前审批流是否存在驳回数据，驳回需重置审批
            ApprovalInstance approvalInstance = new ApprovalInstance();
            approvalInstance.setBusinessId(csDeviceVo.getDevInfo().getId().toString());
            List<ApprovalInstance> approvalInstances = instanceMapper.selectInstanceList(approvalInstance);
            if (CollectionUtils.isNotEmpty(approvalInstances)) {
                ApprovalInstance instance = approvalInstances.get(0);
                if ("3".equals(instance.getStatus())) {
                    // 如果当前节点为第一节点，则状态修改为待审批
                    if (instance.getCurrentNodeOrder() == 1) {
                        num = instanceMapper.updateInstanceStatus(instance.getId(), ApprovalStatusEnum.PENDING.getCode());
                    } else {
                        // 审批中
                        num = instanceMapper.updateInstanceStatus(instance.getId(), ApprovalStatusEnum.IN_PROGRESS.getCode());
                    }
                    if (num < 1) {
                        throw new RuntimeException("修改审批实例状态失败");
                    }
                    // 根据当前节点及id去记录表查询是否存在驳回记录，存在即删除
                    List<ApprovalRecord> approvalRecords = recordMapper.selectRecordListByNode(instance.getId(), instance.getCurrentNodeId());
                    if (CollectionUtils.isNotEmpty(approvalRecords)) {
                        ApprovalRecord approvalRecord = approvalRecords.get(0);
                        // 如果是驳回状态，则删除
                        if ("2".equals(approvalRecord.getApproveResult())) {
                            num = recordMapper.deleteRecordById(approvalRecord.getId());
                            if (num < 1) {
                                throw new RuntimeException("删除审批记录失败");
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new RuntimeException("修改失败");
        }
        return AjaxResult.success("修改成功");
    }

    /**
     * 获取设备详情
     *
     * @param dto
     * @return
     */
    @Override
    public CsDeviceVo getDevDetailsById(CsDeviceDetails dto) {
        CsDeviceVo csDeviceVo = new CsDeviceVo();
        // 根据id查询主任务表数据
        CsDeviceInfo devInfo = mapper.getDevInfoById(dto);
        // 根据id查询设备详情表数据
        List<CsDeviceDetails> devDetailsList = mapper.getDevDetailsById(dto);
        if (CollectionUtils.isNotEmpty(devDetailsList)) {
            // 根据devType去查询装备或工具详情
            for (CsDeviceDetails csDeviceDetails : devDetailsList) {
                CsDeviceDetails devDetails = new CsDeviceDetails();
                if (StringUtils.isNotBlank(csDeviceDetails.getDevType()) && "1".equals(csDeviceDetails.getDevType())) {
                    if ("/".equals(csDeviceDetails.getDevCode())) {
                        csDeviceDetails.setDevCode(null);
                    }
                    devDetails = mapper.getTypeMaDevInfo(csDeviceDetails);
                } else if (StringUtils.isNotBlank(csDeviceDetails.getDevType()) && "2".equals(csDeviceDetails.getDevType())) {
                    if ("/".equals(csDeviceDetails.getDevCode())) {
                        csDeviceDetails.setDevCode(null);
                    }
                    devDetails = mapper.getTypeToolInfo(csDeviceDetails);
                }
                if (devDetails != null) {
                    csDeviceDetails.setCategory(StringUtils.isNotBlank(devDetails.getCategory()) ? devDetails.getCategory() : "");
                    csDeviceDetails.setTypeName(StringUtils.isNotBlank(devDetails.getTypeName()) ? devDetails.getTypeName() : "");
                    csDeviceDetails.setTypeModelName(StringUtils.isNotBlank(devDetails.getTypeModelName()) ? devDetails.getTypeModelName() : "");
                    csDeviceDetails.setManageType(StringUtils.isNotBlank(devDetails.getManageType()) ? devDetails.getManageType() : "");
                    csDeviceDetails.setDevCode(StringUtils.isNotBlank(devDetails.getDevCode()) ? devDetails.getDevCode() : "");
                    csDeviceDetails.setStorageNum(devDetails.getStorageNum());
                    csDeviceDetails.setRemainingYears(StringUtils.isNotBlank(devDetails.getRemainingYears()) ? devDetails.getRemainingYears() : "-");
                    // 用于编辑显示数据是否选中（前端根据typeId和id结合判断）
                    csDeviceDetails.setId(devDetails.getId());
                }
            }
        }
        csDeviceVo.setDevInfo(devInfo);
        csDeviceVo.setDevDetailsList(devDetailsList);
        return csDeviceVo;
    }

    /**
     * 删除出库申请
     *
     * @param csDeviceInfo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult deleteDevDetails(CsDeviceInfo csDeviceInfo) {
        try {
            // 删除主任务
            int num = mapper.deleteChangeInfo(csDeviceInfo);
            if (num < 1) {
                throw new RuntimeException("删除主任务失败");
            }
            // 删除设备详情
            num = mapper.deleteChangeDetails(csDeviceInfo.getId());
            if (num < 1) {
                throw new RuntimeException("删除设备详情失败");
            }
        } catch (RuntimeException e) {
            log.error(e.getMessage());
            throw new RuntimeException("删除失败");
        }
        return AjaxResult.success("删除成功");
    }

    /**
     * 获取申请一级列表
     *
     * @param dto
     * @return
     */
    @Override
    public List<CsDeviceInfo> getList(CsDeviceInfo dto) {
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 管理员和省公司可查看所有数据
//        if (userId != null && deptId != null
//                && !userId.equals(ADMIN_ID)
//                && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {
//            dto.setCompanyId(deptId);
//        }
        if(ADMIN_ID.equals(userId)){
            dto.setCompanyId(1L);
        }else{
            dto.setCompanyId(deptId);
        }
        return mapper.getList(dto);
    }

    /**
     * 审核出库（自用）
     * 注意：此方法由审批回调内部调用，不应直接暴露给前端
     *
     * @param csDeviceInfo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult approve(CsDeviceInfo csDeviceInfo) {
        csDeviceInfo.setUpdateBy(SecurityUtils.getLoginUser().getUserid().toString());
        int num = mapper.approve(csDeviceInfo);
        if (num <= 0) {
            throw new RuntimeException("审核失败，更新数据库失败");
        }
        return AjaxResult.success("审核成功");
    }

    /**
     * 装备单个出库
     *
     * @param entity
     * @return
     */
    @Override
    public AjaxResult out(CsDeviceDetails entity) {
        try {
            //装备
            if (entity.getDevType().equals("1")) {
                BigDecimal toolNum = mapper.getMaNum(entity);
                if (toolNum.compareTo(entity.getOutNum()) < 0) {
                    // 库存不足，计算差额
                    BigDecimal shortage = entity.getOutNum().subtract(toolNum);
                    return AjaxResult.error(String.format(
                            "库存不足！当前可用：%s，需要出库：%s，短缺：%s",
                            toolNum.stripTrailingZeros().toPlainString(),
                            entity.getOutNum().stripTrailingZeros().toPlainString(),
                            shortage.stripTrailingZeros().toPlainString()
                    ));
                }
                mapper.updateZb(entity);
            } else {
                BigDecimal toolNum = mapper.getToolNum(entity);
                // BigDecimal 比较：库存 < 出库数量
                if (toolNum.compareTo(entity.getOutNum()) < 0) {
                    // 库存不足，计算差额
                    BigDecimal shortage = entity.getOutNum().subtract(toolNum);
                    return AjaxResult.error(String.format(
                            "库存不足！当前可用：%s，需要出库：%s，短缺：%s",
                            toolNum.stripTrailingZeros().toPlainString(),
                            entity.getOutNum().stripTrailingZeros().toPlainString(),
                            shortage.stripTrailingZeros().toPlainString()
                    ));
                }
                mapper.updateGj(entity);
            }
            Integer out = mapper.out(entity);
            return out > 0 ? AjaxResult.success("出库成功") : AjaxResult.error("出库失败");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("出库失败");
        }
    }

    /**
     * 单个取消出库
     *
     * @param entity
     * @return
     */
    @Override
    public AjaxResult outCancel(CsDeviceDetails entity) {
        try {
            Integer out = mapper.outCancel(entity);
            return out > 0 ? AjaxResult.success("出库成功") : AjaxResult.error("出库失败");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("出库失败");
        }
    }

    /**
     * @param entity
     * @return
     */
    @Override
    public AjaxResult outCancelAll(CsDeviceDetails entity) {
        try {
            Integer out = mapper.outCancelAll(entity);
            return out > 0 ? AjaxResult.success("出库成功") : AjaxResult.error("出库失败");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("出库失败");
        }
    }

    /**
     * @param entity
     * @return
     */
    @Override
    public AjaxResult outAll(CsDeviceDetails entity) {
        try {
            // 1. 首先查询需要出库的所有物品
            List<CsDeviceDetails> outAllList = mapper.getOutAllList(entity);

            // 2. 先检查所有工器具的库存是否充足
            for (CsDeviceDetails item : outAllList) {
                if (!item.getDevType().equals("1")) {
                    // 工器具需要检查库存
                    BigDecimal toolNum = mapper.getToolNum(item); // 注意：参数应该是 item
                    BigDecimal outNum = item.getOutNum();
                    if (toolNum.compareTo(outNum) < 0) {
                        BigDecimal shortage = outNum.subtract(toolNum);
                        return AjaxResult.error(String.format(
                                "库存不足！工具：%s，当前可用：%s，需要出库：%s，短缺：%s",
                                item.getTypeName(),
                                toolNum.stripTrailingZeros().toPlainString(),
                                outNum.stripTrailingZeros().toPlainString(),
                                shortage.stripTrailingZeros().toPlainString()
                        ));
                    }
                } else {
                    // 工器具需要检查库存
                    BigDecimal toolNum = mapper.getMaNum(item); // 注意：参数应该是 item
                    BigDecimal outNum = item.getOutNum();
                    if (toolNum.compareTo(outNum) < 0) {
                        BigDecimal shortage = outNum.subtract(toolNum);
                        return AjaxResult.error(String.format(
                                "库存不足！ 装备：%s，当前可用：%s，需要出库：%s，短缺：%s",
                                item.getTypeName(),
                                toolNum.stripTrailingZeros().toPlainString(),
                                outNum.stripTrailingZeros().toPlainString(),
                                shortage.stripTrailingZeros().toPlainString()
                        ));
                    }
                }
            }

            // 3. 所有库存检查通过后，执行出库
            Integer out = mapper.outAll(entity);
            if (out <= 0) {
                return AjaxResult.error("出库失败");
            }

            // 4. 更新库存
            for (CsDeviceDetails item : outAllList) {
                if (item.getDevType().equals("1")) {
                    // 装备类型
                    mapper.updateZb(item);
                } else {
                    // 工器具类型 - 此时库存肯定是充足的
                    mapper.updateGj(item);
                }
            }

            return AjaxResult.success("出库成功");

        } catch (Exception e) {
            log.error("批量出库失败", e);
            throw new RuntimeException("出库失败：" + e.getMessage());
        }
    }

    @Override
    public List<CsDeviceChange> getDevChangeRList(CsDeviceChange vo) {
        try {
            return mapper.getDevChangeRList(vo);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return new ArrayList<>();
    }

    /**
     * @param dto
     * @return
     */
    @Override
    public CsDeviceVo getOrderById(CsDeviceDetails dto) {
        CsDeviceVo csDeviceVo = new CsDeviceVo();
        // 根据id查询主任务表数据
        CsDeviceInfo devInfo = mapper.getOrderById(dto);
        // 根据id查询设备详情表数据
        List<CsDeviceDetails> devDetailsList = mapper.getOrderDetailsById(dto);
        if (CollectionUtils.isNotEmpty(devDetailsList)) {
            // 根据devType去查询装备或工具详情
            for (CsDeviceDetails csDeviceDetails : devDetailsList) {
                CsDeviceDetails devDetails = new CsDeviceDetails();
                if (StringUtils.isNotBlank(csDeviceDetails.getDevType()) && "0".equals(csDeviceDetails.getDevType())) {
                    if ("/".equals(csDeviceDetails.getDevCode())) {
                        csDeviceDetails.setDevCode(null);
                    }
                    devDetails = mapper.getOrderDetailsMaDevInfo(csDeviceDetails);
                } else if (StringUtils.isNotBlank(csDeviceDetails.getDevType()) && "1".equals(csDeviceDetails.getDevType())) {
                    if ("/".equals(csDeviceDetails.getDevCode())) {
                        csDeviceDetails.setDevCode(null);
                    }
                    devDetails = mapper.getOrderDetailsTypeToolInfo(csDeviceDetails);
                }
                if (devDetails != null) {
                    csDeviceDetails.setDevType(StringUtils.isNotBlank(devDetails.getDevType()) ? devDetails.getDevType() : "");
                    csDeviceDetails.setCategory(StringUtils.isNotBlank(devDetails.getCategory()) ? devDetails.getCategory() : "");
                    csDeviceDetails.setTypeName(StringUtils.isNotBlank(devDetails.getTypeName()) ? devDetails.getTypeName() : "");
                    csDeviceDetails.setTypeModelName(StringUtils.isNotBlank(devDetails.getTypeModelName()) ? devDetails.getTypeModelName() : "");
                    csDeviceDetails.setManageType(StringUtils.isNotBlank(devDetails.getManageType()) ? devDetails.getManageType() : "");
                    csDeviceDetails.setDevCode(StringUtils.isNotBlank(devDetails.getDevCode()) ? devDetails.getDevCode() : "");
                    csDeviceDetails.setStorageNum(devDetails.getStorageNum());
                    // 用于编辑显示数据是否选中（前端根据typeId和id结合判断）
                    csDeviceDetails.setId(devDetails.getId());
                }
            }
        }
        csDeviceVo.setDevInfo(devInfo);
        csDeviceVo.setDevDetailsList(devDetailsList);
        return csDeviceVo;
    }

    /**
     * @param entity
     * @return
     */
    @Override
    public AjaxResult orderOut(CsDeviceDetails entity) {
        try {
            //装备
            if (entity.getDevType().equals("1")) {
                mapper.updateOrderZb(entity);
            } else {
                BigDecimal toolNum = mapper.getToolNum(entity);
                // BigDecimal 比较：库存 < 出库数量
                if (toolNum.compareTo(entity.getOutNum()) < 0) {
                    // 库存不足，计算差额
                    BigDecimal shortage = entity.getOutNum().subtract(toolNum);
                    return AjaxResult.error(String.format(
                            "库存不足！当前可用：%s，需要出库：%s，短缺：%s",
                            toolNum.stripTrailingZeros().toPlainString(),
                            entity.getOutNum().stripTrailingZeros().toPlainString(),
                            shortage.stripTrailingZeros().toPlainString()
                    ));
                }
                mapper.updateOrderGj(entity);
            }
            Integer out = mapper.orderOut(entity);
            return out > 0 ? AjaxResult.success("出库成功") : AjaxResult.error("出库失败");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("出库失败");
        }
    }

    /**
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult orderOutAll(CsDeviceDetails entity) {
        try {
            // 1. 首先查询需要出库的所有物品
            List<CsDeviceDetails> outAllList = mapper.getOrderOutAllList(entity);

            // 2. 先检查所有工器具的库存是否充足
            for (CsDeviceDetails item : outAllList) {
                if (!item.getDevType().equals("0")) {
                    // 工器具需要检查库存
                    BigDecimal toolNum = mapper.getToolNum(item); // 注意：参数应该是 item
                    BigDecimal outNum = item.getOutNum();
                    if (toolNum.compareTo(outNum) < 0) {
                        BigDecimal shortage = outNum.subtract(toolNum);
                        return AjaxResult.error(String.format(
                                "库存不足！工具：%s，当前可用：%s，需要出库：%s，短缺：%s",
                                item.getTypeName(),
                                toolNum.stripTrailingZeros().toPlainString(),
                                outNum.stripTrailingZeros().toPlainString(),
                                shortage.stripTrailingZeros().toPlainString()
                        ));
                    }
                }
            }

            // 3. 所有库存检查通过后，执行出库
            Integer out = mapper.orderOutAll(entity);
            if (out <= 0) {
                return AjaxResult.error("出库失败");
            }

            // 4. 更新库存
            for (CsDeviceDetails item : outAllList) {
                if (item.getDevType().equals("0")) {
                    // 装备类型
                    mapper.updateOrderZb(item);
                } else {
                    // 工器具类型 - 此时库存肯定是充足的
                    mapper.updateOrderGj(item);
                }
            }

            return AjaxResult.success("出库成功");

        } catch (Exception e) {
            log.error("批量出库失败", e);
            throw new RuntimeException("出库失败：" + e.getMessage());
        }
    }

    /**
     * @param entity
     * @return
     */
    @Override
    public AjaxResult orderOutCancel(CsDeviceDetails entity) {
        try {
            Integer out = mapper.orderOutCancel(entity);
            return out > 0 ? AjaxResult.success("出库成功") : AjaxResult.error("出库失败");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("出库失败");
        }
    }

    /**
     * @param entity
     * @return
     */
    @Override
    public AjaxResult orderOutCancelAll(CsDeviceDetails entity) {
        try {
            Integer out = mapper.orderOutCancelAll(entity);
            return out > 0 ? AjaxResult.success("出库成功") : AjaxResult.error("出库失败");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("出库失败");
        }
    }

    /**
     * 获取待出库单子
     *
     * @param dto
     * @return
     */
    @Override
    public List<CsDeviceInfo> getOutboundList(CsDeviceInfo dto) {
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 管理员和省公司可查看所有数据
//        if (userId != null && deptId != null
//                && !userId.equals(ADMIN_ID)
//                && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {
//            dto.setCompanyId(deptId);
//        }
        if(ADMIN_ID.equals(userId)){
            dto.setCompanyId(1L);
        }else{
            dto.setCompanyId(deptId);
        }
        return mapper.getOutboundList(dto);
    }

    /**
     * 生成任务编号
     *
     * @param thisMonthMaxOrder
     * @return
     */
    private String genderTaskCode(int thisMonthMaxOrder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date nowDate = DateUtils.getNowDate();
        String format = dateFormat.format(nowDate);
        String result = format.replace("-", "");
        return TypeConstants.LEASE_TASK_TYPE_LABEL + result + String.format("-%04d", thisMonthMaxOrder + 1);
    }

    /**
     * 维修接口
     *
     * @param vo
     * @return
     */
    @Override
    public AjaxResult updateDevChangeInfo2(CsDeviceChangeVo vo) {
        try {
            String username = SecurityUtils.getLoginUser().getSysUser().getNickName();

            vo.setCreateUser(username);
            if (StringUtils.isBlank(vo.getType())) {
                return AjaxResult.error("请上传类型type:1入库 2出库 3 退役  4 维修");
            }
            String json = vo.getJsonData();
            if (StringUtils.isBlank(json)) {
                return AjaxResult.error("请选择变更的设备");
            }
            List<CsDeviceChangeDetailsVo> list = JSON.parseArray(json, CsDeviceChangeDetailsVo.class);
            if (list == null || list.isEmpty()) {
                return AjaxResult.error("请选择变更的设备");
            }
            //入库厂家
            String usUnit = mapper.getChangeUnit(list.get(0).getDevId());
            vo.setUseUint(usUnit);
            vo.setChangeUnit(usUnit);
            vo.setChangeStatus("1");
            vo.setDevNum(list.size() + "");
            String proId = vo.getProCode();
            int num = mapper.addChangeInfo(vo);
            if (num > 0) {
                for (CsDeviceChangeDetailsVo deviceChangeDetailsVo : list) {
                    CsDeviceChangeVo entity = new CsDeviceChangeVo();
                    entity.setDevId(deviceChangeDetailsVo.getDevId());
                    entity.setChangeStatus(deviceChangeDetailsVo.getStatus());
                    entity.setUseUint(usUnit);
                    entity.setChangeUnit(usUnit);
                    if ("1".equals(deviceChangeDetailsVo.getStatus())) {
                        deviceChangeDetailsVo.setStatus("1");
                        updateDevDetails2(deviceChangeDetailsVo.getDevId(), proId, "1", deviceChangeDetailsVo.getNum());
                    } else {
                        deviceChangeDetailsVo.setStatus("4");
                        updateDevDetails2(deviceChangeDetailsVo.getDevId(), proId, "4", deviceChangeDetailsVo.getNum());
                    }
                    //新增设备列表数据
                    deviceChangeDetailsVo.setChangeId(vo.getId());
                    //新增设备详情
                    int isSuccess = mapper.addDetailsInfo(deviceChangeDetailsVo);
                    if (isSuccess > 0) {
                        vo.setDevId(deviceChangeDetailsVo.getDevId());
                        vo.setChangeStatus(vo.getStatus());
                        vo.setUseUint(null);
                        vo.setUserName(null);
                        vo.setUserPhone(null);
                        vo.setProCode(null);
                        mapper.updateDevInfo(entity);
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return AjaxResult.success();
    }

    /**
     * 新增设备台账数据
     *
     * @param vo
     * @return
     */
    @Override
    public AjaxResult addChangeInfo(CsDeviceChangeVo vo) {
        try {
            String username = SecurityUtils.getLoginUser().getSysUser().getNickName();
            vo.setCreateUser(username);
            String proCode = vo.getProCode();
            if (StringUtils.isBlank(proCode)) {
                return AjaxResult.error("请选择工程");
            }
            if (StringUtils.isBlank(vo.getType())) {
                return AjaxResult.error("请上传类型type:1入库 2出库 3 退役  4 维修");
            }
            String json = vo.getJsonData();
            if (StringUtils.isBlank(json)) {
                return AjaxResult.error("请选择变更的设备");
            }
            List<CsDeviceChangeDetailsVo> list = JSON.parseArray(json, CsDeviceChangeDetailsVo.class);
            if (list == null || list.isEmpty()) {
                return AjaxResult.error("请选择变更的设备");
            }
            //出库
            if ("2".equals(vo.getType())) {
                String changeUnit = mapper.getChangeUnit(list.get(0).getDevId());
                vo.setChangeUnit(changeUnit);
            } else {
                //
                String changeUnit = mapper.getChangeUnitById(list.get(0).getDevId());
                vo.setChangeUnit(changeUnit);
            }
            if ("1".equals(vo.getType())) {
                //入库厂家
                String changeUnit = mapper.getChangeUnit(list.get(0).getDevId());
                vo.setUseUint(changeUnit);
            }
            //变更前状态查询
            String changeStatus = mapper.getChangeStatus(list.get(0).getDevId());
            vo.setChangeStatus(changeStatus);
            vo.setDevNum(list.size() + "");
            int num = mapper.addChangeInfo(vo);
            if (num > 0) {
                for (CsDeviceChangeDetailsVo deviceChangeDetailsVo : list) {
                    //新增设备列表数据
                    deviceChangeDetailsVo.setChangeId(vo.getId());
                    //数据更新
                    updateDevDetails(deviceChangeDetailsVo.getDevId(), vo.getProCode(), vo.getType(), deviceChangeDetailsVo.getNum());
                    //新增设备详情
                    int isSuccess = mapper.addDetailsInfo(deviceChangeDetailsVo);
                    if (isSuccess > 0) {
                        vo.setDevId(deviceChangeDetailsVo.getDevId());
                        if ("2".startsWith(vo.getType())) {
                            vo.setChangeStatus(vo.getStatus());
                        } else if ("3".startsWith(vo.getType())) {
                            vo.setChangeStatus("4");
                        } else if ("4".startsWith(vo.getType())) {
                            vo.setChangeStatus("5");
                        }
                        mapper.updateDevInfo(vo);
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return AjaxResult.success();
    }

    public void updateDevDetails2(String devId, String proCode, String type, int num) {
        try {
            DevChangeDetailsVo vo = new DevChangeDetailsVo(devId, proCode, type, num);
            List<DevChangeDetailsVo> list = mapper.getDevChangeDetailsList(vo);
            DevChangeDetailsVo devChangeDetailsVo = new DevChangeDetailsVo(devId, proCode, "5", num);
            List<DevChangeDetailsVo> newList = mapper.getDevChangeDetailsList(devChangeDetailsVo);
            for (DevChangeDetailsVo voo : newList) {
                if (voo.getNum() == num) {
                    mapper.deleteDevChangeDetails(voo);
                } else if (voo.getNum() > num) {
                    int newNum = voo.getNum() - num;
                    vo.setNum(newNum);
                    mapper.updateChangeDetailsNum(vo);
                }
            }
            //入库--报废
            if ("4".equals(type)) {
                if (list == null || list.isEmpty()) {
                    mapper.addDevChangeDetails(vo);
                } else {
                    for (DevChangeDetailsVo voo : list) {
                        int newNum = voo.getNum() + num;
                        vo.setNum(newNum);
                        mapper.updateChangeDetailsNum(vo);
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    /**
     * 修改设备 状态
     */
    public void updateDevDetails(String devId, String proCode, String type, int num) {
        try {
            DevChangeDetailsVo vo = new DevChangeDetailsVo(devId, proCode, type, num);
            List<DevChangeDetailsVo> list = mapper.getDevChangeDetailsList(vo);
            if ("1".equals(type) || "5".equals(type)) {
                DevChangeDetailsVo devChangeDetailsVo = new DevChangeDetailsVo(devId, proCode, "2", num);
                List<DevChangeDetailsVo> newList = mapper.getDevChangeDetailsList(devChangeDetailsVo);
                for (DevChangeDetailsVo voo : newList) {
                    if (voo.getNum() == num) {
                        mapper.deleteDevChangeDetails(voo);
                    } else if (voo.getNum() > num) {
                        int newNum = voo.getNum() - num;
                        vo.setNum(newNum);
                        mapper.updateChangeDetailsNum(vo);
                    }
                }
            }
            //入库
            if ("1".equals(type)) {
                //查询 历史数据 进行删除
                for (DevChangeDetailsVo voo : list) {
                    if (voo.getNum() == num) {
                        mapper.deleteDevChangeDetails(voo);
                    } else if (voo.getNum() > num) {
                        int newNum = voo.getNum() - num;
                        vo.setNum(newNum);
                        mapper.updateChangeDetailsNum(vo);
                    }
                }
            } else if ("2".equals(type) || "3".equals(type) || "4".equals(type) || "5".equals(type)) {
                if (list == null || list.isEmpty()) {
                    mapper.addDevChangeDetails(vo);
                } else {
                    for (DevChangeDetailsVo voo : list) {
                        int newNum = voo.getNum() + num;
                        vo.setNum(newNum);
                        mapper.updateChangeDetailsNum(vo);
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }

    }

    /**
     * 查询工程下拉选
     *
     * @param vo
     * @return
     */
    @Override
    public List<JjProjectVo> getProList(JjProjectVo vo) {
        try {
            return mapper.getProList(vo);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return new ArrayList<>();
    }

    /**
     * 查询设备流转台账记录
     *
     * @param vo
     * @return
     */
    @Override
    public List<CsDeviceChangeVo> getDevChangeList(CsDeviceChangeVo vo) {
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        try {
            // 核心逻辑：给 endTime 加 1 天（仅当 endTime 非空时处理）
            String originalEndTime = vo.getEndTime();
            if (originalEndTime != null && !originalEndTime.trim().isEmpty()) {
                // 1. 去除首尾空格（避免前端传参带空格导致解析失败）
                String endTime = originalEndTime.trim();
                // 2. 解析字符串为 LocalDate（yyyy-MM-dd 格式）
                LocalDate endLocalDate = LocalDate.parse(endTime, dateFormatter);
                // 3. 日期加 1 天
                LocalDate endTimeAfterAddOneDay = endLocalDate.plusDays(1);
                // 4. 重新格式化为字符串，设置回 VO（关键：传给 Mapper）
                vo.setEndTime(endTimeAfterAddOneDay.format(dateFormatter));

            }
            Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
            Long userId = SecurityUtils.getLoginUser().getUserid();
            if(ADMIN_ID.equals(userId)){
                vo.setCompanyId(1L);
            }else{
                vo.setCompanyId(deptId);
            }
            return mapper.getDevChangeList(vo);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return new ArrayList<>();
    }

    /**
     * 设备出库单记录
     *
     * @param vo
     * @return
     */
    @Override
    public List<DevChangeVo> getDevDetails(CsDeviceChangeDetailsVo vo) {
        try {
            DevChangeVo entity = mapper.getChange(vo);
            vo.setType(entity.getType());
            List<DevChangeVo> list = mapper.getDevDetails(vo);
            for (DevChangeVo devChangeVo : list) {
                if (devChangeVo.getWorkingHours() == null) {
                    devChangeVo.setWorkingHours(0);
                }

                devChangeVo.setRemainingHours(devChangeVo.getMaxWorkingHours() - devChangeVo.getWorkingHours());
            }
            return list;
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return new ArrayList<>();
    }

    @Override
    public List<Map<String, Object>> getVoltageLevel(JjProjectVo vo) {
        try {
            return mapper.getVoltageLevel(vo);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return new ArrayList<>();
    }
}
