package com.red.circle.console.app.scheduler;

import com.red.circle.component.redis.annotation.TaskCacheLock;
import com.red.circle.console.infra.database.rds.service.count.StatisticsDailyCurrencyCountPlatformService;
import com.red.circle.console.infra.database.rds.service.count.StatisticsDailyPurchaseAmountPlatformService;
import com.red.circle.console.infra.database.rds.service.count.StatisticsDailyPurchaseAmountService;
import com.red.circle.console.infra.database.rds.service.count.StatisticsDailyRegisterLogoutPlatformService;
import com.red.circle.console.infra.database.rds.service.count.StatisticsDailyRegisterLogoutService;
import com.red.circle.console.infra.database.util.DateFormatEnum;
import com.red.circle.console.infra.database.util.LocalDateUtils;
import com.red.circle.console.infra.database.util.ZonedDateTimeUtils;
import com.red.circle.tool.core.date.LocalDateTimeUtils;
import java.time.LocalDate;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 统计任务.
 *
 * @author pengliang on 2023/3/23
 */
@Slf4j
@Component
@AllArgsConstructor
public class StatisticsTask {

  private final StatisticsDailyRegisterLogoutService statisticsDailyRegisterLogoutService;
  private final StatisticsDailyPurchaseAmountService statisticsDailyPurchaseAmountService;
  private final StatisticsDailyCurrencyCountPlatformService statisticsDailyCurrencyCountPlatformService;
  private final StatisticsDailyPurchaseAmountPlatformService statisticsDailyPurchaseAmountPlatformService;
  private final StatisticsDailyRegisterLogoutPlatformService statisticsDailyRegisterLogoutPlatformService;

  /**
   * 全平台总新增+用户新增情况统计，早上8点执行.
   */
  @Scheduled(cron = "0 0 8 * * ?", zone = "Asia/Shanghai")
  @TaskCacheLock(key = "USER_ADDED_COUNT", expireSecond = 60 * 60)
  public void userAddedCount() {
    log.warn("[userAddedCount] 开始执行统计:系统时间：{}",
        LocalDateTimeUtils.nowFormat(DateFormatEnum.yyyy_MM_dd_HH_mm_ss.getPattern()));

    // 运行前一天， 中国上海时间
    var countTime = countDateAsiaShanghai();
    var countNumber = Integer.parseInt(
        LocalDateUtils.format(countTime, DateFormatEnum.yyyyMMdd));
    var now = nowDateAsiaShanghai();

    log.warn("[userAddedCount] 参数({},{},{})",
        countNumber,
        LocalDateUtils.format(countTime, DateFormatEnum.yyyy_MM_dd),
        LocalDateUtils.format(now, DateFormatEnum.yyyy_MM_dd));

    // 全平台总新增
    statisticsDailyRegisterLogoutService.countUserAdded(
        countNumber,
        countTime,
        now
    );
    log.warn("[userAddedCount] 全平台总新增,完成");

    // 用户新增情况统计
    statisticsDailyRegisterLogoutPlatformService.countUserAdded(
        countNumber,
        countTime,
        now
    );
    log.warn("[userAddedCount] 用户新增情况统计,完成");
  }

  /**
   * 每日内购情况，早上8点执行.
   */
  @Scheduled(cron = "0 0 8 * * ?", zone = "Asia/Shanghai")
  @TaskCacheLock(key = "EVERYDAY_IN_APP_PURCHASE_COUNT", expireSecond = 60 * 60)
  public void everydayInAppPurchaseCount() {
    log.warn("[everydayInAppPurchaseCount] 开始执行统计:系统时间：{}",
        LocalDateTimeUtils.nowFormat(DateFormatEnum.yyyy_MM_dd_HH_mm_ss.getPattern()));

    // 运行前一天， 中国上海时间
    var countTime = countDateAsiaShanghai();
    var countNumber = Integer.parseInt(
        LocalDateUtils.format(countTime, DateFormatEnum.yyyyMMdd));
    var now = nowDateAsiaShanghai();

    log.warn("[everydayInAppPurchaseCount] 参数({},{},{})",
        countNumber,
        LocalDateUtils.format(countTime, DateFormatEnum.yyyy_MM_dd),
        LocalDateUtils.format(now, DateFormatEnum.yyyy_MM_dd));

    // 每日积分收支统计
    statisticsDailyCurrencyCountPlatformService.countIntegral(
        countNumber,
        countTime,
        now
    );
    log.warn("[everydayInAppPurchaseCount] 每日积分收支统计，完成");

    // 统计每日内购/退款
    statisticsDailyPurchaseAmountService.countInAppPurchaseOrRefund(
        countTime,
        now
    );
    log.warn("[everydayInAppPurchaseCount] 统计每日内购/退款，完成");

    // 统计每日内购/退款-区分区域
    statisticsDailyPurchaseAmountService.countInAppPurchaseOrRefundRegion(
        countTime,
        now
    );
    log.warn("[everydayInAppPurchaseCount] 统计每日内购/退款-区分区域，完成");

    // 统计每日内购/退款-区分区域(其他)
    statisticsDailyPurchaseAmountService.countInAppPurchaseOrRefundOther(
        countTime,
        now
    );
    log.warn("[everydayInAppPurchaseCount] 统计每日内购/退款-区分区域(其他)，完成");

    // 统计每日内购-离线充值
    statisticsDailyPurchaseAmountService.countInAppPurchaseOrRefundOffline(
        countTime,
        now
    );
    log.warn("[everydayInAppPurchaseCount] 统计每日内购-离线充值，完成");

    // 统计每日各平台内购情况
    statisticsDailyPurchaseAmountPlatformService.countPurchasePlatform(
        countNumber,
        countTime,
        now
    );
    log.warn("[everydayInAppPurchaseCount] 统计每日各平台内购情况，完成");

    // 统计每日各平台内购情况-区分区域
    statisticsDailyPurchaseAmountPlatformService.countPurchasePlatformRegion(
        countNumber,
        countTime,
        now
    );
    log.warn("[everydayInAppPurchaseCount] 统计每日各平台内购情况-区分区域，完成");

    // 统计每日各平台内购情况-区分区域(其他)
    statisticsDailyPurchaseAmountPlatformService.countPurchasePlatformOther(
        countNumber,
        countTime,
        now
    );
    log.warn("[everydayInAppPurchaseCount] 统计每日各平台内购情况-区分区域(其他)，完成");
  }


  /**
   * 每月内购情况，每月1号8点执行.
   */
  @Scheduled(cron = "0 0 8 1 * ?", zone = "Asia/Shanghai")
  @TaskCacheLock(key = "MONTHLY_IN_APP_PURCHASES_COUNT", expireSecond = 60 * 60)
  public void monthlyInAppPurchases() {
    long startTime = System.currentTimeMillis();
    log.info("exec monthly_in_app_purchases_count start");
    statisticsDailyPurchaseAmountPlatformService.countPurchasePlatformMonth();
    log.info("exec monthly_in_app_purchases_count end with {}",System.currentTimeMillis()-startTime);
  }

  private LocalDate countDateAsiaShanghai() {
    return ZonedDateTimeUtils.nowAsiaShanghai()
        .minusDays(1)
        .toLocalDate();
  }

  private LocalDate nowDateAsiaShanghai() {
    return ZonedDateTimeUtils.nowAsiaShanghai().toLocalDate();
  }

}
