import { Injectable, Logger, HttpException, HttpStatus } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PrismaService } from '../../infrastructure/persistence/prisma/prisma.service';

export interface ManualMiningCalculateRequest {
  accountSequence: string;
  adoptionDate: string;
}

export interface ManualMiningExecuteRequest {
  accountSequence: string;
  adoptionDate: string;
  operatorId: string;
  operatorName: string;
  reason: string;
}

/**
 * 手工补发挖矿服务 - 管理后台层
 * 负责调用 mining-service 的内部 API
 */
@Injectable()
export class ManualMiningService {
  private readonly logger = new Logger(ManualMiningService.name);
  private readonly miningServiceUrl: string;

  constructor(
    private readonly prisma: PrismaService,
    private readonly configService: ConfigService,
  ) {
    this.miningServiceUrl = this.configService.get<string>(
      'MINING_SERVICE_URL',
      'http://localhost:3021',
    );
  }

  /**
   * 计算预估补发金额
   */
  async calculate(request: ManualMiningCalculateRequest): Promise<any> {
    try {
      const response = await fetch(
        `${this.miningServiceUrl}/api/v2/mining/admin/manual-mining/calculate`,
        {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(request),
        },
      );

      const result = await response.json();

      if (!response.ok) {
        throw new HttpException(
          result.message || '计算失败',
          response.status,
        );
      }

      return result;
    } catch (error) {
      if (error instanceof HttpException) {
        throw error;
      }
      this.logger.error('Failed to calculate manual mining', error);
      throw new HttpException(
        `调用 mining-service 失败: ${error instanceof Error ? error.message : error}`,
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  /**
   * 执行手工补发
   */
  async execute(
    request: ManualMiningExecuteRequest,
    adminId: string,
    ipAddress?: string,
    userAgent?: string,
  ): Promise<any> {
    try {
      const response = await fetch(
        `${this.miningServiceUrl}/api/v2/mining/admin/manual-mining/execute`,
        {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(request),
        },
      );

      const result = await response.json();

      if (!response.ok) {
        throw new HttpException(
          result.message || '执行失败',
          response.status,
        );
      }

      // 记录审计日志
      await this.prisma.auditLog.create({
        data: {
          adminId,
          action: 'CREATE',
          resource: 'MANUAL_MINING',
          resourceId: result.recordId,
          newValue: {
            accountSequence: request.accountSequence,
            adoptionDate: request.adoptionDate,
            amount: result.amount,
            reason: request.reason,
          },
          ipAddress,
          userAgent,
        },
      });

      this.logger.log(
        `Manual mining executed by admin ${adminId}: account=${request.accountSequence}, amount=${result.amount}`,
      );

      return result;
    } catch (error) {
      if (error instanceof HttpException) {
        throw error;
      }
      this.logger.error('Failed to execute manual mining', error);
      throw new HttpException(
        `调用 mining-service 失败: ${error instanceof Error ? error.message : error}`,
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  /**
   * 获取补发记录列表
   */
  async getRecords(page: number = 1, pageSize: number = 20): Promise<any> {
    try {
      const response = await fetch(
        `${this.miningServiceUrl}/api/v2/mining/admin/manual-mining/records?page=${page}&pageSize=${pageSize}`,
        {
          method: 'GET',
          headers: { 'Content-Type': 'application/json' },
        },
      );

      const result = await response.json();

      if (!response.ok) {
        throw new HttpException(
          result.message || '获取记录失败',
          response.status,
        );
      }

      return result;
    } catch (error) {
      if (error instanceof HttpException) {
        throw error;
      }
      this.logger.error('Failed to get manual mining records', error);
      throw new HttpException(
        `调用 mining-service 失败: ${error instanceof Error ? error.message : error}`,
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  /**
   * 根据 accountSequence 获取补发记录
   */
  async getRecordByAccountSequence(accountSequence: string): Promise<any> {
    try {
      const response = await fetch(
        `${this.miningServiceUrl}/api/v2/mining/admin/manual-mining/records/${accountSequence}`,
        {
          method: 'GET',
          headers: { 'Content-Type': 'application/json' },
        },
      );

      if (response.status === 404) {
        return null;
      }

      const result = await response.json();

      if (!response.ok) {
        throw new HttpException(
          result.message || '获取记录失败',
          response.status,
        );
      }

      return result;
    } catch (error) {
      if (error instanceof HttpException) {
        throw error;
      }
      this.logger.error('Failed to get manual mining record', error);
      throw new HttpException(
        `调用 mining-service 失败: ${error instanceof Error ? error.message : error}`,
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }
}
