import { Body, Controller, HttpCode, HttpStatus, NotFoundException, Post } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { SignJWT } from 'jose';
import { createZodDto } from 'nestjs-zod';
import { DevTokenRequestSchema, type AuthTokenResponse } from '@sar/api-interface';
import type { Env } from '../config/env.schema';
import { Public } from './public.decorator';

class DevTokenRequestDto extends createZodDto(DevTokenRequestSchema) {}

// Dev-only stub — emite JWT HS256 para smoke tests locais.
// CODING-RULES PGD-SEC-002: retorna 404 em produção.
// CODING-RULES PGD-AUTHZ-002: id_empresa vem do body aqui APENAS porque
//   este endpoint É o gerador do token — nenhum outro handler pode fazer isso.
// ADR 0006 revogado: workspaceId → idEmpresa (Int da empresa no ERP)

@Public()
@Controller({ path: 'auth/dev' })
export class DevAuthController {
  private readonly secret: Uint8Array;
  private readonly expiresIn: number;
  private readonly isProd: boolean;
  private readonly devEmpresaId: number;

  constructor(config: ConfigService<Env, true>) {
    this.secret = new TextEncoder().encode(config.get('MASTER_LOGIN_JWT_SECRET', { infer: true }));
    this.expiresIn = config.get('JWT_ACCESS_EXPIRATION', { infer: true });
    this.isProd = config.get('NODE_ENV', { infer: true }) === 'production';
    this.devEmpresaId = config.get('DEV_EMPRESA_ID', { infer: true });
  }

  @Post('token')
  @HttpCode(HttpStatus.OK)
  async token(@Body() dto: DevTokenRequestDto): Promise<AuthTokenResponse> {
    if (this.isProd) throw new NotFoundException();

    const accessToken = await new SignJWT({
      id_empresa: dto.idEmpresa ?? this.devEmpresaId,
      role: dto.role,
    })
      .setProtectedHeader({ alg: 'HS256' })
      .setSubject(dto.userId)
      .setIssuedAt()
      .setExpirationTime(`${this.expiresIn}s`)
      .sign(this.secret);

    return { accessToken, tokenType: 'Bearer', expiresIn: this.expiresIn };
  }
}
