package com.jeequan.jeepay.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.service.mapper.DivisionSubjectMapper;
import com.jeequan.jeepay.service.mapper.DivisionTaskMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

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

/**
 * <p>
 * 用户分账模板表 服务实现类
 * </p>
 *
 * @author [mybatis plus generator]
 * @since 2024-04-02
 */
@Service
public class DivisionTaskService extends ServiceImpl<DivisionTaskMapper, DivisionTask>{

    @Autowired
    private DivisionConnService divisionConnService;

    @Autowired
    private MchStoreService mchStoreService;

    @Autowired
    private DivisionSubjectMapper divisionSubjectMapper;

    /**
     * 分页查询
     * @param iPage
     * @param entity
     * @return
     */
    public IPage<DivisionTask> pageList(Page<DivisionTask> iPage, DivisionTask entity) {
        LambdaQueryWrapper<DivisionTask> wrapper = DivisionTask.gw(entity);
        wrapper.orderByDesc(DivisionTask::getUpdatedAt);
        // 时间范围条件
        entity.buildQueryDateRange();
        return baseMapper.pageList(iPage,entity);
    }

    /**
     * 新增分账模板
     * @param task
     */
    @Transactional(rollbackFor = Exception.class)
    public void addSave(DivisionTask task) {
        task.preCheck();
        DivisionTask autoTask = getAutoTask(task.getIfCode());
        if(autoTask != null){
            throw new BizException("每个通道只能有一个自动分账任务");
        }
        checkDivision(task.getDivisionList(),task.getReceiveList());
        save(task);
        List<DivisionConn> list = new ArrayList<>();
        for (String division:task.getDivisionList()) {
            for (DivisionSubject subject:task.getReceiveList()) {
                DivisionConn divisionConn = new DivisionConn();
                divisionConn.setDivisionNo(division);
                divisionConn.setTaskId(task.getTaskId());
                divisionConn.setReceiveNo(subject.getDivisionNo());
                divisionConn.setDivisionValue(subject.getDivisionValue());
                divisionConn.setIsCharge(subject.getIsCharge());
                list.add(divisionConn);
            }
        }
        try {
            divisionConnService.saveOrUpdateBatch(list);
        }catch (Exception e){
            throw new BizException("分账接收方明细中不能包含两个相同的分账接收方");
        }
    }

    /**
     * 检查分账参数
     * @param divisionList
     * @param receiveList
     */
    public void checkDivision(List<String> divisionList, List<DivisionSubject> receiveList) {
        for (String storeId:divisionList) {
            MchStore store = mchStoreService.getById(storeId);
            Assert.notNull(store,"门店信息异常");
        }
        BigDecimal ratio = BigDecimal.ZERO;
        int count = 0;
        for (DivisionSubject subject:receiveList) {
            DivisionSubject ext = divisionSubjectMapper.selectById(subject.getDivisionNo());
            Assert.notNull(ext,"分账方收款方信息不存在或分账收款方账号有误");
            ratio = ratio.add(subject.getDivisionValue());
            if(CS.YES == subject.getIsCharge()){
                count++;
            }
        }
        if(count > 1){
            throw new BizException("分账详情中是否手收取手续费一方有且只有一个");
        }
        if(ratio.compareTo(DivisionTask.DEFAULT_MAX_RATIO) > 0){
            throw new BizException("分账详情分账比例之和不允许超过30%");
        }
    }

    /**
     * 获取自动分账任务对象
     * @param ifCode
     * @return
     */
    public DivisionTask getAutoTask(String ifCode) {
        List<DivisionTask> list = list(DivisionTask.gw().eq(DivisionTask::getIfCode, ifCode).eq(DivisionTask::getIsAuto, CS.YES));
        if(list.isEmpty()){
            return null;
        }
        return list.get(0);
    }

    /**
     * 获取分账对象详情
     * @param taskId
     * @return
     */
    public DivisionTask getDivisionSubject(String taskId) {
        DivisionTask task = baseMapper.selectById(taskId);
        if(task == null){
            throw new BizException("数据异常");
        }
        return task;
    }

    /**
     * 新增绑定
     * @param task
     */
    public void saveBindSubject(DivisionTask task) {
        task.preSubjectCheck();
        DivisionTask ext = baseMapper.selectById(task.getTaskId());
        if(ext == null){
            throw new BizException("模板数据异常");
        }
        switch (ext.getDivisionMode()){
            case DivisionTask.DIV_MODE_RATIO:
                task.checkDivisionRationValue(ext);
                break;
            case DivisionTask.DIV_MODE_AMOUNT:
                task.checkDivisionAmountValue(ext);
                break;
            default:
                throw new BizException("未知的分账模式");
        }
        List<DivisionSubject> receiveList = task.getReceiveList();
        List<DivisionConn> connList = new ArrayList<>(receiveList.size());
        for (DivisionSubject receive:receiveList) {
            DivisionConn conn = new DivisionConn();
            conn.setTaskId(ext.getTaskId());
            conn.setDivisionNo(receive.getDivisionNo());
            conn.setDivisionValue(receive.getDivisionValue());
            conn.setIsCharge(receive.getIsCharge());
            connList.add(conn);
        }
        divisionConnService.saveOrUpdateBatch(connList);
    }
}
