import { Controller, Get, Query, UseGuards } from '@nestjs/common';
import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
import { PrismaService } from '../../infrastructure/database/prisma.service';
import { AdminAuthGuard } from '../../common/guards/admin-auth.guard';
import { AdminRolesGuard } from '../../common/guards/admin-roles.guard';
import { AdminRoles } from '../../common/decorators/admin-roles.decorator';
import type { AdminRole } from '../../common/types/admin-role.enum';

@ApiTags('admin-metrics')
@Controller('admin-api/metrics')
@UseGuards(AdminAuthGuard, AdminRolesGuard)
@ApiBearerAuth()
export class AdminMetricsController {
  constructor(private readonly prisma: PrismaService) {}

  @Get('overview')
  @AdminRoles('SUPER_ADMIN' as AdminRole)
  @ApiOperation({ summary: '指标概览' })
  async overview() {
    const today = new Date(); today.setHours(0, 0, 0, 0);
    const [todayCalls, avgDuration, errorCount] = await Promise.all([
      this.prisma.apiMetric.count({ where: { createdAt: { gte: today } } }),
      this.prisma.apiMetric.aggregate({ _avg: { duration: true }, where: { createdAt: { gte: today } } }),
      this.prisma.apiMetric.count({ where: { createdAt: { gte: today }, statusCode: { gte: 400 } } }),
    ]);
    const total = await this.prisma.apiMetric.count();
    return { todayCalls, avgDuration: Math.round(avgDuration._avg.duration || 0), errorCount, total };
  }

  @Get('top')
  @AdminRoles('SUPER_ADMIN' as AdminRole)
  @ApiOperation({ summary: '接口耗时排行' })
  async top(@Query('limit') limit = 10) {
    const metrics = await this.prisma.apiMetric.groupBy({
      by: ['path', 'method'],
      _avg: { duration: true },
      _count: { id: true },
      orderBy: { _avg: { duration: 'desc' } },
      take: parseInt(String(limit)),
    });
    return metrics.map(m => ({ path: m.path, method: m.method, avgDuration: Math.round(m._avg.duration || 0), calls: m._count.id }));
  }

  @Get('recent')
  @AdminRoles('SUPER_ADMIN' as AdminRole)
  @ApiOperation({ summary: '最近请求' })
  async recent(@Query('limit') limit = 30) {
    return this.prisma.apiMetric.findMany({ orderBy: { createdAt: 'desc' }, take: parseInt(String(limit)) });
  }

  @Get('ai')
  @AdminRoles('SUPER_ADMIN' as AdminRole)
  @ApiOperation({ summary: 'AI 调用耗时统计' })
  async aiMetrics(@Query('days') days = '7') {
    const since = new Date(Date.now() - parseInt(days) * 86400000);
    const logs = await this.prisma.aiUsageLog.findMany({
      where: { createdAt: { gte: since } },
      select: { provider: true, model: true, latencyMs: true, success: true, estimatedCost: true },
    });

    const byProvider: Record<string, { calls: number; totalLatency: number; totalCost: number; failures: number }> = {};
    const byModel: Record<string, { calls: number; totalLatency: number; totalCost: number; failures: number }> = {};
    for (const l of logs) {
      const pk = l.provider;
      if (!byProvider[pk]) byProvider[pk] = { calls: 0, totalLatency: 0, totalCost: 0, failures: 0 };
      byProvider[pk].calls++;
      byProvider[pk].totalLatency += l.latencyMs;
      byProvider[pk].totalCost += l.estimatedCost;
      if (!l.success) byProvider[pk].failures++;

      const mk = `${l.provider}/${l.model}`;
      if (!byModel[mk]) byModel[mk] = { calls: 0, totalLatency: 0, totalCost: 0, failures: 0 };
      byModel[mk].calls++;
      byModel[mk].totalLatency += l.latencyMs;
      byModel[mk].totalCost += l.estimatedCost;
      if (!l.success) byModel[mk].failures++;
    }

    const providers = Object.entries(byProvider).map(([name, d]) => ({
      name, calls: d.calls, avgLatencyMs: Math.round(d.totalLatency / d.calls),
      totalCost: d.totalCost.toFixed(4), failureRate: ((d.failures / d.calls) * 100).toFixed(1) + '%',
    }));
    const models = Object.entries(byModel).map(([name, d]) => ({
      name, calls: d.calls, avgLatencyMs: Math.round(d.totalLatency / d.calls),
      totalCost: d.totalCost.toFixed(4), failureRate: ((d.failures / d.calls) * 100).toFixed(1) + '%',
    }));

    return { totalCalls: logs.length, days: parseInt(days), providers, models };
  }

  @Get('worker')
  @AdminRoles('SUPER_ADMIN' as AdminRole)
  @ApiOperation({ summary: 'Worker 任务耗时统计' })
  async workerMetrics(@Query('days') days = '7') {
    const since = new Date(Date.now() - parseInt(days) * 86400000);
    const logs = await this.prisma.taskLog.findMany({
      where: { createdAt: { gte: since } },
      select: { queueName: true, status: true },
    });

    const byQueue: Record<string, { total: number; completed: number; failed: number }> = {};
    for (const l of logs) {
      if (!byQueue[l.queueName]) byQueue[l.queueName] = { total: 0, completed: 0, failed: 0 };
      byQueue[l.queueName].total++;
      if (l.status === 'completed' || l.status === 'retried') byQueue[l.queueName].completed++;
      if (l.status === 'failed' || l.status === 'error') byQueue[l.queueName].failed++;
    }

    const queues = Object.entries(byQueue).map(([name, d]) => ({
      name, total: d.total, completed: d.completed, failed: d.failed,
      successRate: d.total > 0 ? ((d.completed / d.total) * 100).toFixed(1) + '%' : '0%',
    }));

    return { totalTasks: logs.length, days: parseInt(days), queues };
  }
}
