package com.czg.service.order.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.czg.config.RedisCst;
import com.czg.order.entity.OrderInfo;
import com.czg.order.service.OrderInfoService;
import com.czg.utils.PageUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.czg.order.entity.ShopTableOrderStatistic;
import com.czg.order.service.ShopTableOrderStatisticService;
import com.czg.service.order.mapper.ShopTableOrderStatisticMapper;
import jakarta.annotation.Resource;
import lombok.Data;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;

/**
 * 台桌订单统计表 服务层实现。
 *
 * @author zs
 * @since 2025-03-07
 */
@Service
public class ShopTableOrderStatisticServiceImpl extends ServiceImpl<ShopTableOrderStatisticMapper, ShopTableOrderStatistic> implements ShopTableOrderStatisticService{
    @Resource
    private OrderInfoService orderInfoService;

    @Override
    public Page<ShopTableOrderStatistic> summary(Long shopId, String startTime, String endTime) {
        Page<Object> page = PageUtil.buildPage();
        PageHelper.startPage(Math.toIntExact(page.getPageNumber()),Math.toIntExact(page.getPageSize()));
        return PageUtil.convert(new PageInfo<>(mapper.selectSummary(shopId, startTime, endTime)));
    }

    @Override
    public boolean addInfo(long shopId, long tableId, long count, BigDecimal amount) {
            ShopTableOrderStatistic statistic = getOne(new QueryWrapper().eq(ShopTableOrderStatistic::getShopId, shopId).eq(ShopTableOrderStatistic::getTableId, tableId)
                    .eq(ShopTableOrderStatistic::getCreateDay, DateUtil.date().toDateStr()));
            if (statistic == null) {
                statistic = new ShopTableOrderStatistic();
                statistic.setShopId(shopId);
                statistic.setTableId(tableId);
                statistic.setCreateDay(DateUtil.date().toSqlDate());
                statistic.setOrderCount(count);
                statistic.setOrderAmount(amount);
                save(statistic);
            }
            return mapper.incrInfo(shopId, tableId, count, amount, DateUtil.date().toDateStr());
    }

    @Data
    private static class StatisticTask{
        private long successCount = 0;
        private BigDecimal successAmount = BigDecimal.ZERO;
        private long refundCount = 0;
        private BigDecimal refundAmount = BigDecimal.ZERO;
    }

    @Override
    public void statistic() {
        // 获取前一天
        DateTime yesterday = DateUtil.yesterday();

        // 获取前一天的开始时间（00:00:00）
        DateTime startOfDay = DateUtil.beginOfDay(yesterday);

        // 获取前一天的结束时间（23:59:59）
        DateTime endOfDay = DateUtil.endOfDay(yesterday);
        List<OrderInfo> orderInfos = orderInfoService.list(new QueryWrapper()
                .ge(OrderInfo::getCreateTime, startOfDay)
                .le(OrderInfo::getCreateTime, endOfDay)
                .ne(OrderInfo::getStatus, "unpaid").ne(OrderInfo::getStatus, "cancelled"));

        HashMap<Long, StatisticTask> countInfo = new HashMap<>();
        for (OrderInfo item : orderInfos) {
            StatisticTask statisticTask = countInfo.get(item.getShopId());
            if (statisticTask == null) {
                countInfo.put(item.getShopId(), statisticTask = new StatisticTask());
            }
            if ("refunding".equals(item.getStatus()) || "refund".equals(item.getStatus()) || "part-refund".equals(item.getStatus())) {
                statisticTask.setRefundAmount(statisticTask.getRefundAmount().add(item.getRefundAmount()));
                statisticTask.setRefundCount(statisticTask.getRefundCount() + 1);
                if (item.getRefundAmount().compareTo(item.getPayAmount()) < 0) {
                    statisticTask.setSuccessAmount(statisticTask.getSuccessAmount().add(item.getPayAmount().subtract(item.getRefundAmount())));
                }
            }else {
                statisticTask.setSuccessCount(statisticTask.getSuccessCount() + 1);
                statisticTask.setSuccessAmount(statisticTask.getSuccessAmount().add(item.getPayAmount()));
            }
        }

        countInfo.forEach((shopId, statisticTask) -> {
            ShopTableOrderStatistic statistic = getOne(new QueryWrapper().eq(ShopTableOrderStatistic::getShopId, shopId).eq(ShopTableOrderStatistic::getCreateDay, yesterday.toSqlDate()));
            if (statistic == null) {
                statistic = new ShopTableOrderStatistic();
                statistic.setShopId(shopId);
                statistic.setTableId(0L);
                statistic.setCreateDay(yesterday.toSqlDate());
            }
            statistic.setOrderCount(statisticTask.getSuccessCount());
            statistic.setOrderAmount(statisticTask.getSuccessAmount());
            statistic.setRefundCount(statisticTask.getRefundCount());
            statistic.setRefundAmount(statisticTask.getRefundAmount());
            saveOrUpdate(statistic);
        });

    }

}
