import { Injectable, Logger } from '@nestjs/common';
import { Decimal } from '@prisma/client/runtime/library';
import { PrismaService } from '../prisma/prisma.service';
import {
  IGlobalStatsRepository,
  GlobalStatsData,
} from '../../../domain/repositories';

@Injectable()
export class GlobalStatsRepository implements IGlobalStatsRepository {
  private readonly logger = new Logger(GlobalStatsRepository.name);
  private readonly GLOBAL_KEY = 'global';

  constructor(private readonly prisma: PrismaService) {}

  async getGlobalStats(): Promise<GlobalStatsData> {
    const stats = await this.prisma.globalStats.findUnique({
      where: { statsKey: this.GLOBAL_KEY },
    });

    if (stats) {
      return this.toDomain(stats);
    }

    // 如果不存在，创建初始记录
    const created = await this.prisma.globalStats.create({
      data: { statsKey: this.GLOBAL_KEY },
    });

    return this.toDomain(created);
  }

  async incrementPlanting(
    treeCount: number,
    amount: Decimal,
  ): Promise<GlobalStatsData> {
    // [2026-01-07] 修复：防御性处理，确保 treeCount 不为 undefined
    const safeTreeCount = treeCount ?? 0;
    const safeAmount = amount ?? new Decimal(0);

    this.logger.debug(
      `Incrementing global planting: trees=${safeTreeCount}, amount=${safeAmount}`,
    );

    const result = await this.prisma.globalStats.upsert({
      where: { statsKey: this.GLOBAL_KEY },
      create: {
        statsKey: this.GLOBAL_KEY,
        totalPlantingCount: safeTreeCount,
        totalOrderCount: 1,
        totalPlantingAmount: safeAmount,
      },
      update: {
        totalPlantingCount: { increment: safeTreeCount },
        totalOrderCount: { increment: 1 },
        totalPlantingAmount: { increment: safeAmount },
      },
    });

    return this.toDomain(result);
  }

  async incrementOrder(): Promise<GlobalStatsData> {
    const result = await this.prisma.globalStats.upsert({
      where: { statsKey: this.GLOBAL_KEY },
      create: {
        statsKey: this.GLOBAL_KEY,
        totalOrderCount: 1,
      },
      update: {
        totalOrderCount: { increment: 1 },
      },
    });

    return this.toDomain(result);
  }

  async incrementUser(): Promise<GlobalStatsData> {
    this.logger.debug('Incrementing global user count');

    const result = await this.prisma.globalStats.upsert({
      where: { statsKey: this.GLOBAL_KEY },
      create: {
        statsKey: this.GLOBAL_KEY,
        totalUserCount: 1,
      },
      update: {
        totalUserCount: { increment: 1 },
      },
    });

    return this.toDomain(result);
  }

  async incrementProvinceCompany(): Promise<GlobalStatsData> {
    this.logger.debug('Incrementing global province company count');

    const result = await this.prisma.globalStats.upsert({
      where: { statsKey: this.GLOBAL_KEY },
      create: {
        statsKey: this.GLOBAL_KEY,
        totalProvinceCompanyCount: 1,
      },
      update: {
        totalProvinceCompanyCount: { increment: 1 },
      },
    });

    return this.toDomain(result);
  }

  async incrementCityCompany(): Promise<GlobalStatsData> {
    this.logger.debug('Incrementing global city company count');

    const result = await this.prisma.globalStats.upsert({
      where: { statsKey: this.GLOBAL_KEY },
      create: {
        statsKey: this.GLOBAL_KEY,
        totalCityCompanyCount: 1,
      },
      update: {
        totalCityCompanyCount: { increment: 1 },
      },
    });

    return this.toDomain(result);
  }

  async updateStats(updates: Partial<GlobalStatsData>): Promise<GlobalStatsData> {
    const result = await this.prisma.globalStats.update({
      where: { statsKey: this.GLOBAL_KEY },
      data: {
        totalPlantingCount: updates.totalPlantingCount,
        totalOrderCount: updates.totalOrderCount,
        totalPlantingAmount: updates.totalPlantingAmount,
        totalUserCount: updates.totalUserCount,
        totalProvinceCompanyCount: updates.totalProvinceCompanyCount,
        totalCityCompanyCount: updates.totalCityCompanyCount,
      },
    });

    return this.toDomain(result);
  }

  private toDomain(
    record: Awaited<ReturnType<typeof this.prisma.globalStats.findFirst>>,
  ): GlobalStatsData {
    if (!record) {
      throw new Error('Record is null');
    }
    return {
      id: record.id,
      statsKey: record.statsKey,
      totalPlantingCount: record.totalPlantingCount,
      totalOrderCount: record.totalOrderCount,
      totalPlantingAmount: record.totalPlantingAmount,
      totalUserCount: record.totalUserCount,
      totalProvinceCompanyCount: record.totalProvinceCompanyCount,
      totalCityCompanyCount: record.totalCityCompanyCount,
      createdAt: record.createdAt,
      updatedAt: record.updatedAt,
    };
  }
}
