package com.yd.csf.service.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yd.common.constant.CommonConstant;
import com.yd.common.enums.ResultCode;
import com.yd.common.exception.BusinessException;
import com.yd.common.utils.RandomStringGenerator;
import com.yd.csf.service.dto.CommissionExpectedAddDto;
import com.yd.csf.service.dto.CommissionExpectedAddRequest;
import com.yd.csf.service.dto.CommissionExpectedQueryRequest;
import com.yd.csf.service.dto.CommissionExpectedUpdateRequest;
import com.yd.csf.service.enums.CommissionExpectedStatusEnum;
import com.yd.csf.service.model.CommissionExpected;
import com.yd.csf.service.service.CommissionExpectedService;
import com.yd.csf.service.dao.CommissionExpectedMapper;
import com.yd.csf.service.vo.CommissionExpectedVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author Zhang Jianan
* @description 针对表【commission_expected(预计来佣表)】的数据库操作Service实现
* @createDate 2025-10-08 19:47:40
*/
@Service
public class CommissionExpectedServiceImpl extends ServiceImpl<CommissionExpectedMapper, CommissionExpected>
    implements CommissionExpectedService{

    @Override
    public Page<CommissionExpectedVO> getCommissionExpectedVOPage(Page<CommissionExpected> commissionExpectedPage) {
        List<CommissionExpected> CommissionExpectedList = commissionExpectedPage.getRecords();
        Page<CommissionExpectedVO> CommissionExpectedVOPage = new Page<>(commissionExpectedPage.getCurrent(), commissionExpectedPage.getSize(), commissionExpectedPage.getTotal());
        if (CollUtil.isEmpty(CommissionExpectedList)) {
            return CommissionExpectedVOPage;
        }

        // 填充信息
        List<CommissionExpectedVO> CommissionExpectedVOList = CommissionExpectedList.stream().map(CommissionExpectedVO::objToVo).collect(Collectors.toList());
        CommissionExpectedVOPage.setRecords(CommissionExpectedVOList);
        return CommissionExpectedVOPage;
    }

    /**
     * 校验数据
     *
     * @param commissionExpected
     * @param add      对创建的数据进行校验
     */
    @Override
    public void validCommissionExpected(CommissionExpected commissionExpected, boolean add) {
        if (commissionExpected == null) {
            throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "预计来佣对象不能为空");
        }
        String policyNo = commissionExpected.getPolicyNo();
        if (StringUtils.isBlank(policyNo)) {
            throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "保单号不能为空");
        }
        String commissionName = commissionExpected.getCommissionName();
        if (StringUtils.isBlank(commissionName)) {
            throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "来佣名称不能为空");
        }
        BigDecimal commissionRatio = commissionExpected.getCommissionRatio();
        if (ObjectUtils.isEmpty(commissionRatio)) {
            throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "来佣比例不能为空");
        }
        Integer commissionPeriod = commissionExpected.getCommissionPeriod();
        if (ObjectUtils.isEmpty(commissionPeriod)) {
            throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "佣金期数不能为空");
        }
        Integer totalPeriod = commissionExpected.getTotalPeriod();
        if (ObjectUtils.isEmpty(totalPeriod)) {
            throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "总来佣期数不能为空");
        }
        // 创建数据时，参数不能为空
        if (add) {
            // todo 补充校验规则
//            ThrowUtils.throwIf(StringUtils.isBlank(title), ErrorCode.PARAMS_ERROR);
        }
    }

    /**
     * 获取查询条件
     *
     * @param commissionExpectedQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<CommissionExpected> getQueryWrapper(CommissionExpectedQueryRequest commissionExpectedQueryRequest) {
        QueryWrapper<CommissionExpected> queryWrapper = new QueryWrapper<>();
        if (commissionExpectedQueryRequest == null) {
            return queryWrapper;
        }
        // 获取查询参数
        String policyNo = commissionExpectedQueryRequest.getPolicyNo();
        // 精确查询
        queryWrapper.eq(ObjectUtils.isNotEmpty(policyNo), "policy_no", policyNo);
        // 默认排序规则
        queryWrapper.orderByAsc("commission_period");
        // 排序字段
        String sortField = commissionExpectedQueryRequest.getSortField();
        String sortOrder = commissionExpectedQueryRequest.getSortOrder();
        queryWrapper.orderBy(ObjectUtils.isNotEmpty(sortField) && sortField.equals("reconciliation_company"), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        queryWrapper.orderBy(ObjectUtils.isNotEmpty(sortField) && sortField.equals("commission_name"), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        queryWrapper.orderBy(ObjectUtils.isNotEmpty(sortField) && sortField.equals("commission_period"), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        queryWrapper.orderBy(ObjectUtils.isNotEmpty(sortField) && sortField.equals("amount"), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }

    /**
     * 获取预计来佣封装
     *
     * @param commissionExpected
     * @return
     */
    @Override
    public CommissionExpectedVO getCommissionExpectedVO(CommissionExpected commissionExpected) {
        // 对象转封装类
        CommissionExpectedVO commissionExpectedVO = CommissionExpectedVO.objToVo(commissionExpected);

        // todo 可以根据需要为封装对象补充值，不需要的内容可以删除

        return commissionExpectedVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addCommissionExpected(CommissionExpectedAddRequest commissionExpectedAddRequest) {
        List<CommissionExpectedAddDto> addDtoList = commissionExpectedAddRequest.getCommissionExpectedAddDtoList();
        if (CollUtil.isEmpty(addDtoList)) {
            throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "预计来佣列表不能为空");
        }

        List<CommissionExpected> addList = new ArrayList<>();
        List<CommissionExpected> updateList = new ArrayList<>();
        for (CommissionExpectedAddDto addDto : addDtoList) {
            CommissionExpected commissionExpected = new CommissionExpected();
            BeanUtils.copyProperties(addDto, commissionExpected);

            // 校验参数
            validCommissionExpected(commissionExpected, true);

            if (StringUtils.isBlank(addDto.getCommissionExpectedBizId())) {
                // 生成新单编号
                commissionExpected.setCommissionExpectedBizId(RandomStringGenerator.generateBizId16("commission_expected"));
                commissionExpected.setCreateTime(new Date());
                commissionExpected.setUpdateTime(new Date());
                // 设置默认状态
                commissionExpected.setStatus(CommissionExpectedStatusEnum.PENDING.getItemValue());
                addList.add(commissionExpected);
            } else {
                commissionExpected.setUpdateTime(new Date());
                updateList.add(commissionExpected);
            }

        }
        // 新增预计来佣
        if (CollectionUtils.isNotEmpty(addList)) {
            this.saveBatch(addList);
        }
        if (CollectionUtils.isNotEmpty(updateList)) {
            List<String> bizIdList = updateList.stream().map(CommissionExpected::getCommissionExpectedBizId).collect(Collectors.toList());
            List<CommissionExpected> list = this.list(new QueryWrapper<CommissionExpected>().in("commission_expected_biz_id", bizIdList));
            Map<String, CommissionExpected> map = list.stream().collect(Collectors.toMap(CommissionExpected::getCommissionExpectedBizId, a -> a));
            for (CommissionExpected update : updateList) {
                CommissionExpected commissionExpectedFromDb = map.get(update.getCommissionExpectedBizId());
                update.setId(commissionExpectedFromDb.getId());
            }
            this.updateBatchById(updateList);
        }
        return true;
    }

    @Override
    public Boolean deleteCommissionExpected(String commissionExpectedBizId) {
        if (StringUtils.isBlank(commissionExpectedBizId)) {
            throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "预计来佣业务id不能为空");
        }
        // 校验预计来佣是否存在
        CommissionExpected commissionExpected = getByBizId(commissionExpectedBizId);
        if (commissionExpected == null) {
            throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "预计来佣不存在");
        }
        return this.removeById(commissionExpected.getId());
    }

    @Override
    public Boolean updateCommissionExpected(CommissionExpectedUpdateRequest commissionExpectedUpdateRequest) {
        // 校验预计来佣是否存在
        CommissionExpected commissionExpected = getByBizId(commissionExpectedUpdateRequest.getCommissionExpectedBizId());
        if (commissionExpected == null) {
            throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "预计来佣不存在");
        }
        if (commissionExpected.getCommissionRatio() == null) {
            if (commissionExpectedUpdateRequest.getRatio() != null) {
                commissionExpected.setCommissionRatio(commissionExpectedUpdateRequest.getRatio());
            } else {
                commissionExpected.setCommissionRatio(commissionExpectedUpdateRequest.getCommissionRatio());
            }
        }
        // 校验数据
        validCommissionExpected(commissionExpected, false);
        // 转换为实体类
        BeanUtils.copyProperties(commissionExpectedUpdateRequest, commissionExpected);
        if (commissionExpectedUpdateRequest.getRatio() != null) {
            commissionExpected.setCommissionRatio(commissionExpectedUpdateRequest.getRatio());
        } else {
            commissionExpected.setCommissionRatio(commissionExpectedUpdateRequest.getCommissionRatio());
        }
        commissionExpected.setUpdateTime(new Date());
        // 更新预计来佣
        return this.updateById(commissionExpected);
    }

    private CommissionExpected getByBizId(String commissionExpectedBizId) {
        return this.getOne(new QueryWrapper<CommissionExpected>().eq("commission_expected_biz_id", commissionExpectedBizId));
    }
}




