import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Post,
} from '@nestjs/common';
import {
  IsInt,
  IsString,
  Max,
  MaxLength,
  Min,
  MinLength,
} from 'class-validator';
import { RequirePermissions } from '@common/decorators/permissions.decorator';
import { CurrentUser } from '@common/decorators/current-user.decorator';
import { Auditable, Sensitive } from '@core/observability/audit/decorators/auditable.decorator';
import { EmergencyBypassService } from '@common/services/emergency-bypass.service';
import { IamAuditService } from '@common/services/iam-audit.service';

class EnableBypassDto {
  @IsString()
  @MinLength(3)
  @MaxLength(200)
  endpoint!: string;

  @IsString()
  @MinLength(2)
  @MaxLength(500)
  reason!: string;

  @IsInt()
  @Min(60)
  @Max(4 * 60 * 60)
  ttlSec!: number;
}

/**
 * IAM 后台：紧急豁免（规则 §5.6 - P2）
 *
 * 路径用 base64url 传 endpoint，避免 'POST /api/v1/x' 这种带空格/斜杠的字符串走 path param 出 404。
 */
@Controller('iam/emergency-bypass')
export class EmergencyBypassController {
  constructor(
    private readonly service: EmergencyBypassService,
    private readonly audit: IamAuditService,
  ) {}

  @Get()
  @RequirePermissions('iam_admin:read')
  list() {
    return this.service.listActive();
  }

  @Post()
  @RequirePermissions('iam_admin:manage')
  @Auditable()
  @Sensitive()
  async enable(
    @Body() body: EnableBypassDto,
    @CurrentUser('userId') actor: string,
  ) {
    await this.service.enableFor(body.endpoint, body.reason, body.ttlSec);
    await this.audit.record({
      actor,
      action: 'CREATE',
      resource: 'EmergencyBypass',
      after: { endpoint: body.endpoint, reason: body.reason, ttlSec: body.ttlSec },
    });
    return { ok: true };
  }

  @Delete(':endpoint')
  @RequirePermissions('iam_admin:manage')
  @Auditable()
  @Sensitive()
  async disable(
    @Param('endpoint') endpointB64: string,
    @CurrentUser('userId') actor: string,
  ) {
    const endpoint = Buffer.from(endpointB64, 'base64url').toString('utf8');
    await this.service.disable(endpoint);
    await this.audit.record({
      actor,
      action: 'DELETE',
      resource: 'EmergencyBypass',
      after: { endpoint },
    });
    return { ok: true };
  }
}
