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

export interface TradingConfigEntity {
  id: string;
  totalShares: Money;
  burnTarget: Money;
  burnPeriodMinutes: number;
  minuteBurnRate: Money;
  isActive: boolean;
  buyEnabled: boolean;
  depthEnabled: boolean;
  activatedAt: Date | null;
  createdAt: Date;
  updatedAt: Date;
}

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

  async getConfig(): Promise<TradingConfigEntity | null> {
    const record = await this.prisma.tradingConfig.findFirst();
    if (!record) {
      return null;
    }
    return this.toDomain(record);
  }

  async initializeConfig(): Promise<TradingConfigEntity> {
    const existing = await this.prisma.tradingConfig.findFirst();
    if (existing) {
      return this.toDomain(existing);
    }

    const record = await this.prisma.tradingConfig.create({
      data: {
        totalShares: new Decimal('10002000000'), // 100.02亿
        burnTarget: new Decimal('10000000000'),
        burnPeriodMinutes: 2102400, // 365 * 4 * 1440
        minuteBurnRate: new Decimal('4756.468797564687'),
        isActive: false,
      },
    });

    return this.toDomain(record);
  }

  async activate(): Promise<void> {
    const config = await this.prisma.tradingConfig.findFirst();
    if (!config) {
      throw new Error('Trading config not initialized');
    }

    await this.prisma.tradingConfig.update({
      where: { id: config.id },
      data: {
        isActive: true,
        activatedAt: new Date(),
      },
    });
  }

  async deactivate(): Promise<void> {
    const config = await this.prisma.tradingConfig.findFirst();
    if (!config) {
      return;
    }

    await this.prisma.tradingConfig.update({
      where: { id: config.id },
      data: { isActive: false },
    });
  }

  async updateMinuteBurnRate(newRate: Money): Promise<void> {
    const config = await this.prisma.tradingConfig.findFirst();
    if (!config) {
      throw new Error('Trading config not initialized');
    }

    await this.prisma.tradingConfig.update({
      where: { id: config.id },
      data: { minuteBurnRate: newRate.value },
    });
  }

  async setBuyEnabled(enabled: boolean): Promise<void> {
    const config = await this.prisma.tradingConfig.findFirst();
    if (!config) {
      throw new Error('Trading config not initialized');
    }

    await this.prisma.tradingConfig.update({
      where: { id: config.id },
      data: { buyEnabled: enabled },
    });
  }

  async setDepthEnabled(enabled: boolean): Promise<void> {
    const config = await this.prisma.tradingConfig.findFirst();
    if (!config) {
      throw new Error('Trading config not initialized');
    }

    await this.prisma.tradingConfig.update({
      where: { id: config.id },
      data: { depthEnabled: enabled },
    });
  }

  private toDomain(record: any): TradingConfigEntity {
    return {
      id: record.id,
      totalShares: new Money(record.totalShares),
      burnTarget: new Money(record.burnTarget),
      burnPeriodMinutes: record.burnPeriodMinutes,
      minuteBurnRate: new Money(record.minuteBurnRate),
      isActive: record.isActive,
      buyEnabled: record.buyEnabled ?? false,
      depthEnabled: record.depthEnabled ?? false,
      activatedAt: record.activatedAt,
      createdAt: record.createdAt,
      updatedAt: record.updatedAt,
    };
  }
}
