import { Controller, Get, Query, Req } from '@nestjs/common';
import { ApiCookieAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
import type { Request } from 'express';
import { AuditWriter } from '../audit/audit.service';
import { AdminUsersReader, type AdminUsersPage } from './admin-users-reader.service';
import { RequireAdmin } from './require-admin.decorator';
import { AdminUsersQueryDto } from './users-query.dto';

/**
 * `GET /api/admin/users` — paginated, filterable view of the BFF's
 * user directory per ADR-0020's v1 admin catalogue. Gated by
 * `@RequireAdmin` and emits `admin.users.query` on every read so
 * the directory browsing surface is itself auditable.
 *
 * Mirrors `AdminAuditController`'s shape so the SPA's data flow
 * (filters → service → audit emit → response) follows the same
 * pattern across admin modules.
 */
@ApiTags('admin (user directory)')
@ApiCookieAuth('portal_admin_session')
@Controller('admin/users')
@RequireAdmin()
export class AdminUsersController {
  constructor(
    private readonly usersReader: AdminUsersReader,
    private readonly audit: AuditWriter,
  ) {}

  @ApiOperation({
    summary: 'Paginated user-directory query — emits `admin.users.query` on every call',
  })
  @Get()
  async list(@Req() req: Request, @Query() filters: AdminUsersQueryDto): Promise<AdminUsersPage> {
    const page = await this.usersReader.findUsers(filters);

    // Guard guarantees `req.session.user`; defensively narrow.
    const actorOid = req.session.user?.oid;
    if (actorOid !== undefined) {
      await this.audit.adminUsersQuery({
        actor: { oid: actorOid },
        filters: { ...filters },
        resultCount: page.items.length,
      });
    }

    return page;
  }
}
