import { BadRequestException, Controller, ForbiddenException, Get, Headers, NotFoundException, Param, Post, Query } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { ActorResolver, type MessagePrincipal } from '../identity/actor.resolver';
import { SessionVerifier } from '../platform/session.verifier';
import { recordAudit } from '../observability/audit';
import { DlqService } from './dlq.service';

/**
 * DLQ ops surface (P9, KG-13). Strictly tenant-scoped: a caller only ever sees and
 * replays dead-letters owned by their own scope (assertOwns fences replay by id).
 */
@Controller('v1/dlq')
export class DlqController {
  constructor(
    private readonly prisma: PrismaService,
    private readonly dlq: DlqService,
    private readonly actors: ActorResolver,
    private readonly session: SessionVerifier,
  ) {}

  @Get()
  async list(@Query('status') status?: string, @Headers('authorization') auth?: string) {
    const principal = this.principal(auth);
    const scope = await this.actors.findScope(principal);
    if (!scope) return []; // a caller with no scope owns nothing
    return this.dlq.listDlq(scope.id, status);
  }

  @Post(':id/replay')
  async replay(@Param('id') id: string, @Headers('authorization') auth?: string) {
    const principal = this.principal(auth);
    const item = await this.prisma.iiosDlqItem.findUnique({ where: { id } });
    if (!item) throw new NotFoundException('dlq item not found');
    if (!item.scopeId) throw new ForbiddenException('dlq item is not tenant-scoped');
    const scope = await this.actors.assertOwns(principal, item.scopeId); // KG-02 fence
    const result = await this.dlq.replay(id);
    await recordAudit(this.prisma, { action: 'dlq.replay', resourceType: 'dlq_item', resourceId: id, scopeId: scope.id });
    return result;
  }

  private principal(authorization?: string): MessagePrincipal {
    const token = (authorization ?? '').replace(/^Bearer\s+/i, '');
    if (!token) throw new BadRequestException('Authorization bearer token is required');
    return this.session.verify(token);
  }
}
