package com.pusong.business.service.approver.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pusong.business.domain.PsApproverRecord;
import com.pusong.business.domain.PsContractPay;
import com.pusong.business.domain.bo.PsApproverRecordBo;
import com.pusong.business.domain.vo.PsApproverRecordVo;
import com.pusong.business.domain.vo.PsCompanyInfoVo;
import com.pusong.business.domain.vo.PsContractPayVo;
import com.pusong.business.enums.ApproverStatusEnum;
import com.pusong.business.enums.ApproverTypeEnum;
import com.pusong.business.enums.PayStatusEnum;
import com.pusong.business.mapper.PsApproverRecordMapper;
import com.pusong.business.mapper.PsContractPayMapper;
import com.pusong.business.service.IPsApproverRecordService;
import com.pusong.business.service.IPsCompanyInfoService;
import com.pusong.business.service.approver.ApproverContainer;
import com.pusong.business.service.approver.ApproverService;
import com.pusong.common.core.exception.ServiceException;
import com.pusong.common.core.utils.DateUtils;
import com.pusong.common.core.utils.StringUtils;
import com.pusong.common.mybatis.core.page.PageQuery;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 审批记录Service接口
 *
 * @author wls
 * @date 2024-08-05
 */
public abstract class ApproverAbstractServiceImpl implements ApproverService {
    @Resource
    private PsApproverRecordMapper approverRecordMapper;
    @Resource
    private ApproverContainer approverContainer;
    @Resource
    private PsApproverRecordMapper recordMapper;
    @Resource
    private  PsContractPayMapper baseMapper;
    @Resource
    private IPsCompanyInfoService companyInfoService;
    /**
     * 通用申请方法
     * @param bussinessId
     * @param desc
     * @param updateData
     */
   public void apply(String bussinessId, String contractCode, String desc, String updateData){
        //退款,回款审批时用 合同编号进行查询校验
       LambdaQueryWrapper<PsApproverRecord> wq = Wrappers.<PsApproverRecord>lambdaQuery().eq(PsApproverRecord::getDelFlag, "0")
               .eq(PsApproverRecord::getBusinessType, approverType())
               .eq(PsApproverRecord::getApproverStatus, ApproverStatusEnum.INIT.getCode());
       if(StringUtils.equals(approverType(), ApproverTypeEnum.RETURN.getCode()) || StringUtils.equals(approverType(), ApproverTypeEnum.PAY.getCode())){
           wq.eq(PsApproverRecord::getContractCode,contractCode);
       }else{
           wq.eq(PsApproverRecord::getBusinessId,bussinessId);
       }
       List<PsApproverRecord> list = approverRecordMapper.selectList(wq);
       if(CollectionUtils.isNotEmpty(list)){
           throw new ServiceException("已存在同类型审批，请勿重复提交");
       }

       PsApproverRecord record = new PsApproverRecord();
       record.setBusinessId(bussinessId);
       record.setContractCode(contractCode);
       record.setBusinessType(approverType());
       record.setApplyDesc(desc);
       record.setUpdateData(updateData);
       record.setApplyDate(new Date());
       record.setApproverStatus(ApproverStatusEnum.INIT.getCode());
       approverRecordMapper.insert(record);

   }

    protected abstract String approverType();
    @PostConstruct
    public void register() {
        approverContainer.registerService(approverType(), this);
    }

    /**
     * 查询列表
     */
    @Override
    public Page<PsApproverRecordVo> queryList(PsApproverRecordBo bo, PageQuery pageQuery){
        QueryWrapper<PsApproverRecord> lqw = Wrappers.<PsApproverRecord>query().eq("app.business_type",approverType())
                .eq(bo.getId()!=null,"app.id",bo.getId())
                .eq("app.del_flag","0")
                .eq(StringUtils.isNotBlank(bo.getApproverStatus()),"app.approver_status",bo.getApproverStatus())
                .like(StringUtils.isNotBlank(bo.getCustomerName()),"cus.custom_name",bo.getCustomerName())
                .like(StringUtils.isNotBlank(bo.getCompanyName()),"com.company_name",bo.getCompanyName())
                .like(StringUtils.isNotBlank(bo.getContractCode()),"app.contract_code",bo.getContractCode())
                //销售经理姓名
                .exists(StringUtils.isNotBlank(bo.getCustomManagerName()),"select 1 from sys_user su where su.user_id = info.custom_manager and su.nick_name like '%"+bo.getCustomManagerName()+"%'")
                .orderByAsc("app.approver_status").orderByDesc("app.apply_date");

        if (ApproverTypeEnum.PAY.getCode().equals( bo.getBusinessType()) || ApproverTypeEnum.RETURN.getCode().equals( bo.getBusinessType()) ){
            if (bo.getPay() == null){
                bo.setPay("1");
            }
        }
        Page<PsApproverRecordVo> res = recordMapper.selectPageApproverList(pageQuery.build(), lqw, bo.getPay());

        if(CollectionUtils.isNotEmpty(res.getRecords())){
            res.getRecords().forEach(item->{
                if (item.getContractAmount() != null)
                    item.setResidualMoney(item.getContractAmount().subtract(item.getPayMoney()));
                //装填回款周期
                List<PsContractPayVo> payList = queryListByContractCode(item.getContractCode(),"1", PayStatusEnum.SUCCESS);
                if(CollectionUtils.isNotEmpty(payList)){
                    item.setPeriod(DateUtils.calWorkDate(payList.get(0).getPayDate(),payList.get(payList.size()-1).getPayDate()));
                }
                //装填服务公司信息
                List<PsCompanyInfoVo> list = companyInfoService.getServiceCompany(item.getContractCode());
                item.setServicePsCompanyInfoVo(list);
            });
        }
        return res;
    }



    /**
     * 查询合同回款记录列表
     *
     * @param contractCode        合同编码
     * @return
     */
    public List<PsContractPayVo> queryListByContractCode(String contractCode, String business, PayStatusEnum enu){
        if(StringUtils.isBlank(contractCode)){return new ArrayList<>();}
        List<PsContractPayVo> list = baseMapper.selectVoList(Wrappers.<PsContractPay>lambdaQuery().
                eq(PsContractPay::getContractCode, contractCode).eq(PsContractPay::getDelFlag,0)
                .eq(StringUtils.isNotBlank(business),PsContractPay::getBusinessType,business)
                .eq(enu != null ,PsContractPay::getPayStatus, enu.getCode())
                .notIn(PsContractPay::getPayStatus, PayStatusEnum.getStatus())//去掉无用的状态
                .orderByAsc(PsContractPay::getPayDate));
        return list == null?new ArrayList<>():list;
    }
}
