import { Body, Controller, Delete, Get, Param, ParseIntPipe, Post, Put, Query, UploadedFile, UseGuards, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
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 { RequireModule, RequirePermission } from 'src/auth/decorators';
import { ModuleGuard } from 'src/auth/guards/module.guard';
import { PermissionGuard } from 'src/auth/guards/permission.guard';
import { EcommerceAdminService } from './ecommerce-admin.service';
import { crearTokenVistaPrevia } from '../public/preview-token';
import { envs } from 'src/config';
import { UpsertEcommerceConfigDto } from './dto/upsert-ecommerce-config.dto';

@ApiTags('ecommerce-admin')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('ECOMMERCE')
@Controller({ path: 'ecommerce/config', version: '1' })
export class EcommerceAdminController {
  constructor(private readonly service: EcommerceAdminService) {}

  @Get()
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_VER')
  @ApiOperation({ summary: 'Obtener configuración ecommerce de la empresa (crea defaults si no existe)' })
  getConfig(@GetUser() user: LoginUserInfo) {
    return this.service.getConfig(user.empresa_id);
  }

  @Put()
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_EDITAR')
  @ApiOperation({ summary: 'Guardar cambios de configuración como borrador' })
  updateDraft(@Body() dto: UpsertEcommerceConfigDto, @GetUser() user: LoginUserInfo) {
    return this.service.updateDraft(user.empresa_id, dto);
  }

  // Publicar es lo que impacta la tienda en vivo: permiso aparte de "editar el
  // borrador", para que alguien pueda maquetar sin poder publicar.
  @Post('publish')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_PUBLICAR')
  @ApiOperation({ summary: 'Publicar configuración actual creando una versión congelada' })
  publish(@GetUser() user: LoginUserInfo) {
    return this.service.publish(user.empresa_id, user.id);
  }

  // La tienda muestra el borrador sólo con este token (30 min, de esta empresa).
  @Post('preview-token')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_VER')
  @ApiOperation({ summary: 'Token para ver el borrador en la tienda (vista previa)' })
  previewToken(@GetUser() user: LoginUserInfo) {
    return { token: crearTokenVistaPrevia(user.empresa_id, envs.jwtSecret) };
  }

  @Get('opciones')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_VER')
  @ApiOperation({ summary: 'Sucursales, depósitos y listas de precios para los selectores del panel' })
  getOpciones(@GetUser() user: LoginUserInfo) {
    return this.service.getOpciones(user.empresa_id);
  }

  @Get('equipo')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_VER')
  @ApiOperation({ summary: 'Estado de los perfiles operativos de la tienda (existen / usuarios)' })
  getEquipo(@GetUser() user: LoginUserInfo) {
    return this.service.getEquipo(user.empresa_id);
  }

  @Post('equipo/preparar')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_EDITAR')
  @ApiOperation({ summary: 'Crear los perfiles operativos de la tienda (Operador/Despacho/Mostrador)' })
  prepararEquipo(@GetUser() user: LoginUserInfo) {
    return this.service.prepararEquipo(user.empresa_id);
  }

  @Get('pagos-estado')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_VER')
  @ApiOperation({ summary: 'Estado de Novasis Pay (configurado / activo / modo) para el checklist' })
  getPagosEstado(@GetUser() user: LoginUserInfo) {
    return this.service.getPagosEstado(user.empresa_id);
  }

  @Get('stock-cobertura')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_VER')
  @ApiOperation({ summary: 'Cobertura de stock: productos publicados con stock en el depósito dado' })
  getStockCobertura(@GetUser() user: LoginUserInfo, @Query('depositoId') depositoId?: string) {
    return this.service.getStockCobertura(user.empresa_id, depositoId || undefined);
  }

  @Post('notificaciones/test')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_EDITAR')
  @ApiOperation({ summary: 'Enviar un email de prueba de una plantilla de notificación' })
  enviarNotificacionPrueba(
    @Body() body: { template: string; email?: string },
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.enviarNotificacionPrueba(user.empresa_id, body.template, body.email);
  }

  @Get('versions')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_VER')
  @ApiOperation({ summary: 'Listar versiones publicadas' })
  listVersions(@GetUser() user: LoginUserInfo) {
    return this.service.listVersions(user.empresa_id);
  }

  @Post('rollback/:version')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_PUBLICAR')
  @ApiOperation({ summary: 'Restaurar una versión publicada anterior' })
  rollback(@Param('version', ParseIntPipe) version: number, @GetUser() user: LoginUserInfo) {
    return this.service.rollback(user.empresa_id, version, user.id);
  }

  // ── Imágenes de categorías ────────────────────────────────────────

  @Get('categorias')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_VER')
  @ApiOperation({ summary: 'Listar categorías con imagen custom actual' })
  listCategorias(@GetUser() user: LoginUserInfo) {
    return this.service.listCategorias(user.empresa_id);
  }

  @Post('imagen')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_EDITAR')
  @ApiOperation({ summary: 'Subir una imagen de la tienda (hero, promo…) optimizada a WebP; devuelve la URL' })
  @UseInterceptors(FileInterceptor('file', { limits: { fileSize: 8 * 1024 * 1024 } }))
  uploadStoreImage(
    @UploadedFile() file: Express.Multer.File,
    @GetUser() user: LoginUserInfo,
    @Query('slot') slot?: string,
  ) {
    return this.service.uploadStoreImage(user.empresa_id, slot, file);
  }

  @Post('categorias/:id/imagen')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_EDITAR')
  @ApiOperation({ summary: 'Subir imagen para una categoría (WebP, S3)' })
  @UseInterceptors(FileInterceptor('file', { limits: { fileSize: 8 * 1024 * 1024 } }))
  uploadCategoryImage(
    @Param('id') categoriaId: string,
    @UploadedFile() file: Express.Multer.File,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.service.uploadCategoryImage(user.empresa_id, categoriaId, file);
  }

  @Delete('categorias/:id/imagen')
  @RequirePermission('ECOMMERCE', 'EC_CFG_TIENDA_EDITAR')
  @ApiOperation({ summary: 'Eliminar imagen custom de una categoría' })
  deleteCategoryImage(@Param('id') categoriaId: string, @GetUser() user: LoginUserInfo) {
    return this.service.deleteCategoryImage(user.empresa_id, categoriaId);
  }
}
