package com.izouma.jiashanxia.service;

import com.izouma.jiashanxia.domain.OrderInfo;
import com.izouma.jiashanxia.domain.WxFee;
import com.izouma.jiashanxia.dto.StatisticDTO;
import com.izouma.jiashanxia.enums.OrderInfoStatus;
import com.izouma.jiashanxia.repo.CompanyRepo;
import com.izouma.jiashanxia.repo.OrderInfoRepo;
import com.izouma.jiashanxia.repo.UserRepo;
import com.izouma.jiashanxia.repo.WxFeeRepo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@AllArgsConstructor
public class StatisticService {
    private UserRepo      userRepo;
    private CompanyRepo   companyRepo;
    private OrderInfoRepo orderInfoRepo;
    private WxFeeRepo     wxFeeRepo;

    /*
    数据总揽
     */
    public Map<String, Object> dataOverview() {
        long user = userRepo.count();
        long company = companyRepo.count();
        long order = orderInfoRepo.countByStatus(OrderInfoStatus.PAID);
        BigDecimal fee = wxFeeRepo.sumByAmount();

        Map<String, Object> data = new HashMap<>();
        data.put("user", user);
        data.put("company", company);
        data.put("order", order);
        data.put("fee", fee);
        return data;
    }

    /*
    每日订单折线图
     */
    public List<StatisticDTO> dayData(Integer day) {
        List<StatisticDTO> dtos = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime start = LocalDateTime.of(now.toLocalDate().minusDays(day - 1), LocalTime.MIN);
        List<OrderInfo> orderInfos = orderInfoRepo.findAllByPaidAtBetweenAndStatus(start, now, OrderInfoStatus.PAID);
        List<WxFee> wxFees = wxFeeRepo.findAllByCreatedAtBetween(start, now);

        while (day > 0) {
            LocalDateTime end = start.plusDays(1);
            LocalDateTime finalStart = start;
            long order = orderInfos.stream()
                    .filter(orderInfo -> !finalStart.isAfter(orderInfo.getPaidAt()) && end.isAfter(orderInfo.getPaidAt()))
                    .count();
            BigDecimal fee = wxFees.stream()
                    .filter(wxFee -> !finalStart.isAfter(wxFee.getCreatedAt()) && end.isAfter(wxFee.getCreatedAt()))
                    .map(WxFee::getAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            dtos.add(StatisticDTO.builder()
                    .date(finalStart.toLocalDate())
                    .dayOrder(order)
                    .dayFee(fee)
                    .build());
            day--;
            start = end;
        }
        return dtos;
    }
}
