package com.starry.admin.common.task;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.starry.admin.modules.clerk.module.entity.PlayClerkUserInfoEntity;
import com.starry.admin.modules.clerk.module.entity.PlayClerkWagesDetailsInfoEntity;
import com.starry.admin.modules.clerk.module.entity.PlayClerkWagesInfoEntity;
import com.starry.admin.modules.clerk.service.IPlayClerkUserInfoService;
import com.starry.admin.modules.clerk.service.IPlayClerkWagesDetailsInfoService;
import com.starry.admin.modules.clerk.service.IPlayClerkWagesInfoService;
import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity;
import com.starry.admin.modules.order.service.IPlayOrderInfoService;
import com.starry.admin.modules.system.module.entity.SysTenantEntity;
import com.starry.admin.modules.system.service.ISysTenantService;
import com.starry.admin.utils.SecurityUtils;
import com.starry.common.utils.IdUtils;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 订单工资结算
 *
 * @author admin
 * @since 2024/5/28 下午2:42
 **/
@Slf4j
@Component
public class ClerkWagesSettlementTask {


    @Resource
    private IPlayClerkUserInfoService clerkUserInfoService;

    @Resource
    private IPlayOrderInfoService playOrderInfoService;

    @Resource
    private IPlayClerkWagesInfoService playClerkWagesInfoService;

    @Resource
    private IPlayClerkWagesDetailsInfoService playClerkWagesDetailsInfoService;

    /**
     * 每分钟查询未结算订单 如果订单完成时间超过24小时，可进行结算，生成工资
     */
    @Scheduled(cron = "0 0/10 * * * ?")
    public void dailyRanking() {
        // 1、查询所有的租户信息
        List<PlayClerkUserInfoEntity> clerkUserReturnVos = clerkUserInfoService.listAll();
        // 生成每个人的工资信息
        for (PlayClerkUserInfoEntity clerkUserInfo : clerkUserReturnVos) {
            try {
                updateClerkWagesInfo(clerkUserInfo.getId());
            } catch (Exception e) {
                log.error("订单结算异常：" + e.getMessage());
                log.error(e.getMessage(),e);
            }

        }
    }

    /**
     * 活动24小时前完成的订单，对订单进行结算
     *
     * @param clerkId 店员ID
     */
    public void updateClerkWagesInfo(String clerkId) {
        // 获得24小时前完成,并且未结算的订单
        LocalDateTime lastTime = LocalDateTime.now().minusDays(1);
        // 查询当前店员上次结算工资到现在的订单
        List<PlayOrderInfoEntity> orderInfoEntities = playOrderInfoService.listByEndTime(clerkId, lastTime);
        if(CollectionUtils.isEmpty(orderInfoEntities)) return;
        PlayClerkWagesInfoEntity entity = playClerkWagesInfoService.getLastSettlement(clerkId);
        // 更新订单信息
        updateClerkWagesInfo(clerkId, entity == null ? IdUtils.getUuid() : entity.getId(), orderInfoEntities);
    }

    /**
     * 更新最新一次工资统计信息 更新订单记录
     *
     * @param orderInfoEntities 订单列表
     */
    public void updateClerkWagesInfo(String clerkId, String wagesId, List<PlayOrderInfoEntity> orderInfoEntities) {
        // 修改订单状态并且新增订单结算详情
        for (PlayOrderInfoEntity orderInfo : orderInfoEntities) {
            // 修改订单状态
            orderInfo.setOrderSettlementState("1");
            orderInfo.setOrderSettlementTime(LocalDateTime.now());
            playOrderInfoService.update(Wrappers.lambdaUpdate(PlayOrderInfoEntity.class)
                    .eq(PlayOrderInfoEntity::getId, orderInfo.getId())
                    .set(PlayOrderInfoEntity::getOrderSettlementState, "1")
                    .set(PlayOrderInfoEntity::getOrderSettlementTime, LocalDateTime.now()));

            PlayClerkWagesDetailsInfoEntity wagesDetailsInfo = playClerkWagesDetailsInfoService
                    .selectByOrderId(orderInfo.getId());
            if (wagesDetailsInfo == null) {
                wagesDetailsInfo = new PlayClerkWagesDetailsInfoEntity();
                wagesDetailsInfo.setId(IdUtils.getUuid());
            }
            // 新增订单结算详情
            wagesDetailsInfo.setWagesId(wagesId);
            wagesDetailsInfo.setClerkId(clerkId);
            wagesDetailsInfo.setOrderId(orderInfo.getId());
            wagesDetailsInfo.setOrderNo(orderInfo.getOrderNo());
            wagesDetailsInfo.setFinalAmount(orderInfo.getFinalAmount());
            wagesDetailsInfo.setTenantId(orderInfo.getTenantId());
            wagesDetailsInfo.setEstimatedRevenue(orderInfo.getEstimatedRevenue());
            wagesDetailsInfo.setEndOrderTime(orderInfo.getOrderEndTime());
            playClerkWagesDetailsInfoService.saveOrUpdate(wagesDetailsInfo);
        }
        // 新增订单结算信息
        BigDecimal finalAmount = BigDecimal.ZERO;
        Integer orderContinueNumber = 0;
        BigDecimal orderContinueMoney = BigDecimal.ZERO;
        Integer ordersExpiredNumber = 0;
        BigDecimal estimatedRevenue = BigDecimal.ZERO;
        Integer orderNumber = 0;
        LocalDate lastTime = playClerkWagesInfoService.getLastSettlementTime(clerkId);
        for (PlayClerkWagesDetailsInfoEntity entity : playClerkWagesDetailsInfoService.selectByWagesId(wagesId)) {
            PlayOrderInfoEntity orderInfo = playOrderInfoService.selectOrderInfoById(entity.getOrderId());
            finalAmount = finalAmount.add(orderInfo.getFinalAmount());
            orderNumber++;
            estimatedRevenue = estimatedRevenue.add(orderInfo.getEstimatedRevenue());
            if ("0".equals(orderInfo.getFirstOrder())) {
                orderContinueNumber++;
                orderContinueMoney = orderContinueMoney.add(orderInfo.getFinalAmount());
            }
            if ("1".equals(orderInfo.getOrdersExpiredState())) {
                ordersExpiredNumber++;
            }
        }

        PlayClerkWagesInfoEntity wagesInfo = new PlayClerkWagesInfoEntity();
        wagesInfo.setId(wagesId);
        wagesInfo.setClerkId(clerkId);
        wagesInfo.setStartCountDate(lastTime);
        wagesInfo.setEndCountDate(LocalDate.now());
        wagesInfo.setOrderNumber(orderNumber);
        wagesInfo.setFinalAmount(finalAmount);
        wagesInfo.setOrderContinueNumber(orderContinueNumber);
        wagesInfo.setOrderContinueMoney(orderContinueMoney);
        wagesInfo.setTenantId(orderInfoEntities.get(0).getTenantId());
        wagesInfo.setOrdersExpiredNumber(ordersExpiredNumber);
        wagesInfo.setSettlementDate(LocalDate.now());
        wagesInfo.setEstimatedRevenue(estimatedRevenue);
        if (ChronoUnit.DAYS.between(LocalDate.now(), lastTime) <= 7) {
            wagesInfo.setHistoricalStatistics("0");
        } else {
            wagesInfo.setHistoricalStatistics("1");
        }

        playClerkWagesInfoService.saveOrUpdate(wagesInfo);
    }
}
