package com.bonus.sgzb.app.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.bonus.sgzb.app.domain.LeaseApplyDetails;
import com.bonus.sgzb.app.domain.TmTask;
import com.bonus.sgzb.app.mapper.LeaseApplyDetailsMapper;
import com.bonus.sgzb.app.mapper.LeaseOutDetailsMapper;
import com.bonus.sgzb.app.service.LeaseOutDetailsService;
import com.bonus.sgzb.base.api.domain.*;
import com.bonus.sgzb.base.mapper.MaLabelBindMapper;
import com.bonus.sgzb.base.mapper.MaMachineMapper;
import com.bonus.sgzb.base.vo.MaLabelBindVO;
import com.bonus.sgzb.common.core.utils.StringUtils;
import com.bonus.sgzb.common.core.web.domain.AjaxResult;
import com.bonus.sgzb.common.security.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * Description: 领料出库详情接口实现类
 *
 * @Author 阮世耀
 * @Create 2023/12/17 15:06
 * @Version 1.0
 */

@Service(value = "LeaseOutDetailsService")
@Slf4j
public class LeaseOutDetailsServiceImpl implements LeaseOutDetailsService {

    @Resource
    private LeaseOutDetailsMapper leaseOutDetailsMapper;
    @Resource
    private LeaseApplyDetailsMapper leaseApplyDetailsMapper;
    @Resource
    private MaMachineMapper maMachineMapper;
    @Resource
    private MaLabelBindMapper maLabelBindMapper;

    /**
     * 根据任务id查询出库数据
     *
     * @param parentId 任务id
     * @return 出库数据集合
     */
    @Override
    public List<LeaseOutDetails> selectListByParentId(String parentId) {
        return leaseOutDetailsMapper.selectListByParentId(parentId);
    }

    /**
     * 领料出库列表
     *
     * @param bean 参数
     * @return 列表
     */
    @Override
    public List<LeaseOutDetails> leaseOutRecordList(LeaseOutDetails bean) {
        return leaseOutDetailsMapper.leaseOutRecordList(bean);
    }

    @Override
    @Transactional
    public int bindMachineByRfid(MaMachine maMachine) {
        List<MaMachine> maMachineByMaIdAndMaCode = maMachineMapper.getMaMachineByMaIdAndMaCode(maMachine);
        if (CollUtil.isNotEmpty(maMachineByMaIdAndMaCode)) {
            for (MaMachine machine : maMachineByMaIdAndMaCode) {
                if (StringUtils.isBlank(machine.getRfidCode())) {
                    machine.setRfidCode(maMachine.getRfidCode());
                    maMachineMapper.updateMaMachine(machine);
                } else {
                    return 2;
                }
            }
            return 0;
        }
        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int bindMachineByQrCode(MaMachine maMachine) {
        List<MaMachine> maMachineByMaIdAndMaCode = maMachineMapper.getMaMachineByMaTypeAndMaCode(maMachine);
        if (CollUtil.isEmpty(maMachineByMaIdAndMaCode)) {
            maMachine.setCreateTime(new Date());
            int i = maMachineMapper.maMachineAdd(maMachine);
            MaLabelBind maLabelBinds = maLabelBindMapper.selectMaLabelBindByMaCode(maMachine);
            if (maLabelBinds != null) {
                MaLabelBindVO maLabelBind = new MaLabelBindVO();
                maLabelBind.setTypeId(maMachine.getTypeId());
                maLabelBind.setBindTime(new Date().toString());
                maLabelBind.setBinder(SecurityUtils.getLoginUser().getUsername());
                maLabelBindMapper.updateMaLabelBind(maLabelBind);
                return 0;
            } else {
                MaLabelBind maLabelBind = new MaLabelBind();
                maLabelBind.setLabelCode(maMachine.getQrCode());
                maLabelBind.setMaId(maMachine.getMaId());
                maLabelBind.setTypeId(maMachine.getTypeId());
                maLabelBind.setBindTime(new Date());

                maLabelBind.setBinder(maMachine.getBinder());
                maLabelBind.setStatus("1");
                maLabelBind.setLabelType(9);
                maLabelBindMapper.insertLabelBind(maLabelBind);
                maLabelBindMapper.updateMalableCode(maLabelBind);
                maLabelBindMapper.updateMatypeNum(maLabelBind.getTypeId());
                return 0;
            }
        } else {
            return 1;
        }
    }

    @Override
    @Transactional
    public AjaxResult submitOutRfid(List<LeaseOutDetails> recordList) {
        for (LeaseOutDetails bean : recordList) {
            AjaxResult ajaxResult = submitOut(bean);
            if (ajaxResult.isError()) {
                return ajaxResult;
            }
        }
        return AjaxResult.success();
    }

    @Override
    public List<TmTask> getDetailsByApplyId(TmTask typeId) {
        return leaseApplyDetailsMapper.getDetailsByApplyId(typeId);
    }

    /**
     * 领料出库处理
     *
     * @param record 出库对象
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult submitOut(LeaseOutDetails record) {
        int res = 0;
        try {
            // 1、判断是否重复提交
            res = checkRepeatSubmit(record);
            record.setPreStoreNum(getStorageNum(record));
            if (res > 0) {
                if ((record.getManageType() == 1 || record.getManageType() == 2) && record.getInputNum() != null) {
                    record.setOutNum(record.getInputNum().doubleValue());
                }
                //2、判断成套机具出库库存是否足够
                if (record.getManageType() == 2) {
                    res = checkStorageNumCt(record);
                    if (res == 0) {
                        throw new RuntimeException("出库失败,库存不足");
                    }
                } else {
                    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 = leaseOutDetailsMapper.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) {
            e.printStackTrace();
            return AjaxResult.error("出库失败");
        }
        return AjaxResult.success("出库成功");
    }

    private int getStorageNum(LeaseOutDetails record) {
        if (StringUtils.isNull(record)) {
            return 0;
        }
        //判断(ma_type 设备规格表)中的库存够不够出库的
        MaType maType = leaseOutDetailsMapper.selectByTypeId(record);
        if (maType != null) {
            if ("1".equals(maType.getManageType())) {
                return maType.getNum().intValue();
            } else if ("0".equals(maType.getManageType())) {
                return leaseOutDetailsMapper.getCountOfCodeMachine(record);
            }
        }
        return 0;
    }

    private int insertRecords(LeaseOutDetails record) {
        int res = 0;
        // 首先更新领料任务详情表的领料数及状态（lease_apply_details）
        res = leaseOutDetailsMapper.updateLeaseApplyDetailsOutNum(record);
        LeaseApplyDetails leaseApplyDetails = leaseOutDetailsMapper.getLeaseApplyDetails(record);
        if (leaseApplyDetails.getPreNum().equals(leaseApplyDetails.getAlNum()) || leaseApplyDetails.getAuditNum().equals(leaseApplyDetails.getAlNum())) {
            leaseOutDetailsMapper.updateLeaseApplyDetails(record);
        }
        if (res > 0) {
            // 插入领料出库明细表（lease_out_details）
            res = leaseOutDetailsMapper.insertSelective(record);
            if (res > 0) {
                if (record.getManageType() == 2) {
                    // 成套机具减少 (ma_type 设备规格表)的库存数量
                    res = leaseOutDetailsMapper.updateMaTypeStockNum(record);
                    // 成套机具减少 (ma_type 设备规格表)配件的库存数量
                    List<TmTask> typeIds = leaseOutDetailsMapper.getMaTypeDetails(record);
                    typeIds.removeIf(item -> item == null);
                    for (TmTask typeId : typeIds) {
                        MachinePart machinePart = leaseOutDetailsMapper.getMachineParts(typeId);
                        machinePart.setPartNum((typeId.getPartNum() * record.getOutNum()));
                        typeId.setNum(machinePart.getNum() - machinePart.getPartNum());
                        res = leaseOutDetailsMapper.updateMaTypeStockNumCt(typeId);
                    }
                } else {
                    // 普通机具减少 (ma_type 设备规格表)的库存数量
                    res = leaseOutDetailsMapper.updateMaTypeStockNum(record);
                }
                // 更新 (ma_machine 设备表)的状态
                leaseOutDetailsMapper.updateMaMachineStatus(record);
            }
        }
        return res;
    }

    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 = leaseOutDetailsMapper.getTaskId(record.getParentId());
        if (i == leaseApplyDetailsList.size()) {
            leaseOutDetailsMapper.updateTaskStatus(taskId, 35);
            res = 1;
        } else {
            leaseOutDetailsMapper.updateTaskStatus(taskId, 34);
            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(0.00);
        }
        //判断(ma_type 设备规格表)中的库存够不够出库的
        MaType maType = leaseOutDetailsMapper.selectByTypeId(record);
        if (maType != null) {
            if ("0".equals(maType.getManageType())) {
                int count = leaseOutDetailsMapper.getCountOfCodeMachine(record);
                if (BigDecimal.valueOf(count).compareTo(BigDecimal.valueOf(record.getOutNum())) < 0) {
                    return 0;
                }
            } else if ("1".equals(maType.getManageType())) {
                if (maType.getNum() == null || maType.getNum().compareTo(BigDecimal.valueOf(record.getOutNum())) < 0) {
                    return 0;
                }
            }
        }
        return 1;
    }

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

        if (record.getOutNum() == null || record.getOutNum() < outNum) {
            record.setOutNum(0.00);
        }
        //先判断成套机具的库存是否足够
        int num = leaseOutDetailsMapper.getmaChineByCt(record);
        if (num < record.getOutNum()) {
            return res;
        }
        //判断(ma_type 设备规格表)中的库存够不够出库的
        List<TmTask> typeIds = leaseOutDetailsMapper.getMaTypeDetails(record);
        typeIds.removeIf(item -> item == null);
        for (TmTask typeId : typeIds) {
            MachinePart machinePart = leaseOutDetailsMapper.getMachineParts(typeId);
            machinePart.setPartNum((typeId.getPartNum() * record.getOutNum()));
            if (machinePart.getNum() < machinePart.getPartNum()) {
                return res;
            }
        }
        return 1;
    }

    private int checkRepeatSubmit(LeaseOutDetails record) {
        String maStatus = "15";
        int res = 0;
        if (record.getManageType() == 1 || record.getManageType() == 2) {
            // 如果是数量出库校验待出库数量
            LeaseApplyDetails details = leaseOutDetailsMapper.getOutboundNum(record);
            if (details == null) {
                return res;
            } else {
                res = 1;
            }
        } else {
            // 如果是编码出库判断是否在库
            if (!(Objects.equals(0, record.getMaId()) || record.getMaId() == null)) {
                String status = leaseOutDetailsMapper.getMachineStatus(record);
                if (!maStatus.equals(status)) {
                    return res;
                } else {
                    res = 1;
                }
            }
        }
        return res;
    }

    public int insSltInfo(String taskId, LeaseOutDetails record) {
        int res = 0;
        SltAgreementInfo sltAgreementInfo = leaseOutDetailsMapper.getSltAgreementInfo(record);
        if (sltAgreementInfo != null) {
            double num = Double.parseDouble(sltAgreementInfo.getNum());
            double outNum = record.getOutNum();
            sltAgreementInfo.setNum(String.valueOf(num + outNum));
            res = leaseOutDetailsMapper.updSltInfo(sltAgreementInfo);
        } else {
            String agreementId = leaseOutDetailsMapper.getAgreementId(taskId);
            String protocol = leaseOutDetailsMapper.getProtocol(agreementId);
            MaType ma = leaseOutDetailsMapper.getMaType(record.getTypeId());
            if (StringUtils.isEmpty(protocol)) {
                ma.setFinalPrice(ma.getLeasePrice());
            } else {
                if ("1".equals(protocol)) {
                    ma.setFinalPrice(ma.getLeasePrice());
                } else if ("2".equals(protocol)) {
                    ma.setFinalPrice(ma.getRentPrice());
                } else {
                    ma.setFinalPrice(ma.getLeasePrice());
                }
            }
            res = leaseOutDetailsMapper.insSltInfo(record, agreementId, ma);
        }
        return res;
    }

    /**
     * @param maCode 编码ID
     * @return 数据
     */
    @Override
    public List<MaMachine> getMaMachineByCode(String maCode) {
        return maMachineMapper.getMaMachineByCode(maCode);
    }


    @Override
    public List<MaMachine> getMaMachineByQrCode(String qrCode) {
        return maMachineMapper.getMaMachineByQrCode(qrCode);
    }

    @Override
    public List<LeaseApplyDetails> leaseOutRecord(LeaseApplyDetails bean) {
        return leaseOutDetailsMapper.leaseOutRecord(bean);
    }

    @Override
    public List<LeaseApplyDetails> proUseRecord(LeaseApplyDetails bean) {
        return leaseOutDetailsMapper.proUseRecord(bean);
    }


    @Override
    public List<MaMachine> getMaMachineByRfidCode(String rfidCode) {
        return maMachineMapper.getMaMachineByRfidCode(rfidCode);
    }

}
