package com.ruoyi.bst.bonus.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.bst.area.domain.AreaVO;
import com.ruoyi.bst.areaJoin.domain.AreaJoinVO;
import com.ruoyi.bst.areaJoin.domain.enums.AreaJoinType;
import com.ruoyi.bst.areaJoin.service.AreaJoinService;
import com.ruoyi.bst.bonus.domain.Bonus;
import com.ruoyi.bst.bonus.domain.enums.BonusArrivalType;
import com.ruoyi.bst.bonus.domain.enums.BonusBstType;
import com.ruoyi.bst.bonus.domain.enums.BonusStatus;
import com.ruoyi.bst.bonus.service.BonusConverter;
import com.ruoyi.bst.bonus.utils.BonusUtil;
import com.ruoyi.bst.channel.domain.ChannelVO;
import com.ruoyi.bst.channel.domain.enums.ChannelType;
import com.ruoyi.bst.device.domain.DeviceVO;
import com.ruoyi.bst.order.domain.Order;
import com.ruoyi.bst.order.domain.bo.OrderCreateBO;
import com.ruoyi.bst.vipOrder.domain.VipOrder;
import com.ruoyi.bst.vipOrder.domain.bo.VipOrderCreateBO;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.MathUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.collection.CollectionUtils;

@Service
public class BonusConverterImpl implements BonusConverter {

    @Autowired
    private AreaJoinService areaJoinService;

    @Override
    public List<Bonus> toBonusList(OrderCreateBO bo) {
        if (bo == null) {
            return Collections.emptyList();
        }

        ChannelVO channel = bo.getChannel();
        if (channel == null) {
            return Collections.emptyList();
        }

        // 加盟信息，当车辆归属用户不是当前运营区的运营商时，才有加盟信息
        DeviceVO device = bo.getDevice();
        if (device != null && device.getMchId() != null && !Objects.equals(device.getMchId(), device.getAreaUserId())) {
            AreaJoinVO areaJoin = areaJoinService.selectByUserArea(device.getMchId(), device.getAreaId());
            bo.setAreaJoin(areaJoin);
        }

        // 获取基础分成列表
        boolean isPlatform = ChannelType.PLATFORM.getType().equals(channel.getType());
        List<Bonus> result = toBaseBonusListPlatform(bo.getDevice(), bo.getPartners(), bo.getAreaJoin(), isPlatform);

        // 设置业务数据
        Order order = bo.getOrder();
        String reason = "订单收入:" + order.getNo();
        for (Bonus bonus : result) {
            bonus.setReason(reason);
            bonus.setBstType(BonusBstType.ORDER.getType());
            bonus.setBstId(order.getId());
            bonus.setStatus(BonusStatus.INVALID.getStatus());
            bonus.setToBalance(isPlatform);
            bonus.setAreaId(order.getAreaId());
            if (channel != null) {
                bonus.setChannelId(channel.getChannelId());
            }
        }
        
        return result;
    }

    /**
     * 获取基础分成列表
     *
     * @param device   设备
     * @param partners 运营区合伙人列表
     * @param join     设备的所属用户在对应区域的加盟信息
     */
    @Override
    public List<Bonus> toBaseBonusListPlatform(DeviceVO device, List<AreaJoinVO> partners, AreaJoinVO join, boolean isPlatform) {
        if (device == null) {
            return Collections.emptyList();
        }

        Long areaUserId = device.getAreaUserId(); // 运营区归属用户(运营商)
        Long areaAgentId = device.getAreaAgentId(); // 运营区代理商
        BigDecimal totalPoint = BigDecimal.ZERO; // 已分成百分比
        List<Bonus> result = new ArrayList<>();

        // 处理加盟分成：车是加盟商的，且加盟方式为加盟商
        if (join != null && Objects.equals(device.getMchId(), join.getUserId())
                && AreaJoinType.JOIN.getCode().equals(join.getType())) {
            // 加盟商分成
            BonusUtil.addBonus(result, BonusArrivalType.JOIN, join.getUserId(), join.getUserName(),
                    join.getPoint(), Arrays.asList(areaUserId, areaAgentId));
        }
        // 处理合伙人分成：车不是加盟商的，且运营区有合伙人
        else if (CollectionUtils.isNotEmptyElement(partners)) {
            List<Long> viewUserIds = Arrays.asList(areaUserId, areaAgentId);
            BonusUtil.addPartnerBonus(result, partners, viewUserIds);
        }

        // 运营商分成
        if (areaUserId != null && device.getAreaUserPoint() != null) {
            totalPoint = BonusUtil.sumPoint(result);
            BonusUtil.addBonus(result, BonusArrivalType.MCH, areaUserId, device.getAreaUserName(),
                    MathUtils.subtractDecimal(device.getAreaUserPoint(), totalPoint), Arrays.asList(areaAgentId));
        }

        // 代理商分成
        if (areaAgentId != null && device.getAreaAgentPoint() != null) {
            totalPoint = BonusUtil.sumPoint(result);
            BonusUtil.addBonus(result, BonusArrivalType.AGENT, areaAgentId, device.getAreaAgentName(),
                    MathUtils.subtractDecimal(device.getAreaAgentPoint(), totalPoint), Collections.emptyList());
        }

        // 处理平台分成
        this.handlePlatformBonus(result, isPlatform);

        // 判断分成是否正确
        this.checkBonus(result);

        return result;
    }

    /**
     * 处理平台分成
     * 若需要平台分成，则将剩余的分成百分比添加到平台分成中
     * 若不需要平台分成，则将剩余分成按照 代理商、运营商 的顺序添加到分成列表中
     */
    private void handlePlatformBonus(List<Bonus> result, boolean isPlatform) {
        if (result == null) {
            result = new ArrayList<>();
        }

        // 计算剩余分成
        BigDecimal totalPoint = BonusUtil.sumPoint(result);
        BigDecimal surplusPoint = MathUtils.subtractDecimal(new BigDecimal(100), totalPoint);
        if (MathUtils.equals(surplusPoint, BigDecimal.ZERO)) {
            return;
        }

        if (!isPlatform) {
            // 若存在代理商分成，则将剩余分成加入到代理商分成中
            Bonus agent = result.stream().filter(item -> BonusArrivalType.AGENT.getType().equals(item.getArrivalType())).findFirst().orElse(null);
            if (agent != null) {
                agent.setPoint(MathUtils.addDecimal(agent.getPoint(), surplusPoint));
                return;
            }

            // 若存在运营商分成，则将剩余分成加入到运营商分成中
            Bonus mch = result.stream().filter(item -> BonusArrivalType.MCH.getType().equals(item.getArrivalType())).findFirst().orElse(null);
            if (mch != null) {
                mch.setPoint(MathUtils.addDecimal(mch.getPoint(), surplusPoint));
                return;
            }
        }

        // 平台分成
        BonusUtil.addBonus(result, BonusArrivalType.PLATFORM, 1L, "创特科技", surplusPoint, null);
    }

    // 校验分成是否正确
    private void checkBonus(List<Bonus> result) {
        BigDecimal totalPoint = BonusUtil.sumPoint(result);

        if (!MathUtils.equals(totalPoint, new BigDecimal(100))) {
            throw new ServiceException("分成计算错误，总分成百分比不为100%");
        }
        for (Bonus bonus : result) {
            ServiceUtil.assertion(bonus == null, "分成计算错误，分成方数据为空");
            ServiceUtil.assertion(bonus.getArrivalId() == null, "分成计算错误，分成方ID为空");
            ServiceUtil.assertion(bonus.getPoint().compareTo(BigDecimal.ZERO) < 0, "分成计算错误，分成方【%s】分成百分比为负数",
                    bonus.getArrivalName());
        }
    }

    @Override
    public List<Bonus> toBonusList(VipOrderCreateBO bo) {
        
        if (bo == null) {
            return Collections.emptyList();
        }
        ChannelVO channel = bo.getChannel();

        // 获取基础分成列表
        boolean isPlatform = ChannelType.PLATFORM.getType().equals(channel.getType());
        List<Bonus> result = toBaseBonusListPlatform(bo.getArea(), bo.getPartners(), isPlatform);

        // 设置业务数据
        VipOrder order = bo.getOrder();
        String reason = "卡券订单收入:" + order.getNo();
        for (Bonus bonus : result) {
            bonus.setReason(reason);
            bonus.setBstType(BonusBstType.VIP_ORDER.getType());
            bonus.setBstId(order.getId());
            bonus.setStatus(BonusStatus.INVALID.getStatus());
            bonus.setToBalance(isPlatform);
            bonus.setAreaId(order.getVipAreaId());
            if (channel != null) {
                bonus.setChannelId(channel.getChannelId());
            }
        }

        return result;
    }

    // 获取基础分成列表
    private List<Bonus> toBaseBonusListPlatform(AreaVO area, List<AreaJoinVO> partners, boolean isPlatform) {
        List<Bonus> result = new ArrayList<>();

        // 运营区
        if (area == null) {
            return Collections.emptyList();
        }
        BigDecimal totalPoint = BigDecimal.ZERO; // 已分成百分比

        // 合伙人分成
        BonusUtil.addPartnerBonus(result, partners, Arrays.asList(area.getUserId(), area.getAgentId()));

        // 运营商分成
        if (area.getUserId() != null && area.getUserPoint() != null) {
            totalPoint = BonusUtil.sumPoint(result);
            BonusUtil.addBonus(result, BonusArrivalType.MCH, area.getUserId(), area.getUserName(),
                    MathUtils.subtractDecimal(area.getUserPoint(), totalPoint), Arrays.asList(area.getAgentId()));
        }

        // 代理商分成
        if (area.getAgentId() != null && area.getAgentPoint() != null) {
            totalPoint = BonusUtil.sumPoint(result);
            BonusUtil.addBonus(result, BonusArrivalType.AGENT, area.getAgentId(), area.getAgentName(),
                    MathUtils.subtractDecimal(area.getAgentPoint(), totalPoint), Collections.emptyList());
        }

        // 处理平台分成
        this.handlePlatformBonus(result, isPlatform);

        // 判断分成是否正确
        this.checkBonus(result);

        return result;
    }

}
