package com.bonus.material.lease.service.impl;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import com.bonus.common.biz.constant.MaterialConstants;
import com.bonus.common.biz.enums.LeaseTaskStatusEnum;
import com.bonus.common.biz.enums.MaMachineStatusEnum;
import com.bonus.common.biz.enums.MaTypeManageTypeEnum;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.material.basic.mapper.BmAgreementInfoMapper;
import com.bonus.material.lease.domain.LeaseApplyDetails;
import com.bonus.material.lease.mapper.LeaseApplyDetailsMapper;
import com.bonus.material.lease.mapper.LeaseApplyInfoMapper;
import com.bonus.material.ma.domain.Type;
import com.bonus.material.ma.mapper.MachineMapper;
import com.bonus.material.ma.mapper.TypeMapper;
import com.bonus.material.settlement.domain.SltAgreementInfo;
import com.bonus.material.settlement.mapper.SltAgreementInfoMapper;
import com.bonus.material.task.mapper.TmTaskAgreementMapper;
import com.bonus.material.task.mapper.TmTaskMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bonus.material.lease.mapper.LeaseOutDetailsMapper;
import com.bonus.material.lease.domain.LeaseOutDetails;
import com.bonus.material.lease.service.ILeaseOutDetailsService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 领料出库详细Service业务层处理
 * 
 * @author xsheng
 * @date 2024-10-16
 */
@Service
@Slf4j
public class LeaseOutDetailsServiceImpl implements ILeaseOutDetailsService {
    @Autowired
    LeaseApplyInfoMapper leaseApplyInfoMapper;

    @Autowired
    private LeaseOutDetailsMapper leaseOutDetailsMapper;

    @Autowired
    LeaseApplyDetailsMapper leaseApplyDetailsMapper;

    @Autowired
    MachineMapper machineMapper;

    @Autowired
    TypeMapper typeMapper;

    @Autowired
    private TmTaskMapper tmTaskMapper;

    @Autowired
    private SltAgreementInfoMapper sltAgreementInfoMapper;

    @Autowired
    BmAgreementInfoMapper bmAgreementInfoMapper;

    @Autowired
    TmTaskAgreementMapper tmTaskAgreementMapper;
    /**
     * 查询领料出库详细
     * 
     * @param id 领料出库详细主键
     * @return 领料出库详细
     */
    @Override
    public LeaseOutDetails selectLeaseOutDetailsById(Long id) {
        return leaseOutDetailsMapper.selectLeaseOutDetailsById(id);
    }

    /**
     * 查询领料出库详细列表
     * 
     * @param leaseOutDetails 领料出库详细
     * @return 领料出库详细
     */
    @Override
    public List<LeaseOutDetails> selectLeaseOutDetailsList(LeaseOutDetails leaseOutDetails) {
        return leaseOutDetailsMapper.selectLeaseOutDetailsList(leaseOutDetails);
    }

    /**
     * 新增领料出库详细
     * 
     * @param leaseOutDetailsList 领料出库详细
     * @return 结果
     */
    @Override
    public AjaxResult insertLeaseOutDetails(List<LeaseOutDetails> leaseOutDetailsList) {
        for (LeaseOutDetails bean : leaseOutDetailsList) {
            AjaxResult ajaxResult = leaseOut(bean);
            if (ajaxResult.isError()) {
                return ajaxResult;
            }
        }
        return AjaxResult.success();
    }

    /**
     * 修改领料出库详细
     * 
     * @param leaseOutDetails 领料出库详细
     * @return 结果
     */
    @Override
    public int updateLeaseOutDetails(LeaseOutDetails leaseOutDetails) {
        leaseOutDetails.setUpdateTime(DateUtils.getNowDate());
        try {
            return leaseOutDetailsMapper.updateLeaseOutDetails(leaseOutDetails);
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    /**
     * 批量删除领料出库详细
     * 
     * @param ids 需要删除的领料出库详细主键
     * @return 结果
     */
    @Override
    public int deleteLeaseOutDetailsByIds(Long[] ids) {
        return leaseOutDetailsMapper.deleteLeaseOutDetailsByIds(ids);
    }

    /**
     * 删除领料出库详细信息
     * 
     * @param id 领料出库详细主键
     * @return 结果
     */
    @Override
    public int deleteLeaseOutDetailsById(Long id) {
        return leaseOutDetailsMapper.deleteLeaseOutDetailsById(id);
    }

    /**
     * 领料出库处理
     *
     * @param record 出库对象
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult leaseOut(LeaseOutDetails record) {
        int res = 0;
        try {
            // 1、判断库存是否足够
            boolean isEnough = checkStorageIsEnough(record);
            //record.setPreStoreNum(getStorageNum(record));
            if (isEnough) {
                if ((record.getManageType() == MaTypeManageTypeEnum.NUMBER_DEVICE.getTypeId()) && record.getInputNum() != null) {
                    record.setOutNum(record.getInputNum());
                }

                res = checkStorageNum(record);

                if (res > 0) {
                    // 3、插入出库记录，修改库存，修改机具状态
                    res = insertRecords(record);
                    if (res == 0) {
                        throw new RuntimeException("出库失败,更新设备规格库存数量时出错!");
                    }
                    // 4、修改任务状态（tm_task）
                    res = updateTaskStatus(record);
                    if (res == 0) {
                        throw new RuntimeException("出库失败,修改任务状态失败");
                    }
                    // 5、插入结算记录
                    String taskId = leaseApplyInfoMapper.getTaskId(record.getParentId());
                    res = insSltInfo(taskId, record);
                    if (res == 0) {
                        throw new RuntimeException("出库失败,插入结算记录失败");
                    }
                    //record.setPostStoreNum(getStorageNum(record));
                } else {
                    return AjaxResult.error("领料出库失败,机具库存不足");
                }
            } else {
                return AjaxResult.error("已领数量大于预领数量或该机具未在库");
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("出库失败");
        }
        return AjaxResult.success("出库成功");
    }

    // 判断库存是否足够
    private boolean checkStorageIsEnough(LeaseOutDetails record) {
        if (record.getManageType().equals(MaTypeManageTypeEnum.NUMBER_DEVICE.getTypeId())) {
            LeaseApplyDetails details = leaseApplyDetailsMapper.getOutboundNum(record);
            if (details == null) {
                return false;
            }
        } else if (record.getManageType().equals(MaTypeManageTypeEnum.CODE_DEVICE.getTypeId())) {
            if (!(Objects.equals(0, record.getMaId()) || record.getMaId() == null)) {
                String status = machineMapper.getMachineStatus(record);
                if (!String.valueOf(MaMachineStatusEnum.IN_STORE.getStatus()).equals(status)) {
                    return false;
                }
            }
        }
        return true;
    }

    private int updateTaskStatus(LeaseOutDetails record) {
        int res = 0;
        // 进行状态判断
        List<LeaseApplyDetails> leaseApplyDetailsList = leaseApplyDetailsMapper.getByParentId(record.getParentId());
        int i = 0;
        for (LeaseApplyDetails bean : leaseApplyDetailsList) {
            if (Objects.equals(bean.getPreNum(), bean.getAlNum())) {
                i++;
            }
        }
        String taskId = leaseApplyInfoMapper.getTaskId(record.getParentId());
        if (i == leaseApplyDetailsList.size()) {
            tmTaskMapper.updateTaskStatus(taskId, LeaseTaskStatusEnum.LEASE_TASK_FINISHED.getStatus());
            res = 1;
        } else {
            tmTaskMapper.updateTaskStatus(taskId, LeaseTaskStatusEnum.LEASE_TASK_IN_PROGRESS.getStatus());
            res = 1;
        }
        return res;
    }

    private int checkStorageNum(LeaseOutDetails record) {
        double outNum = 0.1;
        if (StringUtils.isNull(record)) {
            return 0;
        }

        if (record.getOutNum() == null || record.getOutNum() < outNum) {
            record.setOutNum(0L);
        }
        //判断(ma_type 设备规格表)中的库存够不够出库的
        Type maType = typeMapper.selectByTypeId(record);
        if (maType != null) {
            if ("0".equals(maType.getManageType())) {
                int count = typeMapper.getCountOfCodeMachine(record);
                if (BigDecimal.valueOf(count).compareTo(BigDecimal.valueOf(record.getOutNum())) < 0) {
                    return 0;
                }
            } else if ("1".equals(maType.getManageType())) {
                if (maType.getStorageNum() == null || maType.getStorageNum().compareTo(record.getOutNum()) < 0) {
                    return 0;
                }
            }
        }
        return 1;
    }

    private int insertRecords(LeaseOutDetails record) {
        int res = 0;
        // 首先更新领料任务详情表的领料数及状态（lease_apply_details）
        res = leaseApplyDetailsMapper.updateLeaseApplyDetailsOutNum(record);
        LeaseApplyDetails leaseApplyDetails = leaseApplyDetailsMapper.getLeaseApplyDetails(record);
        if (leaseApplyDetails.getPreNum().equals(leaseApplyDetails.getAlNum()) || leaseApplyDetails.getAuditNum().equals(leaseApplyDetails.getAlNum())) {
            leaseApplyDetailsMapper.updateLeaseApplyDetailsByLeaseOutRecord(record);
        }
        if (res > 0) {
            // 插入领料出库明细表（lease_out_details）
            res = leaseOutDetailsMapper.insertLeaseOutDetails(record);
            if (res > 0) {
                // 普通机具减少 (ma_type 设备规格表)的库存数量
                res = typeMapper.updateMaTypeStockNum(record);
                // 更新 (ma_machine 设备表)的状态
                machineMapper.updateMaMachineStatus(record, MaMachineStatusEnum.IN_USE.getStatus());
            }
        }
        return res;
    }

    public int insSltInfo(String taskId, LeaseOutDetails record) {
        int res = 0;
        SltAgreementInfo sltAgreementInfo = sltAgreementInfoMapper.getSltAgreementInfo(record);
        if (sltAgreementInfo != null) {
            Long num = sltAgreementInfo.getNum();
            Long outNum = record.getOutNum();
            sltAgreementInfo.setNum(num + outNum);
            res = sltAgreementInfoMapper.updSltInfo(sltAgreementInfo);
        } else {
            String agreementId = tmTaskAgreementMapper.getAgreementId(taskId);
            String protocol = bmAgreementInfoMapper.getProtocol(agreementId);
            Type maType = typeMapper.getMaType(record.getTypeId());
            if (StringUtils.isEmpty(protocol)) {
                maType.setFinalPrice(maType.getLeasePrice());
            } else {
                if (MaterialConstants.INNER_PROTOCAL.equals(protocol)) {
                    maType.setFinalPrice(maType.getLeasePrice());
                } else if (MaterialConstants.OUTER_PROTOCAL.equals(protocol)) {
                    maType.setFinalPrice(maType.getRentPrice());
                } else {
                    maType.setFinalPrice(maType.getLeasePrice());
                }
            }
            res = sltAgreementInfoMapper.insSltInfo(record, agreementId, maType);
        }
        return res;
    }

}
