package org.jeecg.modules.apply.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.TypeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.api.model.CabinetModel;
import org.jeecg.modules.api.service.CabinetApiService;
import org.jeecg.modules.api.service.CabinetConnectService;
import org.jeecg.modules.apply.entity.AduitEntity;
import org.jeecg.modules.apply.entity.ApplyDetails;
import org.jeecg.modules.apply.entity.ApplyRecord;
import org.jeecg.modules.apply.mapper.ApplyRecordMapper;
import org.jeecg.modules.apply.service.IApplyDetailsService;
import org.jeecg.modules.apply.service.IApplyRecordService;
import org.jeecg.modules.cabinet.entity.Cabinet;
import org.jeecg.modules.cabinet.mapper.CabinetMapper;
import org.jeecg.modules.material.entity.BuMaterialInfo;
import org.jeecg.modules.material.mapper.BuMaterialInfoMapper;
import org.jeecg.modules.material.model.bo.BuMaterialStockBo;
import org.jeecg.modules.tool.entity.Tool;
import org.jeecg.modules.tool.mapper.ToolMapper;
import org.jeecg.modules.toolBorrowingRecord.entity.ToolBorrowingRecord;
import org.jeecg.modules.toolBorrowingRecord.service.IToolBorrowingRecordService;
import org.jeecg.modules.toolSheet.entity.ToolSheet;
import org.jeecg.modules.toolSheet.mapper.ToolSheetMapper;
import org.jeecg.modules.workOrder.entity.WorkOrder;
import org.jeecg.modules.workOrder.mapper.WorkOrderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 工器具/物资申请记录
 * @Author: jeecg-boot
 * @Date:   2025-02-21
 * @Version: V1.0
 */
@Service
@RequiredArgsConstructor
public class ApplyRecordServiceImpl extends ServiceImpl<ApplyRecordMapper, ApplyRecord> implements IApplyRecordService {

    private final WorkOrderMapper workOrderMapper;
    private final BuMaterialInfoMapper materialInfoMapper;
    private final ToolMapper toolMapper;
    private final IApplyDetailsService applyDetailsService;

    private final CabinetMapper cabinetMapper;

    private final ToolSheetMapper toolSheetMapper;

    private final IToolBorrowingRecordService toolBorrowingRecordService;
    @Value("${spring.active}")
    private String activeProfile;
    @Override
    public boolean save(ApplyRecord entity) {
        WorkOrder workOrder = workOrderMapper.selectById(entity.getWorkOrder());
        if (workOrder == null) throw new RuntimeException("工单不存在");

        Integer applyType = entity.getApplyType();
        Integer status = workOrder.getStatus();

        // 工单状态校验
        if (status == 3) {
            if (applyType == 1) throw new RuntimeException("当前工单无法进行工器具申请操作");
            if (applyType == 0) throw new RuntimeException("当前工单无法进行物料申请操作");
        }

        // 设置工单申请状态
        if (applyType == 0) {
            workOrder.setMaterialStatus(1);
        } else if (applyType == 1) {
            workOrder.setToolsStatus(1);
        }
        workOrderMapper.updateById(workOrder);

        // 设置申请记录字段
        entity.setRegularId(workOrder.getRegularId());
        entity.setStatus(0);
        entity.setDeviceId(workOrder.getDeviceId());
        if (StringUtils.isBlank(entity.getOperateBy())) {
            entity.setOperateBy(workOrder.getCoordinator());
        }
        // 保存主表
        if (!super.save(entity)) {
            return false;
        }

        // 保存明细
        List<ApplyDetails> detailsList = entity.getDetails();
        if (detailsList != null && !detailsList.isEmpty()) {
            detailsList.forEach(item -> {
                item.setApplyId(entity.getId());
                item.setItemType(applyType);
            });
            return applyDetailsService.saveBatch(detailsList);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean aduit(AduitEntity data) {
        ApplyRecord record = baseMapper.selectById(data.getApplyId());
        if(record==null || record.getStatus()!=0){
            return false;
        }
        // 工具领用工单下发
//        if("prod".equals(activeProfile)){
//        if("dev".equals(activeProfile)){
//
//        }
        //下发工单
        sendWorkOrder(record, record.getApplyType());
        //获取登录用户信息
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        record.setAduitBy(sysUser.getId());
        record.setStatus(data.getStatus());
        record.setRejectReson(data.getReason());

        baseMapper.updateById(record);

        //增加借用记录
        if(record.getStatus() != 1){
            return true;
        }
//        if(record.getApplyType() == 1){
//            List<ApplyDetails> detailsList = applyDetailsService.list(new LambdaQueryWrapper<ApplyDetails>()
//                    .eq(ApplyDetails::getApplyId, record.getId()));
//            detailsList.forEach(item -> {
//                //增加借用记录
//                ToolSheet tool = toolSheetMapper.selectOne(new LambdaQueryWrapper<ToolSheet>()
//                        .eq(ToolSheet::getToolId, item.getItemId()).last("limit 1"));
//                if(tool == null){
//                    return;
//                }
////                if(tool.getNum() >= item.getQuantity()){
////                    tool.setNum(tool.getNum() - item.getQuantity().intValue());
////                }
////                toolSheetMapper.updateById(tool);
//                ToolBorrowingRecord borrowingRecord = new ToolBorrowingRecord();
//                borrowingRecord.setToolId(tool.getId());
//                borrowingRecord.setBorrower(record.getOperateBy());
//                borrowingRecord.setStatus(0);
//                borrowingRecord.setCount(item.getQuantity().intValue());
//                borrowingRecord.setWorkOrder(record.getWorkOrder());
//                toolBorrowingRecordService.save(borrowingRecord);
//            });
//        }else{
//            //todo 物料领用记录
//        }
        return true;
    }

    @Override
    public List<ApplyRecord> queryByWorkOrder(String workOrder) {
        List<ApplyRecord> applyRecords = super.list(new LambdaQueryWrapper<ApplyRecord>().eq(ApplyRecord::getWorkOrder,workOrder));
        if (applyRecords.isEmpty()) {
            return applyRecords;
        }
        applyRecords.forEach(record -> {
            List<ApplyDetails> detailsList = applyDetailsService.list(new LambdaQueryWrapper<ApplyDetails>().eq(ApplyDetails::getApplyId, record.getId()));
            detailsList.forEach(applyDetails -> {
                if(applyDetails.getItemType() == 0){
                    //物料
                    BuMaterialInfo materialInfo = materialInfoMapper.selectById(applyDetails.getItemId());
                    applyDetails.setItemName(materialInfo.getName());
                    applyDetails.setSpecification(materialInfo.getSpecifaction());
                    applyDetails.setUnit(materialInfo.getUnit());
                }else if(applyDetails.getItemType() == 1){
                    //工器具
                    Tool tool = toolMapper.selectById(applyDetails.getItemId());
                    applyDetails.setItemName(tool.getName());
                    applyDetails.setSpecification(tool.getModel());
                    applyDetails.setUnit(tool.getUnit());
                }
            });
            record.setDetails(detailsList);
        });
        return applyRecords;
    }

    @Autowired
    private CabinetApiService cabinetApi;
    @Autowired
    private CabinetConnectService cabinetConnectService;

    /**
     * 物料/工具领用申请通过后向物料/工具柜下发工单
     * @param applyRecord
     * @throws RuntimeException
     */
    private void sendWorkOrder(ApplyRecord applyRecord,int applyType) throws RuntimeException{
        WorkOrder workOrder = workOrderMapper.selectById(applyRecord.getWorkOrder());

        CabinetModel cabinetModel = new CabinetModel();
        cabinetModel.setUserId(workOrder.getCoordinator());//工单负责人申请
        cabinetModel.setOrderId(applyRecord.getWorkOrder());
        cabinetModel.setOrderCode(applyRecord.getWorkOrder());//初步将工单id作为工单编号
        cabinetModel.setStartTime(DateUtils.getDate("yyyy-MM-dd HH:mm:ss"));
        cabinetModel.setEndTime(LocalDate.now(ZoneId.of("Asia/Shanghai")).atTime(LocalTime.of(17,0,0)).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        cabinetModel.setToolIds(new ArrayList<>());

        List<ApplyDetails> detailsList = applyDetailsService.list(new LambdaQueryWrapper<ApplyDetails>().eq(ApplyDetails::getApplyId,applyRecord.getId()));
        if(applyType == 0){
            // 向物料柜下发物料领用工单
            cabinetModel.setMaterials(detailsList.stream()
                    .map(detail -> new CabinetModel.Material() {{
                        setMaterialId(detail.getItemId());//todo 应当是materialType，后续再改优先调试
                        setNumber(detail.getQuantity());
                    }}).collect(Collectors.toList()));
        }else if(applyType == 1){
            // 工具领用工单下发
            cabinetModel.setTools(detailsList.stream()
                    .map(detail -> new CabinetModel.Tool() {{
                        setToolType(detail.getItemId());
                        setNumber(detail.getQuantity().intValue());
                    }}).collect(Collectors.toList()));
        }

        // 通过接口下发工单
        // 下发任务工单
        Cabinet cabinet = cabinetMapper.selectOne(new LambdaQueryWrapper<Cabinet>()
                .eq(Cabinet::getType, applyType));
        List<CabinetModel> datas = new ArrayList<>();
        datas.add(cabinetModel);

        if(cabinet != null){
            cabinetApi.sendTMessages(cabinet,datas,"receiveOrderInfo"); // 取消工单是 receiveCancelOrder
        }else{
            throw new RuntimeException("领用工单下发物料/工具柜失败！");
        }
//        cabinetConnectService.sendWorkOrder(cabinetModel,applyType);
//        cabinetApiService.sendWorkOrder(cabinetModel,applyType);
    }
}
