package com.ycwl.basic.biz;

import cn.hutool.core.date.DateUtil;
import com.ycwl.basic.clickhouse.service.StatsQueryService;
import com.ycwl.basic.mapper.BrokerMapper;
import com.ycwl.basic.mapper.BrokerRecordMapper;
import com.ycwl.basic.mapper.StatisticsMapper;
import com.ycwl.basic.model.pc.broker.entity.BrokerRecord;
import com.ycwl.basic.model.pc.broker.resp.BrokerRespVO;
import com.ycwl.basic.model.pc.order.entity.OrderEntity;
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
import com.ycwl.basic.repository.OrderRepository;
import com.ycwl.basic.repository.ScenicRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Component
public class BrokerBiz {
    @Autowired
    private BrokerMapper brokerMapper;
    @Autowired
    private BrokerRecordMapper brokerRecordMapper;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private ScenicRepository scenicRepository;
    @Autowired
    private StatsQueryService statsQueryService;

    public void processOrder(Long orderId) {
        log.info("开始处理订单分佣，订单ID：{}", orderId);
        OrderEntity order = orderRepository.getOrder(orderId);
        if (order == null) {
            log.info("订单不存在，订单ID：{}", orderId);
            return;
        }
        ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(order.getScenicId());
        if (scenicConfig == null) {
            log.info("景区不存在，订单ID：{}", orderId);
            return;
        }
        int expireDay = 3;
        if (scenicConfig.getInteger("sample_store_day") != null) {
            expireDay = scenicConfig.getInteger("sample_store_day");
        }
        List<Long> brokerIdList = statsQueryService.getBrokerIdListForUser(order.getMemberId(), DateUtil.offsetDay(DateUtil.beginOfDay(order.getCreateAt()), -expireDay), order.getCreateAt());
        if (brokerIdList == null || brokerIdList.isEmpty()) {
            log.info("用户与推客无关，订单ID：{}", orderId);
            return;
        }
        Long directBrokerId = brokerIdList.getFirst();
        List<BrokerRespVO> brokerInfoList = brokerIdList.stream().map(brokerId -> {
            BrokerRespVO broker = brokerMapper.getById(brokerId);
            if (broker == null) {
                return null;
            }
            if (Integer.valueOf(0).equals(broker.getStatus())) {
                return null;
            }
            if (Integer.valueOf(0).equals(broker.getBrokerEnable())) {
                return null;
            }
            return broker;
        }).filter(Objects::nonNull).collect(Collectors.toList());
        boolean hasDirectBroker = brokerInfoList.stream().anyMatch(item -> directBrokerId.equals(item.getId()));
        log.info("订单分佣，订单ID：{}，佣金列表：{}", orderId, brokerInfoList);
        if (brokerInfoList.isEmpty()) {
            log.info("佣金列表为空，订单ID：{}", orderId);
            return;
        }
        List<BrokerRecord> brokerRecordList = new ArrayList<>();
        if (brokerInfoList.size() == 1) {
            // 直接算佣金
            String reason = "单人提成：";
            BrokerRespVO broker = brokerInfoList.getFirst();
            BrokerRecord brokerRecord = new BrokerRecord();
            brokerRecord.setBrokerId(broker.getId());
            brokerRecord.setOrderId(orderId);
            if (broker.getBrokerRate() == null) {
                reason += "提成比例为空！";
                brokerRecord.setBrokerRate(BigDecimal.ZERO);
            }
            brokerRecord.setOrderPrice(order.getPayPrice());
            brokerRecord.setBrokerRate(broker.getBrokerRate());
            BigDecimal brokerRate = brokerRecord.getBrokerRate();
            BigDecimal brokerPrice = order.getPayPrice().multiply(brokerRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
            brokerRecord.setDirectPrice(order.getPayPrice());
            brokerRecord.setBrokerPrice(brokerPrice);
            reason += "金额：" + order.getPayPrice() + "元，提成比例：" + brokerRate + "%，提成金额：" + brokerPrice + "元";
            brokerRecord.setReason(reason);
            brokerRecordList.add(brokerRecord);
        } else {
            BrokerRespVO broker = brokerInfoList.getFirst();
            BigDecimal realRate = broker.getBrokerRate();
            BigDecimal brokerPrice = order.getPayPrice().multiply(realRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
            // todo 需要计算实际提成比例
            BigDecimal firstRate = scenicConfig.getBigDecimal("broker_direct_rate");
            if (firstRate == null) {
                firstRate = BigDecimal.ZERO;
            }
            BigDecimal secondRate = BigDecimal.valueOf(100).subtract(firstRate).divide(BigDecimal.valueOf(hasDirectBroker ? (brokerInfoList.size() - 1) : brokerInfoList.size()), 2, RoundingMode.DOWN);
            for (BrokerRespVO item : brokerInfoList) {
                String reason = "多人提成：支付金额：" + order.getPayPrice() + "元，可提成比例：" + realRate + "%，可提成金额：" + brokerPrice + "：";
                BrokerRecord brokerRecord = new BrokerRecord();
                brokerRecord.setBrokerId(item.getId());
                brokerRecord.setOrderId(orderId);
                BigDecimal interBrokerRate;
                if (directBrokerId.equals(item.getId())) {
                    interBrokerRate = firstRate;
                    reason += "直接提成，";
                    brokerRecord.setDirectPrice(order.getPayPrice());
                } else {
                    interBrokerRate = secondRate;
                    brokerRecord.setDirectPrice(BigDecimal.ZERO);
                }
                brokerRecord.setOrderPrice(order.getPayPrice());
                brokerRecord.setBrokerRate(interBrokerRate.multiply(realRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN));
                BigDecimal interBrokerPrice = brokerPrice.multiply(interBrokerRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
                brokerRecord.setBrokerPrice(interBrokerPrice);
                reason += "二次提成比例：" + interBrokerRate + "%，提成金额：" + interBrokerPrice + "元";
                brokerRecord.setReason(reason);
                brokerRecordList.add(brokerRecord);
            }
        }
        if (!hasDirectBroker) {
            String reason = "提成：金额：" + order.getPayPrice() + "元：直接收益，但是不参与提成";
            BrokerRespVO directBroker = brokerMapper.getById(directBrokerId);
            BrokerRecord brokerRecord = new BrokerRecord();
            brokerRecord.setBrokerId(directBroker.getId());
            brokerRecord.setOrderId(orderId);
            brokerRecord.setDirectPrice(order.getPayPrice());
            brokerRecord.setOrderPrice(order.getPayPrice());
            brokerRecord.setBrokerRate(BigDecimal.ZERO);
            brokerRecord.setBrokerPrice(BigDecimal.ZERO);
            brokerRecord.setReason(reason);
            brokerRecordList.add(brokerRecord);
        }
        revokeOrder(orderId);
        brokerRecordList.forEach(brokerRecordMapper::add);
    }

    public void revokeOrder(Long orderId) {
        brokerRecordMapper.deleteByOrderId(orderId);
    }
}
