import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { Money } from '../../../domain/value-objects/money.vo';

export interface PriceSnapshotEntity {
  id: string;
  snapshotTime: Date;
  price: Money;
  greenPoints: Money;
  blackHoleAmount: Money;
  circulationPool: Money;
  effectiveDenominator: Money;
  minuteBurnRate: Money;
  createdAt: Date;
}

@Injectable()
export class PriceSnapshotRepository {
  constructor(private readonly prisma: PrismaService) {}

  async getLatestSnapshot(): Promise<PriceSnapshotEntity | null> {
    const record = await this.prisma.priceSnapshot.findFirst({
      orderBy: { snapshotTime: 'desc' },
    });
    if (!record) {
      return null;
    }
    return this.toDomain(record);
  }

  /**
   * 获取最早的非零价格快照（上线首日价格）
   */
  async getFirstSnapshot(): Promise<PriceSnapshotEntity | null> {
    const record = await this.prisma.priceSnapshot.findFirst({
      where: { price: { gt: 0 } },
      orderBy: { snapshotTime: 'asc' },
    });
    if (!record) {
      return null;
    }
    return this.toDomain(record);
  }

  async getSnapshotAt(time: Date): Promise<PriceSnapshotEntity | null> {
    // 获取指定时间之前最近的快照
    const record = await this.prisma.priceSnapshot.findFirst({
      where: { snapshotTime: { lte: time } },
      orderBy: { snapshotTime: 'desc' },
    });
    if (!record) {
      return null;
    }
    return this.toDomain(record);
  }

  async createSnapshot(data: {
    snapshotTime: Date;
    price: Money;
    greenPoints: Money;
    blackHoleAmount: Money;
    circulationPool: Money;
    effectiveDenominator: Money;
    minuteBurnRate: Money;
  }): Promise<PriceSnapshotEntity> {
    const record = await this.prisma.priceSnapshot.create({
      data: {
        snapshotTime: data.snapshotTime,
        price: data.price.value,
        greenPoints: data.greenPoints.value,
        blackHoleAmount: data.blackHoleAmount.value,
        circulationPool: data.circulationPool.value,
        effectiveDenominator: data.effectiveDenominator.value,
        minuteBurnRate: data.minuteBurnRate.value,
      },
    });
    return this.toDomain(record);
  }

  async getPriceHistory(
    startTime: Date,
    endTime: Date,
    limit: number = 1440,
  ): Promise<PriceSnapshotEntity[]> {
    const records = await this.prisma.priceSnapshot.findMany({
      where: {
        snapshotTime: {
          gte: startTime,
          lte: endTime,
        },
      },
      orderBy: { snapshotTime: 'asc' },
      take: limit,
    });

    return records.map((r) => this.toDomain(r));
  }

  async getSnapshots(
    page: number,
    pageSize: number,
  ): Promise<{
    data: PriceSnapshotEntity[];
    total: number;
  }> {
    const [records, total] = await Promise.all([
      this.prisma.priceSnapshot.findMany({
        orderBy: { snapshotTime: 'desc' },
        skip: (page - 1) * pageSize,
        take: pageSize,
      }),
      this.prisma.priceSnapshot.count(),
    ]);

    return {
      data: records.map((r) => this.toDomain(r)),
      total,
    };
  }

  /**
   * 清理旧的价格快照（保留指定天数）
   */
  async cleanupOldSnapshots(retentionDays: number): Promise<number> {
    const cutoffDate = new Date();
    cutoffDate.setDate(cutoffDate.getDate() - retentionDays);

    const result = await this.prisma.priceSnapshot.deleteMany({
      where: { snapshotTime: { lt: cutoffDate } },
    });

    return result.count;
  }

  private toDomain(record: any): PriceSnapshotEntity {
    return {
      id: record.id,
      snapshotTime: record.snapshotTime,
      price: new Money(record.price),
      greenPoints: new Money(record.greenPoints),
      blackHoleAmount: new Money(record.blackHoleAmount),
      circulationPool: new Money(record.circulationPool),
      effectiveDenominator: new Money(record.effectiveDenominator),
      minuteBurnRate: new Money(record.minuteBurnRate),
      createdAt: record.createdAt,
    };
  }
}
