import { Body, Controller, Get, Param, Post, Query, Req, Res, UseGuards } from '@nestjs/common';
import { Throttle } from '@nestjs/throttler';
import type { Request, Response } from 'express';
import { ErpJwtGuard } from 'src/sesion/erp-jwt.guard';
import { GetSesion } from 'src/sesion/get-sesion.decorator';
import { SoporteHabilitadoGuard } from 'src/sesion/soporte-habilitado.guard';
import { Sesion } from 'src/sesion/sesion.types';
import { AdjuntoParams, ConformidadDto, ListarTicketsQuery, TicketParams, TurnoDto } from './dto/tickets.dto';
import { enviarSse } from './sse';
import { TicketsService } from './tickets.service';

/**
 * La sección "Soporte IA" del frontend. Usuarios con el módulo SOPORTE_IA habilitado
 * (SoporteHabilitadoGuard); lo que el agente les muestra lo limitan sus propios privilegios (§4.3).
 */
@Controller({ path: 'tickets', version: '1' })
@UseGuards(ErpJwtGuard, SoporteHabilitadoGuard)
export class TicketsController {
  constructor(private readonly tickets: TicketsService) {}

  /** Nueva consulta. Responde en streaming (SSE): ticket, progreso, texto, fin. */
  @Post()
  @Throttle({ default: { ttl: 60_000, limit: 15 } })
  async crear(@GetSesion() sesion: Sesion, @Body() dto: TurnoDto, @Req() req: Request, @Res() res: Response) {
    const eventos = await this.tickets.iniciarTurno(sesion, null, dto.texto, dto.imagenes);
    await enviarSse(req, res, eventos);
  }

  /** Seguir la conversación en un ticket abierto. SSE. */
  @Post(':id/mensajes')
  @Throttle({ default: { ttl: 60_000, limit: 15 } })
  async mensaje(
    @GetSesion() sesion: Sesion,
    @Param() p: TicketParams,
    @Body() dto: TurnoDto,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const eventos = await this.tickets.iniciarTurno(sesion, p.id, dto.texto, dto.imagenes);
    await enviarSse(req, res, eventos);
  }

  @Get()
  listar(@GetSesion() sesion: Sesion, @Query() q: ListarTicketsQuery) {
    return this.tickets.listar(sesion, q.pagina ?? 1);
  }

  @Get(':id')
  detalle(@GetSesion() sesion: Sesion, @Param() p: TicketParams) {
    return this.tickets.detalle(sesion, p.id);
  }

  /** Una captura que adjuntó el usuario en su ticket. Con token: el panel la pide como blob. */
  @Get(':id/adjuntos/:adjunto')
  async adjunto(@GetSesion() sesion: Sesion, @Param() p: AdjuntoParams, @Res() res: Response) {
    const a = await this.tickets.adjunto(sesion, p.id, p.adjunto);
    res.setHeader('Content-Type', a.tipo);
    res.setHeader('Cache-Control', 'private, max-age=3600');
    res.setHeader('X-Content-Type-Options', 'nosniff');
    res.end(a.datos);
  }

  @Post(':id/conformidad')
  conformidad(@GetSesion() sesion: Sesion, @Param() p: TicketParams, @Body() dto: ConformidadDto) {
    return this.tickets.conformidad(sesion, p.id, dto.valor);
  }
}
