import { Controller, Get, Post, Delete, Body, Param, Query, Req, Logger } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiQuery, ApiParam } from '@nestjs/swagger';
import { ConfigService } from '@nestjs/config';
import { ConfigManagementService } from '../../application/services/config.service';

class SetConfigDto { category: string; key: string; value: string; description?: string; }

@ApiTags('Config')
@ApiBearerAuth()
@Controller('configs')
export class ConfigController {
  private readonly logger = new Logger(ConfigController.name);

  constructor(
    private readonly configService: ConfigManagementService,
    private readonly appConfigService: ConfigService,
  ) {}

  @Get()
  @ApiOperation({ summary: '获取配置列表' })
  @ApiQuery({ name: 'category', required: false })
  async getConfigs(@Query('category') category?: string) {
    return this.configService.getConfigs(category);
  }

  @Get('transfer-enabled')
  @ApiOperation({ summary: '获取划转开关状态' })
  async getTransferEnabled() {
    const config = await this.configService.getConfig('system', 'transfer_enabled');
    return { enabled: config?.configValue === 'true' };
  }

  @Post('transfer-enabled')
  @ApiOperation({ summary: '设置划转开关状态' })
  async setTransferEnabled(@Body() body: { enabled: boolean }, @Req() req: any) {
    await this.configService.setConfig(req.admin.id, 'system', 'transfer_enabled', String(body.enabled), '划转开关');
    return { success: true };
  }

  @Get('mining/status')
  @ApiOperation({ summary: '获取挖矿状态' })
  async getMiningStatus() {
    const miningServiceUrl = this.appConfigService.get<string>('MINING_SERVICE_URL', 'http://localhost:3021');
    const contributionServiceUrl = this.appConfigService.get<string>('CONTRIBUTION_SERVICE_URL', 'http://localhost:3020');

    this.logger.log(`Fetching mining status from ${miningServiceUrl}/api/v2/admin/status`);
    try {
      // 并行获取 mining-service 状态和 contribution-service 统计数据
      const [miningResponse, contributionResponse] = await Promise.all([
        fetch(`${miningServiceUrl}/api/v2/admin/status`),
        fetch(`${contributionServiceUrl}/api/v2/contribution/stats`).catch(() => null),
      ]);

      if (!miningResponse.ok) {
        throw new Error(`Failed to fetch mining status: ${miningResponse.status}`);
      }
      const miningResult = await miningResponse.json();
      this.logger.log(`Mining service response: ${JSON.stringify(miningResult)}`);

      const miningData = miningResult.data || miningResult;

      // 获取 contribution-service 的全网理论算力
      let networkTotalContribution: string | null = null;
      let userEffectiveContribution: string | null = null;
      let systemAccountsContribution: string | null = null;

      if (contributionResponse && contributionResponse.ok) {
        const contributionResult = await contributionResponse.json();
        const data = contributionResult.data || contributionResult;

        // 全网理论算力 = 总认种树 × 每棵树算力
        networkTotalContribution = data.networkTotalContribution || null;
        // 用户有效算力
        userEffectiveContribution = data.totalContribution || null;
        // 系统账户算力
        const systemAccounts = data.systemAccounts || [];
        const systemTotal = systemAccounts
          .filter((a: any) => a.accountType !== 'HEADQUARTERS')
          .reduce((sum: number, a: any) => sum + parseFloat(a.totalContribution || '0'), 0);
        systemAccountsContribution = systemTotal.toString();
      }

      // mining-service 中的全网理论算力
      const miningNetworkTotal = miningData.networkTotalContribution || '0';
      // mining-service 中的用户有效算力
      const miningUserTotal = miningData.totalContribution || '0';

      // 判断算力是否同步完成
      // 核心条件：全网理论算力已同步（mining-service 的 networkTotalContribution 与 contribution-service 相近）
      // 全网理论算力是挖矿分母，必须同步后才能正确计算挖矿比例
      const networkSynced = networkTotalContribution !== null &&
        parseFloat(networkTotalContribution) > 0 &&
        parseFloat(miningNetworkTotal) > 0 &&
        Math.abs(parseFloat(miningNetworkTotal) - parseFloat(networkTotalContribution)) / parseFloat(networkTotalContribution) < 0.001;

      const isSynced = networkSynced;

      return {
        ...miningData,
        contributionSyncStatus: {
          isSynced,
          // 全网理论算力（应作为挖矿分母）
          networkTotalContribution: networkTotalContribution || '0',
          miningNetworkTotal,
          // 用户有效算力
          userEffectiveContribution: userEffectiveContribution || '0',
          miningUserTotal,
          // 系统账户算力
          systemAccountsContribution: systemAccountsContribution || '0',
          // 兼容旧字段
          miningTotal: miningUserTotal,
          contributionTotal: userEffectiveContribution || '0',
        },
      };
    } catch (error) {
      this.logger.error('Failed to get mining status', error);
      return {
        initialized: false,
        isActive: false,
        error: `Unable to connect to mining service: ${error.message}`,
        contributionSyncStatus: {
          isSynced: false,
          networkTotalContribution: '0',
          miningNetworkTotal: '0',
          userEffectiveContribution: '0',
          miningUserTotal: '0',
          systemAccountsContribution: '0',
          miningTotal: '0',
          contributionTotal: '0',
        },
      };
    }
  }

  @Post('mining/activate')
  @ApiOperation({ summary: '激活挖矿' })
  async activateMining(@Req() req: any) {
    const miningServiceUrl = this.appConfigService.get<string>('MINING_SERVICE_URL', 'http://localhost:3021');
    try {
      const response = await fetch(`${miningServiceUrl}/api/v2/admin/activate`, {
        method: 'POST',
      });
      if (!response.ok) {
        throw new Error('Failed to activate mining');
      }
      const result = await response.json();
      this.logger.log(`Mining activated by admin ${req.admin?.id}`);
      return result;
    } catch (error) {
      this.logger.error('Failed to activate mining', error);
      return { success: false, message: 'Failed to activate mining' };
    }
  }

  @Post('mining/deactivate')
  @ApiOperation({ summary: '停用挖矿' })
  async deactivateMining(@Req() req: any) {
    const miningServiceUrl = this.appConfigService.get<string>('MINING_SERVICE_URL', 'http://localhost:3021');
    try {
      const response = await fetch(`${miningServiceUrl}/api/v2/admin/deactivate`, {
        method: 'POST',
      });
      if (!response.ok) {
        throw new Error('Failed to deactivate mining');
      }
      const result = await response.json();
      this.logger.log(`Mining deactivated by admin ${req.admin?.id}`);
      return result;
    } catch (error) {
      this.logger.error('Failed to deactivate mining', error);
      return { success: false, message: 'Failed to deactivate mining' };
    }
  }

  @Get(':category/:key')
  @ApiOperation({ summary: '获取单个配置' })
  @ApiParam({ name: 'category' })
  @ApiParam({ name: 'key' })
  async getConfig(@Param('category') category: string, @Param('key') key: string) {
    return this.configService.getConfig(category, key);
  }

  @Post()
  @ApiOperation({ summary: '设置配置' })
  async setConfig(@Body() dto: SetConfigDto, @Req() req: any) {
    await this.configService.setConfig(req.admin.id, dto.category, dto.key, dto.value, dto.description);
    return { success: true };
  }

  @Delete(':category/:key')
  @ApiOperation({ summary: '删除配置' })
  async deleteConfig(@Param('category') category: string, @Param('key') key: string, @Req() req: any) {
    await this.configService.deleteConfig(req.admin.id, category, key);
    return { success: true };
  }
}
