import { Body, Controller, Get, Param, Patch, Post, Put, Query, UseGuards, ValidationPipe } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
import { RequireModule } from 'src/auth/decorators/require-module.decorator';
import { RequirePermission } from 'src/auth/decorators/require-permission.decorator';
import type { LoginUserInfo } from 'src/auth/dto/login.dto';
import { GetUser } from 'src/auth/get-user.decorator';
import { ModuleGuard } from 'src/auth/guards/module.guard';
import { PermissionGuard } from 'src/auth/guards/permission.guard';
import { CreatePlaneDto } from './dto/create-plane.dto';
import { UpdatePlaneDto } from './dto/update-plane.dto';
import { PlanesService } from './planes.service';

@ApiTags('Planes')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('PLAN_SUSCRIPCION')
@Controller({ path: 'planes', version: '1' })
export class PlanesController {
  constructor(private readonly planesService: PlanesService) {}

  // ── GET /planes ──
  @Get()
  @RequirePermission('PLAN_SUSCRIPCION', 'SUS_PLA_PLAN_VER')
  @ApiOperation({ summary: 'Listar todos los planes' })
  @ApiQuery({
    name: 'includeInactive',
    required: false,
    description: 'Incluir planes inactivos (default: false)',
  })
  @ApiResponse({ status: 200, description: 'Planes obtenidos correctamente' })
  findAll(@Query('includeInactive') includeInactive?: string) {
    return this.planesService.findAll(includeInactive === 'true');
  }

  // ── GET /planes/estadisticas ──
  @Get('estadisticas')
  @RequirePermission('PLAN_SUSCRIPCION', 'SUS_PLA_PLAN_VER')
  @ApiOperation({ summary: 'Obtener estadísticas de planes' })
  @ApiResponse({ status: 200, description: 'Estadísticas obtenidas' })
  getEstadisticas() {
    return this.planesService.getEstadisticas();
  }

  // ── GET /planes/modulos ──
  @Get('modulos')
  @RequirePermission('PLAN_SUSCRIPCION', 'SUS_PLA_PLAN_VER')
  @ApiOperation({ summary: 'Obtener módulos disponibles del sistema (legacy plano)' })
  @ApiResponse({ status: 200, description: 'Módulos obtenidos' })
  getModulos() {
    return this.planesService.getModulosDisponibles();
  }

  // ── GET /planes/jerarquia ──
  @Get('jerarquia')
  @RequirePermission('PLAN_SUSCRIPCION', 'SUS_PLA_PLAN_VER')
  @ApiOperation({
    summary: 'Jerarquía de módulos raíz con submódulos incluidos y addons',
  })
  @ApiResponse({ status: 200, description: 'Jerarquía obtenida' })
  getJerarquia() {
    return this.planesService.getJerarquiaDisponible();
  }

  // ── GET /planes/:id ──
  @Get(':id')
  @RequirePermission('PLAN_SUSCRIPCION', 'SUS_PLA_PLAN_VER')
  @ApiOperation({ summary: 'Obtener detalle de un plan' })
  @ApiParam({ name: 'id', description: 'ID del plan' })
  @ApiResponse({ status: 200, description: 'Plan obtenido' })
  @ApiResponse({ status: 404, description: 'Plan no encontrado' })
  findOne(@Param('id') id: string) {
    return this.planesService.findOne(id);
  }

  // ── POST /planes ──
  @Post()
  @RequirePermission('PLAN_SUSCRIPCION', 'SUS_PLA_PLAN_EDITAR')
  @ApiOperation({ summary: 'Crear un nuevo plan' })
  @ApiBody({ type: CreatePlaneDto })
  @ApiResponse({ status: 201, description: 'Plan creado correctamente' })
  @ApiResponse({
    status: 400,
    description: 'Datos inválidos o código duplicado',
  })
  create(
    @Body(new ValidationPipe({ whitelist: true, transform: true }))
    dto: CreatePlaneDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.planesService.create(dto, user?.username, user?.id, user?.empresa_id);
  }

  // ── PUT /planes/:id ──
  @Put(':id')
  @RequirePermission('PLAN_SUSCRIPCION', 'SUS_PLA_PLAN_EDITAR')
  @ApiOperation({ summary: 'Actualizar un plan existente' })
  @ApiParam({ name: 'id', description: 'ID del plan' })
  @ApiBody({ type: UpdatePlaneDto })
  @ApiResponse({ status: 200, description: 'Plan actualizado correctamente' })
  @ApiResponse({ status: 404, description: 'Plan no encontrado' })
  update(
    @Param('id') id: string,
    @Body(new ValidationPipe({ whitelist: true, transform: true }))
    dto: UpdatePlaneDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.planesService.update(id, dto, user?.username, user?.id, user?.empresa_id);
  }

  // ── PATCH /planes/:id/toggle ──
  @Patch(':id/toggle')
  @RequirePermission('PLAN_SUSCRIPCION', 'SUS_PLA_PLAN_EDITAR')
  @ApiOperation({ summary: 'Activar/Desactivar un plan' })
  @ApiParam({ name: 'id', description: 'ID del plan' })
  @ApiResponse({ status: 200, description: 'Estado del plan cambiado' })
  @ApiResponse({
    status: 400,
    description: 'No se puede desactivar si tiene suscripciones activas',
  })
  toggleActive(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.planesService.toggleActive(id, user?.id, user?.empresa_id);
  }
}
