import {
    Body,
    Controller,
    Get,
    HttpException,
    HttpStatus,
    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 { SuscripcionesService } from 'src/suscripciones/suscripciones.service';
import { ComisionesService } from './comisiones.service';
import { JerarquiaEmpresasService } from './jerarquia-empresas.service';

@ApiTags('Comisiones y Jerarquía Empresarial')
@Controller({ path: 'empresas/comisiones', version: '1' })
@UseGuards(AuthGuard('jwt'), ModuleGuard, PermissionGuard)
@RequireModule('ADMINISTRACION')
@RequirePermission('ADMINISTRACION', 'ADM_CFG_CONFIG_VER')
export class ComisionesController {
  constructor(
    private readonly comisionesService: ComisionesService,
    private readonly jerarquiaService: JerarquiaEmpresasService,
    private readonly suscripcionesService: SuscripcionesService,
  ) {}

  @Get('health')
  @ApiOperation({ summary: 'Verificar el estado del servicio de comisiones' })
  @ApiResponse({
    status: 200,
    description: 'Servicio de comisiones funcionando correctamente',
  })
  healthCheck() {
    return { status: 'ok', message: 'Comisiones controller is working' };
  }

  @Post('generar/:suscripcionId')
  @RequirePermission('ADMINISTRACION', 'ADM_CFG_CONFIG_EDITAR')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Generar comisiones para una suscripción' })
  @ApiParam({ name: 'suscripcionId', description: 'ID de la suscripción' })
  @ApiBody({ description: 'Tipo de comisión (opcional)' })
  @ApiResponse({
    status: 200,
    description: 'Comisiones generadas exitosamente',
  })
  async generarComisiones(
    @Param('suscripcionId') suscripcionId: string,
    @Body(ValidationPipe) body: { tipo_comision?: string },
    @GetUser() user: LoginUserInfo,
  ) {
    try {
      await this.comisionesService.generarComisiones(suscripcionId, body.tipo_comision || 'mensual');
      return {
        success: true,
        message: 'Comisiones generadas exitosamente',
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al generar comisiones';
      throw new HttpException(
        {
          success: false,
          message,
          error: 'Bad Request',
        },
        HttpStatus.BAD_REQUEST,
      );
    }
  }

  @Post('generar-mensuales')
  @RequirePermission('ADMINISTRACION', 'ADM_CFG_CONFIG_EDITAR')
  @ApiBearerAuth()
  @ApiOperation({
    summary: 'Generar comisiones mensuales para todas las suscripciones activas',
  })
  @ApiResponse({
    status: 200,
    description: 'Comisiones mensuales generadas exitosamente',
  })
  async generarComisionesMensuales(@GetUser() user: LoginUserInfo) {
    try {
      const resultado = await this.comisionesService.generarComisionesMensuales();
      return {
        success: true,
        message: 'Proceso de comisiones mensuales completado',
        data: resultado,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al generar comisiones mensuales';
      throw new HttpException(
        {
          success: false,
          message,
          error: 'Bad Request',
        },
        HttpStatus.BAD_REQUEST,
      );
    }
  }

  @Get('reseller/:resellerEmpresaId/resumen')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Obtener resumen de comisiones de un reseller' })
  @ApiParam({
    name: 'resellerEmpresaId',
    description: 'ID de la empresa reseller',
  })
  @ApiResponse({
    status: 200,
    description: 'Resumen de comisiones obtenido exitosamente',
  })
  async getResumenComisionesReseller(
    @Param('resellerEmpresaId') resellerEmpresaId: string,
    @GetUser() user: LoginUserInfo,
  ) {
    try {
      const resumen = await this.comisionesService.getResumenComisionesReseller(resellerEmpresaId);
      return {
        success: true,
        data: resumen,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener resumen de comisiones';
      throw new HttpException(
        {
          success: false,
          message,
          error: 'Bad Request',
        },
        HttpStatus.BAD_REQUEST,
      );
    }
  }

  @Get('reseller/:resellerEmpresaId/pendientes')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Obtener comisiones pendientes de un reseller' })
  @ApiParam({
    name: 'resellerEmpresaId',
    description: 'ID de la empresa reseller',
  })
  @ApiResponse({
    status: 200,
    description: 'Comisiones pendientes obtenidas exitosamente',
  })
  async getComisionesPendientes(@Param('resellerEmpresaId') resellerEmpresaId: string, @GetUser() user: LoginUserInfo) {
    try {
      const pendientes = await this.comisionesService.getComisionesPendientes(resellerEmpresaId);
      return {
        success: true,
        data: pendientes,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener comisiones pendientes';
      throw new HttpException(
        {
          success: false,
          message,
          error: 'Bad Request',
        },
        HttpStatus.BAD_REQUEST,
      );
    }
  }

  @Get('reseller/:resellerEmpresaId/historial')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Obtener historial de comisiones pagadas' })
  @ApiParam({
    name: 'resellerEmpresaId',
    description: 'ID de la empresa reseller',
  })
  @ApiQuery({
    name: 'limite',
    description: 'Límite de resultados',
    required: false,
  })
  @ApiResponse({
    status: 200,
    description: 'Historial de comisiones obtenido exitosamente',
  })
  async getHistorialComisiones(
    @GetUser() user: LoginUserInfo,
    @Param('resellerEmpresaId') resellerEmpresaId: string,
    @Query('limite') limite?: string,
  ) {
    try {
      const limiteNum = limite ? parseInt(limite, 10) : 50;
      const historial = await this.comisionesService.getHistorialComisiones(resellerEmpresaId, limiteNum);
      return {
        success: true,
        data: historial,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener historial de comisiones';
      throw new HttpException(
        {
          success: false,
          message,
          error: 'Bad Request',
        },
        HttpStatus.BAD_REQUEST,
      );
    }
  }

  @Put('marcar-pagadas')
  @RequirePermission('ADMINISTRACION', 'ADM_CFG_CONFIG_EDITAR')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Marcar comisiones como pagadas' })
  @ApiBody({ description: 'IDs de comisiones y datos de pago' })
  @ApiResponse({
    status: 200,
    description: 'Comisiones marcadas como pagadas exitosamente',
  })
  async marcarComisionesPagadas(
    @Body(ValidationPipe)
    body: {
      comision_ids: string[];
      metodo_pago?: string;
      referencia_pago?: string;
    },
    @GetUser() user: LoginUserInfo,
  ) {
    try {
      await this.comisionesService.marcarComisionesPagadas(body.comision_ids, body.metodo_pago, body.referencia_pago);
      return {
        success: true,
        message: 'Comisiones marcadas como pagadas exitosamente',
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al marcar comisiones como pagadas';
      throw new HttpException(
        {
          success: false,
          message,
          error: 'Bad Request',
        },
        HttpStatus.BAD_REQUEST,
      );
    }
  }

  // ============================================================
  // Endpoints para HOLDING — Vista global de comisiones
  // ============================================================

  @Get('holding/:holdingEmpresaId/resumen-comisiones')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Resumen global de comisiones para el holding' })
  @ApiParam({
    name: 'holdingEmpresaId',
    description: 'ID de la empresa holding',
  })
  @ApiResponse({ status: 200, description: 'Resumen global de comisiones' })
  async getResumenComisionesHolding(
    @Param('holdingEmpresaId') holdingEmpresaId: string,
    @GetUser() _user: LoginUserInfo,
  ) {
    try {
      const resumen = await this.comisionesService.getResumenComisionesHolding(holdingEmpresaId);
      return { success: true, data: resumen };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener resumen de comisiones';
      throw new HttpException({ success: false, message, error: 'Bad Request' }, HttpStatus.BAD_REQUEST);
    }
  }

  @Get('holding/:holdingEmpresaId/agrupadas')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Comisiones agrupadas por reseller/beneficiario' })
  @ApiParam({
    name: 'holdingEmpresaId',
    description: 'ID de la empresa holding',
  })
  @ApiQuery({
    name: 'estado',
    required: false,
    description: 'Filtrar por estado: pendiente, pagada, todos',
  })
  @ApiResponse({
    status: 200,
    description: 'Comisiones agrupadas por reseller',
  })
  async getComisionesAgrupadas(
    @Param('holdingEmpresaId') holdingEmpresaId: string,
    @Query('estado') estado: string,
    @GetUser() _user: LoginUserInfo,
  ) {
    try {
      const agrupadas = await this.comisionesService.getComisionesAgrupadasPorReseller(holdingEmpresaId, estado);
      return { success: true, data: agrupadas };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener comisiones agrupadas';
      throw new HttpException({ success: false, message, error: 'Bad Request' }, HttpStatus.BAD_REQUEST);
    }
  }

  @Get('holding/:holdingEmpresaId/detalle/:resellerEmpresaId')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Detalle de comisiones de un reseller específico' })
  @ApiParam({
    name: 'holdingEmpresaId',
    description: 'ID de la empresa holding',
  })
  @ApiParam({
    name: 'resellerEmpresaId',
    description: 'ID de la empresa reseller/beneficiario',
  })
  @ApiQuery({
    name: 'estado',
    required: false,
    description: 'Filtrar por estado',
  })
  @ApiQuery({
    name: 'limite',
    required: false,
    description: 'Límite de resultados',
  })
  @ApiResponse({
    status: 200,
    description: 'Detalle de comisiones del reseller',
  })
  async getDetalleComisionesReseller(
    @Param('holdingEmpresaId') _holdingEmpresaId: string,
    @Param('resellerEmpresaId') resellerEmpresaId: string,
    @Query('estado') estado: string,
    @Query('limite') limite: string,
    @GetUser() _user: LoginUserInfo,
  ) {
    try {
      const detalle = await this.comisionesService.getComisionesDeReseller(resellerEmpresaId, {
        estado,
        limite: limite ? parseInt(limite, 10) : undefined,
      });
      return { success: true, data: detalle };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener detalle de comisiones';
      throw new HttpException({ success: false, message, error: 'Bad Request' }, HttpStatus.BAD_REQUEST);
    }
  }

  @Get('holding/:holdingEmpresaId/historial-pagos')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Historial de pagos realizados por el holding' })
  @ApiParam({
    name: 'holdingEmpresaId',
    description: 'ID de la empresa holding',
  })
  @ApiQuery({
    name: 'limite',
    required: false,
    description: 'Límite de resultados',
  })
  @ApiResponse({ status: 200, description: 'Historial de pagos' })
  async getHistorialPagosHolding(
    @Param('holdingEmpresaId') holdingEmpresaId: string,
    @Query('limite') limite: string,
    @GetUser() _user: LoginUserInfo,
  ) {
    try {
      const historial = await this.comisionesService.getHistorialPagosHolding(
        holdingEmpresaId,
        limite ? parseInt(limite, 10) : 50,
      );
      return { success: true, data: historial };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener historial de pagos';
      throw new HttpException({ success: false, message, error: 'Bad Request' }, HttpStatus.BAD_REQUEST);
    }
  }

  @Get('jerarquia/:empresaId')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Obtener jerarquía completa de una empresa' })
  @ApiParam({ name: 'empresaId', description: 'ID de la empresa' })
  @ApiResponse({ status: 200, description: 'Jerarquía obtenida exitosamente' })
  async getJerarquiaCompleta(@Param('empresaId') empresaId: string, @GetUser() user: LoginUserInfo) {
    try {
      console.log('llego');
      const jerarquia = await this.jerarquiaService.getJerarquiaCompleta(empresaId);
      return {
        success: true,
        data: jerarquia,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener jerarquía empresarial';
      throw new HttpException(
        {
          success: false,
          message,
          error: 'Bad Request',
        },
        HttpStatus.BAD_REQUEST,
      );
    }
  }

  @Get('jerarquia/:empresaId/hijos')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Obtener hijos directos de una empresa' })
  @ApiParam({ name: 'empresaId', description: 'ID de la empresa' })
  @ApiQuery({
    name: 'incluir_inactivos',
    description: 'Incluir empresas inactivas',
    required: false,
  })
  @ApiResponse({
    status: 200,
    description: 'Hijos directos obtenidos exitosamente',
  })
  async getHijosDirectos(
    @GetUser() user: LoginUserInfo,
    @Param('empresaId') empresaId: string,
    @Query('incluir_inactivos') incluirInactivos?: string,
  ) {
    try {
      const incluir = incluirInactivos === 'true';
      const hijos = await this.jerarquiaService.getHijosDirectos(empresaId, incluir);
      return {
        success: true,
        data: hijos,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener hijos directos';
      throw new HttpException(
        {
          success: false,
          message,
          error: 'Bad Request',
        },
        HttpStatus.BAD_REQUEST,
      );
    }
  }

  @Get('jerarquia/:empresaId/holding')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Obtener holding de una empresa' })
  @ApiParam({ name: 'empresaId', description: 'ID de la empresa' })
  @ApiResponse({ status: 200, description: 'Holding obtenido exitosamente' })
  async getHolding(@Param('empresaId') empresaId: string, @GetUser() user: LoginUserInfo) {
    try {
      const holding = await this.jerarquiaService.getHolding(empresaId);
      return {
        success: true,
        data: holding,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener holding';
      throw new HttpException(
        {
          success: false,
          message,
          error: 'Bad Request',
        },
        HttpStatus.BAD_REQUEST,
      );
    }
  }

  @Get('reseller/:resellerEmpresaId/validar-limites')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Validar límites de un reseller' })
  @ApiParam({
    name: 'resellerEmpresaId',
    description: 'ID de la empresa reseller',
  })
  @ApiResponse({ status: 200, description: 'Límites validados exitosamente' })
  async validarLimitesReseller(@Param('resellerEmpresaId') resellerEmpresaId: string, @GetUser() user: LoginUserInfo) {
    try {
      const limites = await this.jerarquiaService.validarLimitesReseller(resellerEmpresaId);
      return {
        success: true,
        data: limites,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al validar límites del reseller';
      throw new HttpException(
        {
          success: false,
          message,
          error: 'Bad Request',
        },
        HttpStatus.BAD_REQUEST,
      );
    }
  }

  @Get('reseller/:resellerEmpresaId/metricas')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Obtener métricas de un reseller' })
  @ApiParam({
    name: 'resellerEmpresaId',
    description: 'ID de la empresa reseller',
  })
  @ApiResponse({ status: 200, description: 'Métricas obtenidas exitosamente' })
  async getMetricasReseller(@Param('resellerEmpresaId') resellerEmpresaId: string, @GetUser() user: LoginUserInfo) {
    try {
      const metricas = await this.jerarquiaService.getMetricasReseller(resellerEmpresaId);
      return {
        success: true,
        data: metricas,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener métricas del reseller';
      throw new HttpException(
        {
          success: false,
          message,
          error: 'Bad Request',
        },
        HttpStatus.BAD_REQUEST,
      );
    }
  }

  @Get('holding/:holdingEmpresaId/metricas')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Obtener métricas de un holding' })
  @ApiParam({
    name: 'holdingEmpresaId',
    description: 'ID de la empresa holding',
  })
  @ApiResponse({ status: 200, description: 'Métricas obtenidas exitosamente' })
  async getMetricasHolding(@Param('holdingEmpresaId') holdingEmpresaId: string, @GetUser() user: LoginUserInfo) {
    try {
      const metricas = await this.jerarquiaService.getMetricasHolding(holdingEmpresaId);
      return {
        success: true,
        data: metricas,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener métricas del holding';
      throw new HttpException(
        {
          success: false,
          message,
          error: 'Bad Request',
        },
        HttpStatus.BAD_REQUEST,
      );
    }
  }

  @Get('holding/:holdingEmpresaId/dashboard')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Dashboard ejecutivo completo del holding' })
  @ApiParam({
    name: 'holdingEmpresaId',
    description: 'ID de la empresa holding',
  })
  @ApiResponse({ status: 200, description: 'Dashboard obtenido exitosamente' })
  async getDashboardHolding(@Param('holdingEmpresaId') holdingEmpresaId: string, @GetUser() user: LoginUserInfo) {
    try {
      const dashboard = await this.jerarquiaService.getDashboardHolding(holdingEmpresaId);
      return {
        success: true,
        data: dashboard,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener dashboard del holding';
      const status = message.includes('no encontrad') ? HttpStatus.NOT_FOUND : HttpStatus.BAD_REQUEST;
      throw new HttpException(
        {
          success: false,
          message,
          error: 'Error',
        },
        status,
      );
    }
  }

  // ============================================================
  // Gestión de suscripciones para Holdings y Resellers
  // ============================================================

  @Get('suscripciones/:empresaId/subsidiarios')
  @ApiBearerAuth()
  @ApiOperation({
    summary: 'Listar suscripciones de subsidiarios de una empresa (holding/reseller)',
  })
  @ApiParam({
    name: 'empresaId',
    description: 'ID de la empresa holding o reseller',
  })
  @ApiQuery({
    name: 'estado',
    required: false,
    description: 'Filtrar por estado: Activo, Pausado, Cancelado, sin_suscripcion',
  })
  @ApiQuery({
    name: 'busqueda',
    required: false,
    description: 'Buscar por nombre o RUC',
  })
  @ApiQuery({
    name: 'tipo',
    required: false,
    description: 'Filtrar por tipo: subsidiario, reseller',
  })
  @ApiQuery({
    name: 'page',
    required: false,
    description: 'Número de página (default: 1)',
  })
  @ApiQuery({
    name: 'limit',
    required: false,
    description: 'Resultados por página (default: 20, max: 100)',
  })
  @ApiResponse({
    status: 200,
    description: 'Suscripciones de subsidiarios obtenidas exitosamente',
  })
  async getSuscripcionesSubsidiarios(
    @Param('empresaId') empresaId: string,
    @GetUser() _user: LoginUserInfo,
    @Query('estado') estado?: string,
    @Query('busqueda') busqueda?: string,
    @Query('tipo') tipo?: string,
    @Query('page') page?: string,
    @Query('limit') limit?: string,
  ) {
    try {
      const resultado = await this.suscripcionesService.getSuscripcionesSubsidiarios(empresaId, {
        estado,
        busqueda,
        tipo,
        page: page ? parseInt(page, 10) : undefined,
        limit: limit ? parseInt(limit, 10) : undefined,
      });
      return { success: true, data: resultado };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener suscripciones de subsidiarios';
      const status = error?.status || HttpStatus.BAD_REQUEST;
      throw new HttpException({ success: false, message, error: 'Bad Request' }, status);
    }
  }

  @Get('suscripciones/planes-disponibles')
  @ApiBearerAuth()
  @ApiOperation({
    summary: 'Listar planes disponibles para asignar a subsidiarios',
  })
  @ApiResponse({
    status: 200,
    description: 'Planes disponibles obtenidos exitosamente',
  })
  async getPlanesDisponibles(@GetUser() _user: LoginUserInfo) {
    try {
      const planes = await this.suscripcionesService.getPlanesDisponibles();
      return { success: true, data: planes };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtenes disponibles';
      throw new HttpException({ success: false, message, error: 'Bad Request' }, HttpStatus.BAD_REQUEST);
    }
  }

  @Post('suscripciones/:empresaId/subsidiarios/:subsidiarioId')
  @RequirePermission('ADMINISTRACION', 'ADM_CFG_CONFIG_EDITAR')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Crear suscripción para un subsidiario' })
  @ApiParam({
    name: 'empresaId',
    description: 'ID de la empresa holding o reseller (padre)',
  })
  @ApiParam({
    name: 'subsidiarioId',
    description: 'ID de la empresa subsidiaria',
  })
  @ApiBody({ description: 'Datos de la suscripción a crear' })
  @ApiResponse({ status: 201, description: 'Suscripción creada exitosamente' })
  async crearSuscripcionParaSubsidiario(
    @Param('empresaId') empresaId: string,
    @Param('subsidiarioId') subsidiarioId: string,
    @Body()
    body: {
      plan_id: string;
      precio_venta?: number;
      comision_porcentaje?: number;
      descripcion?: string;
      dias_vigencia?: number;
      fecha_inicio?: string;
      dia_cobro?: number;
      notas_comerciales?: string;
    },
    @GetUser() _user: LoginUserInfo,
  ) {
    try {
      const suscripcion = await this.suscripcionesService.crearSuscripcionParaSubsidiario(
        empresaId,
        subsidiarioId,
        body.plan_id,
        {
          precio_venta: body.precio_venta,
          comision_porcentaje: body.comision_porcentaje,
          descripcion: body.descripcion,
          dias_vigencia: body.dias_vigencia,
          fecha_inicio: body.fecha_inicio ? new Date(body.fecha_inicio) : undefined,
          dia_cobro: body.dia_cobro,
          notas_comerciales: body.notas_comerciales,
        },
      );
      return {
        success: true,
        message: 'Suscripción creada exitosamente',
        data: suscripcion,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al crear suscripción';
      const status = error?.status || HttpStatus.BAD_REQUEST;
      throw new HttpException({ success: false, message, error: 'Bad Request' }, status);
    }
  }

  @Put('suscripciones/:empresaId/editar/:suscripcionId')
  @RequirePermission('ADMINISTRACION', 'ADM_CFG_CONFIG_EDITAR')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Editar una suscripción existente' })
  @ApiParam({
    name: 'empresaId',
    description: 'ID de la empresa holding o reseller (padre)',
  })
  @ApiParam({
    name: 'suscripcionId',
    description: 'ID de la suscripción a editar',
  })
  @ApiBody({ description: 'Datos a actualizar' })
  @ApiResponse({
    status: 200,
    description: 'Suscripción actualizada exitosamente',
  })
  async editarSuscripcion(
    @Param('empresaId') empresaId: string,
    @Param('suscripcionId') suscripcionId: string,
    @Body()
    body: {
      precio_venta?: number;
      descripcion?: string;
      fecha_fin?: string;
      comision_aplicada?: number;
      fecha_inicio?: string;
      dia_cobro?: number | null;
      notas_comerciales?: string;
    },
    @GetUser() _user: LoginUserInfo,
  ) {
    try {
      const suscripcion = await this.suscripcionesService.editarSuscripcion(suscripcionId, empresaId, {
        precio_venta: body.precio_venta,
        descripcion: body.descripcion,
        fecha_fin: body.fecha_fin ? new Date(body.fecha_fin) : undefined,
        comision_aplicada: body.comision_aplicada,
        fecha_inicio: body.fecha_inicio ? new Date(body.fecha_inicio) : undefined,
        dia_cobro: body.dia_cobro,
        notas_comerciales: body.notas_comerciales,
      });
      return {
        success: true,
        message: 'Suscripción actualizada exitosamente',
        data: suscripcion,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al editar suscripción';
      const status = error?.status || HttpStatus.BAD_REQUEST;
      throw new HttpException({ success: false, message, error: 'Bad Request' }, status);
    }
  }

  // ============================================================
  // Gestión de módulos adicionales por suscripción
  // ============================================================

  @Get('suscripciones/:empresaId/empresa-modulos/:subsidiarioId')
  @ApiBearerAuth()
  @ApiOperation({
    summary: 'Obtener módulos de una empresa subsidiaria (busca suscripción activa automáticamente)',
  })
  @ApiParam({
    name: 'empresaId',
    description: 'ID de la empresa holding o reseller (padre)',
  })
  @ApiParam({
    name: 'subsidiarioId',
    description: 'ID de la empresa subsidiaria',
  })
  @ApiResponse({
    status: 200,
    description: 'Módulos de la empresa obtenidos exitosamente',
  })
  async getModulosByEmpresa(
    @Param('empresaId') empresaId: string,
    @Param('subsidiarioId') subsidiarioId: string,
    @GetUser() _user: LoginUserInfo,
  ) {
    try {
      return await this.suscripcionesService.getModulosByEmpresa(subsidiarioId, empresaId);
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener módulos de la empresa';
      const status = error?.status || HttpStatus.BAD_REQUEST;
      throw new HttpException({ success: false, message, error: 'Bad Request' }, status);
    }
  }

  @Put('suscripciones/:empresaId/empresa-modulos/:subsidiarioId')
  @RequirePermission('ADMINISTRACION', 'ADM_CFG_CONFIG_EDITAR')
  @ApiBearerAuth()
  @ApiOperation({
    summary: 'Agregar o quitar módulos adicionales de una empresa subsidiaria (busca suscripción activa)',
  })
  @ApiParam({
    name: 'empresaId',
    description: 'ID de la empresa holding o reseller (padre)',
  })
  @ApiParam({
    name: 'subsidiarioId',
    description: 'ID de la empresa subsidiaria',
  })
  @ApiBody({
    description: 'Array de IDs de módulos que deben quedar como adicionales',
  })
  @ApiResponse({
    status: 200,
    description: 'Módulos adicionales actualizados exitosamente',
  })
  async gestionarModulosByEmpresa(
    @Param('empresaId') empresaId: string,
    @Param('subsidiarioId') subsidiarioId: string,
    @Body() body: { modulos_adicionales: string[] },
    @GetUser() user: LoginUserInfo,
  ) {
    try {
      if (!Array.isArray(body.modulos_adicionales)) {
        throw new HttpException(
          {
            success: false,
            message: 'modulos_adicionales debe ser un array de IDs',
          },
          HttpStatus.BAD_REQUEST,
        );
      }
      const resultado = await this.suscripcionesService.gestionarModulosByEmpresa(
        subsidiarioId,
        empresaId,
        body.modulos_adicionales,
        user.id,
      );
      return {
        success: true,
        message: 'Módulos actualizados exitosamente',
        data: resultado,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al gestionar módulos adicionales';
      const status = error?.status || HttpStatus.BAD_REQUEST;
      throw new HttpException({ success: false, message, error: 'Bad Request' }, status);
    }
  }

  @Get('suscripciones/:empresaId/modulos/:suscripcionId')
  @ApiBearerAuth()
  @ApiOperation({
    summary: 'Obtener módulos de una suscripción (incluidos del plan + adicionales)',
  })
  @ApiParam({
    name: 'empresaId',
    description: 'ID de la empresa holding o reseller (padre)',
  })
  @ApiParam({ name: 'suscripcionId', description: 'ID de la suscripción' })
  @ApiResponse({
    status: 200,
    description: 'Módulos de la suscripción obtenidos exitosamente',
  })
  async getModulosSuscripcion(
    @Param('empresaId') empresaId: string,
    @Param('suscripcionId') suscripcionId: string,
    @GetUser() _user: LoginUserInfo,
  ) {
    try {
      return await this.suscripcionesService.getModulosSuscripcion(suscripcionId, empresaId);
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al obtener módulos de la suscripción';
      const status = error?.status || HttpStatus.BAD_REQUEST;
      throw new HttpException({ success: false, message, error: 'Bad Request' }, status);
    }
  }

  @Put('suscripciones/:empresaId/modulos/:suscripcionId')
  @RequirePermission('ADMINISTRACION', 'ADM_CFG_CONFIG_EDITAR')
  @ApiBearerAuth()
  @ApiOperation({
    summary: 'Agregar o quitar módulos adicionales de una suscripción',
  })
  @ApiParam({
    name: 'empresaId',
    description: 'ID de la empresa holding o reseller (padre)',
  })
  @ApiParam({ name: 'suscripcionId', description: 'ID de la suscripción' })
  @ApiBody({
    description: 'Array de IDs de módulos que deben quedar como adicionales (los incluidos en el plan no se afectan)',
  })
  @ApiResponse({
    status: 200,
    description: 'Módulos adicionales actualizados exitosamente',
  })
  async gestionarModulosAdicionales(
    @Param('empresaId') empresaId: string,
    @Param('suscripcionId') suscripcionId: string,
    @Body() body: { modulos_adicionales: string[] },
    @GetUser() user: LoginUserInfo,
  ) {
    try {
      if (!Array.isArray(body.modulos_adicionales)) {
        throw new HttpException(
          {
            success: false,
            message: 'modulos_adicionales debe ser un array de IDs',
          },
          HttpStatus.BAD_REQUEST,
        );
      }
      const resultado = await this.suscripcionesService.gestionarModulosAdicionales(
        suscripcionId,
        empresaId,
        body.modulos_adicionales,
        user.id,
      );
      return {
        success: true,
        message: 'Módulos actualizados exitosamente',
        data: resultado,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al gestionar módulos adicionales';
      const status = error?.status || HttpStatus.BAD_REQUEST;
      throw new HttpException({ success: false, message, error: 'Bad Request' }, status);
    }
  }

  @Patch('jerarquia/:empresaId/suscripcion-estado')
  @RequirePermission('ADMINISTRACION', 'ADM_CFG_CONFIG_EDITAR')
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Cambiar estado de suscripción de una empresa por su ID' })
  @ApiParam({ name: 'empresaId', description: 'ID de la empresa subsidiaria' })
  @ApiBody({ description: 'Nuevo estado y observación opcional' })
  @ApiResponse({ status: 200, description: 'Estado actualizado exitosamente' })
  async cambiarEstadoSuscripcionEmpresa(
    @Param('empresaId') empresaId: string,
    @Body() body: { estado: string; observacion?: string },
    @GetUser() _user: LoginUserInfo,
  ) {
    try {
      const result = await this.jerarquiaService.cambiarEstadoSuscripcion(
        empresaId,
        body.estado as any,
        body.observacion,
      );
      return {
        success: true,
        message: `Estado actualizado a ${body.estado}`,
        data: result,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al cambiar estado';
      const status = (error)?.status || HttpStatus.BAD_REQUEST;
      throw new HttpException({ success: false, message, error: 'Bad Request' }, status);
    }
  }

  @Patch('suscripciones/:empresaId/estado/:suscripcionId')
  @RequirePermission('ADMINISTRACION', 'ADM_CFG_CONFIG_EDITAR')
  @ApiBearerAuth()
  @ApiOperation({
    summary: 'Cambiar estado de una suscripción (Activar, Pausar, Cancelar)',
  })
  @ApiParam({
    name: 'empresaId',
    description: 'ID de la empresa holding o reseller (padre)',
  })
  @ApiParam({ name: 'suscripcionId', description: 'ID de la suscripción' })
  @ApiBody({ description: 'Nuevo estado' })
  @ApiResponse({ status: 200, description: 'Estado actualizado exitosamente' })
  async cambiarEstadoSuscripcion(
    @Param('empresaId') empresaId: string,
    @Param('suscripcionId') suscripcionId: string,
    @Body() body: { estado: string },
    @GetUser() _user: LoginUserInfo,
  ) {
    try {
      const suscripcion = await this.suscripcionesService.cambiarEstadoSuscripcion(
        suscripcionId,
        empresaId,
        body.estado,
      );
      return {
        success: true,
        message: `Suscripción ${body.estado.toLowerCase()} exitosamente`,
        data: suscripcion,
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Error al cambiar estado de suscripción';
      const status = error?.status || HttpStatus.BAD_REQUEST;
      throw new HttpException({ success: false, message, error: 'Bad Request' }, status);
    }
  }
}
