import { Body, Controller, Get, HttpCode, Param, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
import { GetUser } from 'src/auth/get-user.decorator';
import type { LoginUserInfo } from 'src/auth/dto/login.dto';
import { AyudaConfigService } from '../services/ayuda-config.service';
import { AyudaIngestaService } from '../services/ayuda-ingesta.service';
import { UpsertAyudaConfigDto } from '../dto/upsert-ayuda-config.dto';
import { RunIngestaDto } from '../dto/preguntar.dto';

@ApiTags('ayuda-ia-config')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'))
@Controller({ path: 'ayuda-ia/config', version: '1' })
export class AyudaConfigController {
  constructor(
    private readonly configService: AyudaConfigService,
    private readonly ingestaService: AyudaIngestaService,
  ) {}

  @Post()
  @ApiOperation({ summary: 'Crear o actualizar configuración global de Ayuda IA (sólo holding)' })
  upsert(@Body() dto: UpsertAyudaConfigDto, @GetUser() user: LoginUserInfo) {
    return this.configService.upsertConfig(user.empresa_id, dto);
  }

  @Get()
  @ApiOperation({ summary: 'Obtener configuración global (sin API key)' })
  get() {
    return this.configService.getConfig();
  }

  @Post('modelos')
  @HttpCode(200)
  @ApiOperation({ summary: 'Listar modelos disponibles (consulta el proveedor en vivo si hay api_key/base_url)' })
  modelos(@Body() body: { proveedor: string; api_key?: string; base_url?: string }) {
    return this.configService.listarModelos(body);
  }

  @Post('test')
  @HttpCode(200)
  @ApiOperation({ summary: 'Probar conexión con el proveedor (sólo holding)' })
  test(@Body() body: Partial<UpsertAyudaConfigDto>, @GetUser() user: LoginUserInfo) {
    return this.configService.testConexion(user.empresa_id, body);
  }

  @Post('ingesta/run')
  @HttpCode(202)
  @ApiOperation({ summary: 'Disparar ingesta de docs/guías (async, sólo holding). Devuelve job_id.' })
  async runIngesta(@Body() body: RunIngestaDto, @GetUser() user: LoginUserInfo) {
    await this.configService.assertHoldingCaller(user.empresa_id);
    return this.ingestaService.encolarJob(
      user.empresa_id,
      body.source ?? 'all',
      !!body.force,
      !!body.dry_run,
    );
  }

  @Get('ingesta/log/:jobId')
  @ApiOperation({
    summary: 'Detalle por archivo de un job (created/updated/skipped/deleted/error/dryrun_*)',
  })
  jobLog(@Param('jobId') jobId: string) {
    return this.ingestaService.getJobLog(jobId);
  }

  @Get('ingesta/status/:jobId')
  @ApiOperation({ summary: 'Status de un job de ingesta' })
  statusIngesta(@Param('jobId') jobId: string) {
    return this.ingestaService.getJobStatus(jobId);
  }

  @Get('ingesta/activo')
  @ApiOperation({ summary: 'Devuelve el job en curso si existe (para recuperar la barra al recargar)' })
  jobActivo() {
    return this.ingestaService.getJobCorriendoMasReciente();
  }

  @Post('ingesta/cancel/:jobId')
  @HttpCode(200)
  @ApiOperation({ summary: 'Cancela un job de ingesta en curso (sólo holding)' })
  async cancelarIngesta(@Param('jobId') jobId: string, @GetUser() user: LoginUserInfo) {
    await this.configService.assertHoldingCaller(user.empresa_id);
    return this.ingestaService.cancelarJob(jobId);
  }

  @Post('ingesta/cancel-todos')
  @HttpCode(200)
  @ApiOperation({ summary: 'Cancela TODOS los jobs no terminales (limpieza forzada)' })
  async cancelarTodos(@GetUser() user: LoginUserInfo) {
    await this.configService.assertHoldingCaller(user.empresa_id);
    return this.ingestaService.cancelarTodosActivos();
  }
}
