import { Body, Controller, Delete, Get, Header, Param, Post, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { JwtAuthGuard } from '../auth/guards/auth.guard';
import { OrgRolesGuard } from '../auth/guards/org-roles.guard';
import { Roles } from '../auth/decorators/roles.decorator';
import { CertificatesService } from './certificates.service';
import { ProvisionMqttCertDto } from './dto/certificates.dto';
import { RequireAnyOrgAdminGuard } from './guards/require-any-org-admin.guard';

// Global broker/CA management — not org-nested, since the CA is broker-wide
// (mirrors serialNumber already being globally unique across orgs). JWT-only,
// same precedent as api-keys: credential-minting endpoints never accept an
// API key.
@ApiTags('certificates')
@ApiBearerAuth('jwt')
@Controller('certificates')
@UseGuards(JwtAuthGuard, RequireAnyOrgAdminGuard)
export class CertificatesController {
  constructor(private readonly certificatesService: CertificatesService) {}

  @Get('ca')
  caStatus() {
    return this.certificatesService.getCaStatus();
  }

  @Post('ca/init')
  initCa() {
    return this.certificatesService.initCa();
  }

  @Post('mqtt/provision')
  provisionMqttCert(@Body() dto: ProvisionMqttCertDto) {
    return this.certificatesService.provisionMqttCert(dto);
  }

  @Get('ca/download')
  @Header('Content-Type', 'application/x-pem-file')
  @Header('Content-Disposition', 'attachment; filename="ca.crt"')
  downloadCa() {
    return this.certificatesService.downloadCaCert();
  }
}

// Per-device certificate issuance, nested under the org's devices like the
// rest of the domain. Same guard stack as devices create/disable.
@ApiTags('certificates')
@ApiBearerAuth('jwt')
@Controller('orgs/:orgId/devices/:deviceId/certificate')
@UseGuards(JwtAuthGuard, OrgRolesGuard)
@Roles('ORG_ADMIN')
export class DeviceCertificatesController {
  constructor(private readonly certificatesService: CertificatesService) {}

  @Post()
  issue(@Param('orgId') orgId: string, @Param('deviceId') deviceId: string) {
    return this.certificatesService.issueDeviceCertificate(orgId, deviceId);
  }

  @Get()
  get(@Param('orgId') orgId: string, @Param('deviceId') deviceId: string) {
    return this.certificatesService.getDeviceCertificate(orgId, deviceId);
  }

  @Get('cert')
  @Header('Content-Type', 'application/x-pem-file')
  @Header('Content-Disposition', 'attachment; filename="device.crt"')
  downloadCert(@Param('orgId') orgId: string, @Param('deviceId') deviceId: string) {
    return this.certificatesService.downloadDeviceCert(orgId, deviceId);
  }

  @Get('key')
  @Header('Content-Type', 'application/x-pem-file')
  @Header('Content-Disposition', 'attachment; filename="device.key"')
  downloadKey(@Param('orgId') orgId: string, @Param('deviceId') deviceId: string) {
    return this.certificatesService.downloadDeviceKey(orgId, deviceId);
  }

  @Delete()
  revoke(@Param('orgId') orgId: string, @Param('deviceId') deviceId: string) {
    return this.certificatesService.revokeDeviceCertificate(orgId, deviceId);
  }
}
