import { Controller, Get, Post, Put, Delete, Body, Param, Query, UseGuards } from '@nestjs/common';
import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
import { IsString, IsOptional, IsInt, IsBoolean } from 'class-validator';
import { ModelRouter } from './model-router';
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';

class CreateRouteDto {
  @IsString() tier: string;
  @IsOptional() @IsString() taskType?: string;
  @IsString() preferredProvider: string;
  @IsString() preferredModel: string;
  @IsString() fallbackProvider: string;
  @IsString() fallbackModel: string;
  @IsOptional() @IsInt() maxRetries?: number;
}

class UpdateRouteDto {
  @IsOptional() @IsString() preferredProvider?: string;
  @IsOptional() @IsString() preferredModel?: string;
  @IsOptional() @IsString() fallbackProvider?: string;
  @IsOptional() @IsString() fallbackModel?: string;
  @IsOptional() @IsInt() maxRetries?: number;
  @IsOptional() @IsBoolean() isActive?: boolean;
}

class UpdateProviderDto {
  @IsBoolean() enabled: boolean;
}

@ApiTags('admin-ai-gateway')
@Controller('admin-api/ai-gateway')
@UseGuards(AdminAuthGuard, AdminRolesGuard)
@ApiBearerAuth()
export class AdminAiGatewayController {
  constructor(
    private readonly router: ModelRouter,
    private readonly prisma: PrismaService,
  ) {}

  @Get('status')
  @AdminRoles('SUPER_ADMIN' as AdminRole)
  @ApiOperation({ summary: 'AI Gateway 状态' })
  async status() {
    const routes = await this.prisma.modelRoute.findMany({ where: { isActive: true } });
    const providers = await this.prisma.providerConfig.findMany();
    return {
      providers: providers.map(p => ({ name: p.name, enabled: p.enabled })),
      routes: routes.map(r => ({
        id: r.id, tier: r.tier, taskType: r.taskType,
        preferred: `${r.preferredProvider}/${r.preferredModel}`,
        fallback: `${r.fallbackProvider}/${r.fallbackModel}`,
        maxRetries: r.maxRetries,
      })),
      activeRoutes: routes.length,
    };
  }

  // ── Routes CRUD ──

  @Get('routes')
  @AdminRoles('SUPER_ADMIN' as AdminRole)
  @ApiOperation({ summary: '模型路由规则列表' })
  async listRoutes() {
    return this.prisma.modelRoute.findMany({ orderBy: [{ tier: 'asc' }, { taskType: 'asc' }] });
  }

  @Post('routes')
  @AdminRoles('SUPER_ADMIN' as AdminRole)
  @ApiOperation({ summary: '创建路由规则' })
  async createRoute(@Body() dto: CreateRouteDto) {
    const route = await this.prisma.modelRoute.create({
      data: {
        tier: dto.tier,
        taskType: dto.taskType || '*',
        preferredProvider: dto.preferredProvider,
        preferredModel: dto.preferredModel,
        fallbackProvider: dto.fallbackProvider,
        fallbackModel: dto.fallbackModel,
        maxRetries: dto.maxRetries ?? 2,
      },
    });
    await this.router.loadFromDb(); // reload in-memory cache
    return route;
  }

  @Put('routes/:id')
  @AdminRoles('SUPER_ADMIN' as AdminRole)
  @ApiOperation({ summary: '更新路由规则' })
  async updateRoute(@Param('id') id: string, @Body() dto: UpdateRouteDto) {
    const data: any = {};
    if (dto.preferredProvider !== undefined) data.preferredProvider = dto.preferredProvider;
    if (dto.preferredModel !== undefined) data.preferredModel = dto.preferredModel;
    if (dto.fallbackProvider !== undefined) data.fallbackProvider = dto.fallbackProvider;
    if (dto.fallbackModel !== undefined) data.fallbackModel = dto.fallbackModel;
    if (dto.maxRetries !== undefined) data.maxRetries = dto.maxRetries;
    if (dto.isActive !== undefined) data.isActive = dto.isActive;

    const route = await this.prisma.modelRoute.update({ where: { id }, data });
    await this.router.loadFromDb();
    return route;
  }

  @Delete('routes/:id')
  @AdminRoles('SUPER_ADMIN' as AdminRole)
  @ApiOperation({ summary: '删除路由规则' })
  async deleteRoute(@Param('id') id: string) {
    await this.prisma.modelRoute.delete({ where: { id } });
    await this.router.loadFromDb();
    return { success: true };
  }

  // ── Provider management ──

  @Get('providers')
  @AdminRoles('SUPER_ADMIN' as AdminRole)
  @ApiOperation({ summary: 'Provider 列表' })
  async listProviders() {
    return this.prisma.providerConfig.findMany({ orderBy: { name: 'asc' } });
  }

  @Put('providers/:name')
  @AdminRoles('SUPER_ADMIN' as AdminRole)
  @ApiOperation({ summary: '启用/禁用 Provider' })
  async toggleProvider(@Param('name') name: string, @Body() dto: UpdateProviderDto) {
    const provider = await this.prisma.providerConfig.upsert({
      where: { name },
      update: { enabled: dto.enabled },
      create: { name, enabled: dto.enabled },
    });
    return provider;
  }

  // ── Fallback events ──

  @Get('fallback-events')
  @AdminRoles('SUPER_ADMIN' as AdminRole)
  @ApiOperation({ summary: '降级事件日志' })
  async fallbackEvents(@Query('limit') limit = '50') {
    return this.prisma.fallbackEvent.findMany({
      orderBy: { createdAt: 'desc' },
      take: parseInt(limit),
    });
  }
}
