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

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.bonus.common.biz.enums.TmTaskTypeEnum;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.settlement.domain.SltAgreementApply;
import com.bonus.material.settlement.domain.SltAgreementRelation;
import com.bonus.material.settlement.domain.vo.SltInfoVo;
import com.bonus.material.task.domain.TmTask;
import com.bonus.material.task.mapper.TmTaskMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bonus.material.settlement.mapper.SltAgreementInfoMapper;
import com.bonus.material.settlement.domain.SltAgreementInfo;
import com.bonus.material.settlement.service.ISltAgreementInfoService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 结算信息Service业务层处理
 *
 * @author xsheng
 * @date 2024-10-16
 */
@Service
public class SltAgreementInfoServiceImpl implements ISltAgreementInfoService {
    @Autowired
    private SltAgreementInfoMapper sltAgreementInfoMapper;

    @Autowired
    private TmTaskMapper taskMapper;

    /**
     * 查询结算信息
     *
     * @param id 结算信息主键
     * @return 结算信息
     */
    @Override
    public SltAgreementInfo selectSltAgreementInfoById(Long id) {
        return sltAgreementInfoMapper.selectSltAgreementInfoById(id);
    }

    /**
     * 查询结算信息列表
     *
     * @param sltAgreementInfo 结算信息
     * @return 结算信息
     */
    @Override
    public List<SltAgreementInfo> selectSltAgreementInfoList(SltAgreementInfo sltAgreementInfo) {
        return sltAgreementInfoMapper.selectSltAgreementInfoList(sltAgreementInfo);
    }

    @Override
    public List<SltAgreementInfo> getSltAgreementInfo4Project(SltAgreementInfo bean) {
        return sltAgreementInfoMapper.getSltAgreementInfo4Project(bean);
    }

    @Override
    public SltInfoVo getSltInfo(List<SltAgreementInfo> list) {
        SltInfoVo sltInfoVo = new SltInfoVo();
        //租赁费用列表
        List<SltAgreementInfo> leaseList = getLeaseList(list);
        //维修费用列表
        List<SltAgreementInfo> repairList = getRepairList(list);
        //报废费用列表
        List<SltAgreementInfo> scrapList = getScrapList(list);
        //丢失费用列表
        List<SltAgreementInfo> loseList = getLoseList(list);
        sltInfoVo.setLeaseList(leaseList);
        sltInfoVo.setRepairList(repairList);
        sltInfoVo.setScrapList(scrapList);
        sltInfoVo.setLoseList(loseList);
        List<SltAgreementRelation> relations = getRelations(leaseList, repairList, scrapList, loseList, list);
        sltInfoVo.setRelations(relations);
        return sltInfoVo;
    }

    @Override
    public List<SltAgreementApply> getSltExam(SltAgreementInfo bean) {
        return sltAgreementInfoMapper.getSltExam(bean);
    }

    @Override
    public SltInfoVo getSltExamInfo(SltAgreementApply apply) {
        SltInfoVo sltInfoVo = new SltInfoVo();
        List<SltAgreementInfo> list = new ArrayList<>();
        String cost = sltAgreementInfoMapper.getCost(apply);
        List<SltAgreementRelation> relations = sltAgreementInfoMapper.getRelations(apply);
        sltInfoVo.setRelations(relations);
        for (SltAgreementRelation relation : relations) {
            SltAgreementInfo info = new SltAgreementInfo();
            info.setAgreementId(Long.valueOf(relation.getAgreementId()));
            list.add(info);
        }
        List<SltAgreementInfo> leaseList = getLeaseList(list);
        List<SltAgreementInfo> repairList = getRepairList(list);
        List<SltAgreementInfo> scrapList = getScrapList(list);
        List<SltAgreementInfo> loseList = getLoseList(list);
        sltInfoVo.setLeaseList(leaseList);
        sltInfoVo.setRepairList(repairList);
        sltInfoVo.setScrapList(scrapList);
        sltInfoVo.setLoseList(loseList);
        sltInfoVo.setCost(cost);
        return sltInfoVo;
    }

    @Override
    @Transactional
    public int settlementReview(SltAgreementApply apply) {
        Long userid = SecurityUtils.getLoginUser().getUserid();
        apply.setAuditor(String.valueOf(userid));
        int j;
        if ("2".equals(apply.getStatus())) {
            // 驳回
            int i = sltAgreementInfoMapper.updateRelation(apply);
            j = sltAgreementInfoMapper.updateApply(apply);
        } else {
            // 通过
            int i = sltAgreementInfoMapper.updateRelation(apply);
            if (i > 0) {
                List<SltAgreementRelation> relations = sltAgreementInfoMapper.getRelations(apply);
                List<SltAgreementInfo> infos = new ArrayList<>();
                for (SltAgreementRelation bean : relations) {
                    SltAgreementInfo info = new SltAgreementInfo();
                    info.setAgreementId(Long.valueOf(bean.getAgreementId()));
                    infos.add(info);
                }
                List<SltAgreementInfo> loseList = getLoseList(infos);
                for (SltAgreementInfo agreementInfo : loseList) {
                    if (agreementInfo.getMaId() != null) {
                        agreementInfo.setStatus("103");
                        sltAgreementInfoMapper.updateMaStatus(agreementInfo);
                    }
                }
                j = sltAgreementInfoMapper.updateApply(apply);
            } else {
                throw new ServiceException("结算审核失败");
                //throw new ServiceException(ExceptionDict.SETTLEMENT_REVIEW_ERROR_MSG,ExceptionDict.SETTLEMENT_REVIEW_ERROR);
            }
        }
        return j;
    }

    /**
     * 新增结算信息
     *
     * @param sltAgreementInfo 结算信息
     * @return 结果
     */
    @Override
    public int insertSltAgreementInfo(SltAgreementInfo sltAgreementInfo) {
        sltAgreementInfo.setCreateTime(DateUtils.getNowDate());
        try {
            return sltAgreementInfoMapper.insertSltAgreementInfo(sltAgreementInfo);
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    /**
     * 修改结算信息
     *
     * @param sltAgreementInfo 结算信息
     * @return 结果
     */
    @Override
    public int updateSltAgreementInfo(SltAgreementInfo sltAgreementInfo) {
        sltAgreementInfo.setUpdateTime(DateUtils.getNowDate());
        try {
            return sltAgreementInfoMapper.updateSltAgreementInfo(sltAgreementInfo);
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    /**
     * 批量删除结算信息
     *
     * @param ids 需要删除的结算信息主键
     * @return 结果
     */
    @Override
    public int deleteSltAgreementInfoByIds(Long[] ids) {
        return sltAgreementInfoMapper.deleteSltAgreementInfoByIds(ids);
    }

    /**
     * 删除结算信息信息
     *
     * @param id 结算信息主键
     * @return 结果
     */
    @Override
    public int deleteSltAgreementInfoById(Long id) {
        return sltAgreementInfoMapper.deleteSltAgreementInfoById(id);
    }

    public List<SltAgreementInfo> getLeaseList(List<SltAgreementInfo> list) {
        List<SltAgreementInfo> leaseList = new ArrayList<>();
        for (SltAgreementInfo bean : list) {
            List<SltAgreementInfo> oneOfList = sltAgreementInfoMapper.getLeaseList(bean);
            leaseList.addAll(oneOfList);
        }
        for (SltAgreementInfo bean : leaseList) {
            if (bean.getLeasePrice() == null) {
                bean.setLeasePrice(BigDecimal.valueOf(0.00));
            }
            if (bean.getNum() == null) {
                bean.setNum(BigDecimal.valueOf(0L));
            }
            if (bean.getLeaseDay() == null) {
                bean.setLeaseDay(0L);
            }
            BigDecimal leasePrice = bean.getLeasePrice();
            BigDecimal num = bean.getNum();
            BigDecimal leaseDays = new BigDecimal(bean.getLeaseDay());
            BigDecimal costs = leasePrice.multiply(num).multiply(leaseDays);
            bean.setCosts(costs);
        }
        return leaseList;
    }

    public List<SltAgreementInfo> getRepairList(List<SltAgreementInfo> list) {
        List<SltAgreementInfo> repairList = new ArrayList<>();
        Integer taskType = TmTaskTypeEnum.TM_TASK_REPAIR.getTaskTypeId();
        //String taskType = TaskTypeEnum.MAINTENANCE_TASK.getCode();
        for (SltAgreementInfo bean : list) {
            List<TmTask> taskList = taskMapper.getTaskList(bean, taskType);
            if (taskList != null && taskList.size() > 0) {
                List<SltAgreementInfo> repairDetailsList = sltAgreementInfoMapper.getRepairDetailsList(taskList);
                repairList.addAll(repairDetailsList);
            }
        }
        return repairList;
    }

    public List<SltAgreementInfo> getScrapList(List<SltAgreementInfo> list) {
        List<SltAgreementInfo> scrapList = new ArrayList<>();
        Integer taskType = TmTaskTypeEnum.TM_TASK_SCRAP.getTaskTypeId();
        //String taskType = TaskTypeEnum.SCRAP_TASK.getCode();
        for (SltAgreementInfo bean : list) {
            List<TmTask> taskList = taskMapper.getTaskList(bean, taskType);
            if (taskList != null && taskList.size() > 0) {
                List<SltAgreementInfo> scrapDetailsList = sltAgreementInfoMapper.getScrapDetailsList(taskList);
                scrapList.addAll(scrapDetailsList);
            }
        }
        if (scrapList != null && scrapList.size() > 0) {
            for (SltAgreementInfo bean : scrapList) {

                if (bean.getBuyPrice() == null) {
                    bean.setBuyPrice(BigDecimal.valueOf(0.00));
                }
                if (bean.getNum() == null) {
                    bean.setNum(BigDecimal.valueOf(0L));
                }
                BigDecimal buyPrice = bean.getBuyPrice();
                BigDecimal num = bean.getNum();
                BigDecimal costs = buyPrice.multiply(num);
                //计算总金额
                /*BigDecimal costs = BigDecimal.ZERO;
                if (bean.getBuyPrice() != null && bean.getBuyPrice() != null){
                    BigDecimal buyPrice = new BigDecimal(bean.getBuyPrice());
                    BigDecimal num = new BigDecimal(bean.getNum());
                    costs = buyPrice.multiply(num);
                }*/
                bean.setCosts(costs);
            }
        }
        return scrapList;
    }

    public List<SltAgreementInfo> getLoseList(List<SltAgreementInfo> list) {
        List<SltAgreementInfo> loseList = new ArrayList<>();
        for (SltAgreementInfo bean : list) {
            List<SltAgreementInfo> oneOfList = sltAgreementInfoMapper.getLoseList(bean);
            loseList.addAll(oneOfList);
        }
        for (SltAgreementInfo bean : loseList) {
            if (bean.getBuyPrice() == null) {
                bean.setBuyPrice(BigDecimal.valueOf(0.00));
            }
            if (bean.getNum() == null) {
                bean.setNum(BigDecimal.valueOf(0L));
            }
            BigDecimal buyPrice = bean.getBuyPrice();
            BigDecimal num = bean.getNum();
            // 原价 x 数量
            BigDecimal costs = buyPrice.multiply(num);
            //计算租赁费用
            /*BigDecimal costs = BigDecimal.ZERO;
            if (bean.getBuyPrice() != null && bean.getNum() != null){
                BigDecimal buyPrice = new BigDecimal(bean.getBuyPrice());
                BigDecimal num = new BigDecimal(bean.getNum());
                costs = buyPrice.multiply(num);
            }*/
            bean.setCosts(costs);
        }
        return loseList;
    }

    private List<SltAgreementRelation> getRelations(List<SltAgreementInfo> leaseList, List<SltAgreementInfo> repairList,
                                                    List<SltAgreementInfo> scrapList, List<SltAgreementInfo> loseList,
                                                    List<SltAgreementInfo> list) {
        List<SltAgreementRelation> relations = new ArrayList<>();
        for (SltAgreementInfo info : list) {
            SltAgreementRelation relation = new SltAgreementRelation();
            BigDecimal loseCost = BigDecimal.ZERO;
            BigDecimal leaseCost = BigDecimal.ZERO;
            BigDecimal scrapCost = BigDecimal.ZERO;
            BigDecimal repairCost = BigDecimal.ZERO;
            for (SltAgreementInfo lease : leaseList) {
                if (lease.getAgreementId().equals(info.getAgreementId().toString())) {
                    relation.setAgreementId(String.valueOf(lease.getAgreementId()));
                    relation.setProjectName(lease.getProjectName());
                    relation.setUnitName(lease.getUnitName());
                    relation.setCompanyId(lease.getCompanyId());
                    BigDecimal cost = lease.getCosts();
                    leaseCost = leaseCost.add(cost);
                }
            }
            for (SltAgreementInfo repair : repairList) {
                if (repair.getAgreementId().equals(info.getAgreementId().toString())) {
                    BigDecimal cost = repair.getCosts();
                    repairCost = repairCost.add(cost);
                }
            }
            for (SltAgreementInfo scrap : scrapList) {
                if (scrap.getAgreementId().equals(info.getAgreementId().toString())) {
                    BigDecimal cost = scrap.getCosts();
                    scrapCost = scrapCost.add(cost);
                }
            }
            for (SltAgreementInfo lose : loseList) {
                if (lose.getAgreementId().equals(info.getAgreementId().toString())) {
                    //TODO 上面已经set过值，这里为什么还要set值
                    relation.setAgreementId(String.valueOf(lose.getAgreementId()));
                    relation.setProjectName(lose.getProjectName());
                    relation.setUnitName(lose.getUnitName());
                    relation.setCompanyId(lose.getCompanyId());
                    BigDecimal cost = lose.getCosts();
                    loseCost = loseCost.add(cost);
                }
            }
            relation.setLeaseCost(leaseCost);
            relation.setRepairCost(repairCost);
            relation.setScrapCost(scrapCost);
            relation.setLoseCost(loseCost);
            relations.add(relation);
        }
        return relations;
    }
}
