package com.gxwebsoft.shop.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gxwebsoft.common.core.annotation.IgnoreTenant;
import com.gxwebsoft.common.core.enums.ShopDealerCapitalUpdateEnum;
import com.gxwebsoft.common.core.enums.ShopDealerTypeEnum;
import com.gxwebsoft.common.system.redis.OrderNoUtils;
import com.gxwebsoft.shop.dto.ShopDealerSettlementDto;
import com.gxwebsoft.shop.dto.ShopDealerSettlementItemDto;
import com.gxwebsoft.shop.entity.ShopDealerOrder;
import com.gxwebsoft.shop.entity.ShopOrder;
import com.gxwebsoft.shop.mapper.ShopDealerOrderMapper;
import com.gxwebsoft.shop.mapper.ShopOrderMapper;
import com.gxwebsoft.shop.service.ShopDealerOrderService;
import com.gxwebsoft.shop.service.ShopDealerUserService;
import com.gxwebsoft.shop.service.ShopOrderService;
import com.gxwebsoft.shop.vo.ShopDealerOrderTaskVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单结算任务【门店/服务商结算、总分红结算等】
 * @author xm
 * @since 2026-05-15
 */
@Slf4j
@Component
@AllArgsConstructor
public class OrderSettlementTask {

    private ShopDealerOrderMapper shopDealerOrderMapper;

    private ShopDealerOrderService shopDealerOrderService;

    private ShopOrderMapper shopOrderMapper;

    private ShopOrderService shopOrderService;

    private ShopDealerUserService shopDealerUserService;

    private OrderNoUtils orderNoUtils;

    /**
     * 门店、服务商结算任务：每天一点，每10分钟执行一次结算任务
     */
    @Scheduled(cron = "0 0/10 1 * * ?")
    @IgnoreTenant("定时门店、服务商结算任务")
    @Transactional
    public void teamSettlement(){
        //1.查询待结算订单信息
        List<ShopDealerOrderTaskVO> orderTaskVOList = shopDealerOrderMapper.getDealerOrderList(10584);
        if(CollectionUtils.isNotEmpty(orderTaskVOList)){
            LocalDateTime now = LocalDateTime.now();
            List<Integer> orderIdList = orderTaskVOList.stream().map(ShopDealerOrderTaskVO::getOrderId).distinct().collect(Collectors.toList());
            List<Integer> shopDealerIdList = orderTaskVOList.stream().map(ShopDealerOrderTaskVO::getShopDealerOrderId).distinct().collect(Collectors.toList());

            //2.查询商品订单信息
            List<ShopOrder> shopOrderList = shopOrderMapper.selectList(new LambdaQueryWrapper<ShopOrder>().select(ShopOrder::getOrderId, ShopOrder::getTeamSettlementFlag)
                    .in(ShopOrder::getOrderId, orderIdList));

            //3.查询商品订单分销信息
            List<ShopDealerOrder> shopDealerOrderList = shopDealerOrderMapper.selectList(new LambdaQueryWrapper<ShopDealerOrder>().select(ShopDealerOrder::getId, ShopDealerOrder::getOrderNo)
                    .in(ShopDealerOrder::getId, shopDealerIdList));

            //4.结算一级服务商佣金
            Map<Integer, List<ShopDealerOrderTaskVO>> firstDealerMap = orderTaskVOList.stream().collect(Collectors.groupingBy(ShopDealerOrderTaskVO::getFirstDividendUser));
            List<ShopDealerSettlementItemDto> firstSettlementItemDtoList = new ArrayList<>();
            firstDealerMap.forEach((k, value) ->{
                List<Integer> orderIds = value.stream().map(ShopDealerOrderTaskVO::getOrderId).distinct().collect(Collectors.toList());
                List<Integer> shopDealerOrderIds = value.stream().map(ShopDealerOrderTaskVO::getShopDealerOrderId).distinct().collect(Collectors.toList());

                //4.1 标记商品订单为已结算状态
                List<ShopOrder> shopOrders = shopOrderList.stream().filter(shopOrder -> orderIds.contains(shopOrder.getOrderId())).collect(Collectors.toList());
                shopOrders.forEach(shopOrder -> shopOrder.setTeamSettlementFlag(1));

                //4.2 生成分销记录【增加钱包金额】
                BigDecimal firstDividendSum = value.stream().map(ShopDealerOrderTaskVO::getFirstDividend).reduce(BigDecimal.ZERO, BigDecimal::add);
                ShopDealerSettlementItemDto itemDto = new ShopDealerSettlementItemDto();
                String no = orderNoUtils.generate("C");
                itemDto.setNo(no);
                itemDto.setUserId(k);
                itemDto.setMoney(firstDividendSum);
                firstSettlementItemDtoList.add(itemDto);

                //4.3更新商品分销记录对应的一级服务商佣金为已结算状态
                List<ShopDealerOrder> shopDealerOrders = shopDealerOrderList.stream().filter(shopDealerOrder -> shopDealerOrderIds.contains(shopDealerOrder.getId())).collect(Collectors.toList());
                shopDealerOrders.forEach(shopDealerOrder -> {
                    shopDealerOrder.setFirstDividendFlag(1);
                    shopDealerOrder.setFirstDividendNo(no);
                    shopDealerOrder.setFirstDividendTime(now);
                });
            });

            //4.4 一级结算【增加钱包金额】
            if(CollectionUtils.isNotEmpty(firstSettlementItemDtoList)){
                ShopDealerSettlementDto firstSettlementDto = new ShopDealerSettlementDto();
                firstSettlementDto.setType(ShopDealerTypeEnum.WITHDRAW_ACCOUNT.getCode());
                firstSettlementDto.setFlowType(ShopDealerCapitalUpdateEnum.MANAGEMENT_INCOME.getType());
                firstSettlementDto.setComments("团队管理津贴(1)");
                firstSettlementDto.setTenantId(10584);
                firstSettlementDto.setItemList(firstSettlementItemDtoList);
                shopDealerUserService.settlementBatch(firstSettlementDto);
            }

            //5.结算二级服务商佣金
            Map<Integer, List<ShopDealerOrderTaskVO>> secondDealerMap = orderTaskVOList.stream().collect(Collectors.groupingBy(ShopDealerOrderTaskVO::getSecondDividendUser));
            List<ShopDealerSettlementItemDto> secondSettlementItemDtoList = new ArrayList<>();
            secondDealerMap.forEach((k, value) ->{
                List<Integer> orderIds = value.stream().map(ShopDealerOrderTaskVO::getOrderId).distinct().collect(Collectors.toList());
                List<Integer> shopDealerOrderIds = value.stream().map(ShopDealerOrderTaskVO::getShopDealerOrderId).distinct().collect(Collectors.toList());

                //5.1 标记商品订单为已结算状态
                List<ShopOrder> shopOrders = shopOrderList.stream().filter(shopOrder -> orderIds.contains(shopOrder.getOrderId())).collect(Collectors.toList());
                shopOrders.forEach(shopOrder -> shopOrder.setTeamSettlementFlag(1));

                //5.2 生成分销记录【增加钱包金额】
                BigDecimal secondDividendSum = value.stream().map(ShopDealerOrderTaskVO::getSecondDividend).reduce(BigDecimal.ZERO, BigDecimal::add);
                ShopDealerSettlementItemDto itemDto = new ShopDealerSettlementItemDto();
                String no = orderNoUtils.generate("C");
                itemDto.setNo(no);
                itemDto.setUserId(k);
                itemDto.setMoney(secondDividendSum);
                secondSettlementItemDtoList.add(itemDto);

                //5.3 更新商品分销记录对应的一级服务商佣金为已结算状态
                List<ShopDealerOrder> shopDealerOrders = shopDealerOrderList.stream().filter(shopDealerOrder -> shopDealerOrderIds.contains(shopDealerOrder.getId())).collect(Collectors.toList());
                shopDealerOrders.forEach(shopDealerOrder -> {
                    shopDealerOrder.setSecondDividendFlag(1);
                    shopDealerOrder.setSecondDividendNo(no);
                    shopDealerOrder.setSecondDividendTime(now);
                });
            });

            //5.4 二级结算【增加钱包金额】
            if(CollectionUtils.isNotEmpty(secondSettlementItemDtoList)){
                ShopDealerSettlementDto secondSettlementDto = new ShopDealerSettlementDto();
                secondSettlementDto.setType(ShopDealerTypeEnum.WITHDRAW_ACCOUNT.getCode());
                secondSettlementDto.setFlowType(ShopDealerCapitalUpdateEnum.MANAGEMENT_INCOME.getType());
                secondSettlementDto.setComments("团队管理津贴(2)");
                secondSettlementDto.setTenantId(10584);
                secondSettlementDto.setItemList(secondSettlementItemDtoList);
                shopDealerUserService.settlementBatch(secondSettlementDto);
            }

            //6.批量修改订单为已结算状态
            if(CollectionUtils.isNotEmpty(shopOrderList)){
                shopOrderService.updateBatchById(shopOrderList);
            }

            //7.批量修改订单分销数据为已结算状态
            if(CollectionUtils.isNotEmpty(shopDealerOrderList)){
                shopDealerOrderService.updateBatchById(shopDealerOrderList);
            }
        }
    }

}
