import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

async function main() {
  console.log('🌱 Iniciando seeding de datos...');

  // ═══════════════════════════════════════════════════════════════
  // 1. PRIVILEGIOS — Acciones que un usuario puede realizar
  // ═══════════════════════════════════════════════════════════════
  const privilegiosData = [
    { codigo: 'LEER', desc_privilegio: 'Leer/Consultar/Listar' },
    { codigo: 'CREAR', desc_privilegio: 'Crear/Registrar nuevo' },
    { codigo: 'EDITAR', desc_privilegio: 'Editar/Modificar/Actualizar' },
    { codigo: 'ELIMINAR', desc_privilegio: 'Eliminar/Desactivar' },
    { codigo: 'ANULAR', desc_privilegio: 'Anular documentos emitidos' },
    { codigo: 'PROCESAR', desc_privilegio: 'Procesar/Emitir/Timbrar DTE' },
    { codigo: 'EXPORTAR', desc_privilegio: 'Exportar datos a Excel/PDF' },
    { codigo: 'IMPRIMIR', desc_privilegio: 'Imprimir comprobantes/reportes' },
    { codigo: 'APERTURA_CIERRE', desc_privilegio: 'Apertura y cierre de caja' },
    { codigo: 'LIQUIDAR', desc_privilegio: 'Liquidar comisiones' },
    { codigo: 'ASIGNAR', desc_privilegio: 'Asignar recursos (sucursales, usuarios, etc.)' },
    // Presupuestos / Cotizaciones (M36–M43)
    { codigo: 'PRES_APROBAR', desc_privilegio: 'Aprobar presupuestos en el workflow interno' },
    { codigo: 'PRES_CONVERTIR', desc_privilegio: 'Convertir presupuestos a factura o pedido' },
    // Tesorería — privilegios específicos del módulo
    { codigo: 'TES_VER', desc_privilegio: 'Ver cuentas, saldos y movimientos de tesorería' },
    { codigo: 'TES_REGISTRAR_MOVIMIENTO', desc_privilegio: 'Registrar ingresos y egresos' },
    { codigo: 'TES_APROBAR_MOVIMIENTO', desc_privilegio: 'Aprobar movimientos que requieren autorización' },
    { codigo: 'TES_ANULAR_MOVIMIENTO', desc_privilegio: 'Anular movimientos confirmados' },
    { codigo: 'TES_TRANSFERIR', desc_privilegio: 'Registrar transferencias entre cuentas propias' },
    { codigo: 'TES_VER_REPORTES', desc_privilegio: 'Ver reportes de tesorería (flujo de caja, extracto, cartera)' },
    { codigo: 'TES_CONCILIAR', desc_privilegio: 'Importar extractos bancarios y conciliar movimientos' },
    { codigo: 'TES_CONFIG', desc_privilegio: 'Configurar parámetros del módulo de tesorería' },
    // RRHH — privilegios específicos del módulo
    { codigo: 'RRHH_EMPLEADOS_GESTION', desc_privilegio: 'RRHH — Gestionar empleados (alta, edición, baja)' },
    {
      codigo: 'RRHH_ESTRUCTURA_GESTION',
      desc_privilegio: 'RRHH — Gestionar cargos, departamentos, tipos y centros de costo',
    },
    { codigo: 'RRHH_CONCEPTOS_GESTION', desc_privilegio: 'RRHH — Gestionar conceptos de liquidación' },
    { codigo: 'RRHH_PARAMETROS_GESTION', desc_privilegio: 'RRHH — Gestionar parámetros del sistema (IPS, SMLV, etc.)' },
    { codigo: 'RRHH_LIQUIDACIONES_CALCULAR', desc_privilegio: 'RRHH — Calcular liquidaciones (pre-liquidación)' },
    { codigo: 'RRHH_LIQUIDACIONES_CERRAR', desc_privilegio: 'RRHH — Cerrar liquidaciones (inmutables)' },
    { codigo: 'RRHH_REPORTES_VER', desc_privilegio: 'RRHH — Ver reportes y planillas' },
    { codigo: 'RRHH_IPS_GENERAR', desc_privilegio: 'RRHH — Generar reporte IPS / REOP' },
    { codigo: 'RRHH_ACREDITACION_GENERAR', desc_privilegio: 'RRHH — Generar archivo de acreditación bancaria' },
    { codigo: 'RRHH_DESVINCULACIONES_GESTION', desc_privilegio: 'RRHH — Gestionar desvinculaciones y finiquitos' },
    { codigo: 'RRHH_AUDITORIA_VER', desc_privilegio: 'RRHH — Ver bitácora de auditoría del módulo' },
    // Recibos Multi-Factura — privilegios específicos
    { codigo: 'COB_REC_VER', desc_privilegio: 'Ver recibos multi-factura' },
    { codigo: 'COB_REC_CREAR', desc_privilegio: 'Crear recibo multi-factura' },
    { codigo: 'COB_REC_ANULAR', desc_privilegio: 'Anular recibo multi-factura (reversa total)' },
    {
      codigo: 'COB_REC_NC_FLEXIBLE',
      desc_privilegio: 'Aplicar notas de crédito en modo flexible (cualquier factura del cliente)',
    },
    { codigo: 'COB_REC_AJUSTE_MANUAL', desc_privilegio: 'Cerrar recibo con diferencia tipo ajuste manual' },
    { codigo: 'COB_REC_RETENCION_REGISTRAR', desc_privilegio: 'Registrar retenciones recibidas en un recibo' },
    { codigo: 'COB_REC_LIBRO_RETENCIONES', desc_privilegio: 'Ver y exportar libro de retenciones recibidas' },
    { codigo: 'COB_REC_OVERRIDE_FIFO', desc_privilegio: 'Sobreescribir imputación FIFO automática en el recibo' },
    {
      codigo: 'COB_REC_ASIGNAR_COBRADOR',
      desc_privilegio: 'Asignar manualmente un cobrador distinto al de la factura en un recibo',
    },
  ];

  // DEPRECATED: la creación de privilegios pasó a `src/seguridad/seeds/seguridad.seed-data.ts`
  // donde se asignan a su submódulo (privilegios.submodulo_id es NOT NULL).
  // Acá solo actualizamos descripciones de códigos legacy que ya existan en BD.
  console.log('📝 Actualizando descripciones de privilegios legacy...');
  for (const priv of privilegiosData) {
    const exists = await prisma.privilegios.findFirst({
      where: { codigo: priv.codigo },
    });
    if (exists) {
      await prisma.privilegios.update({
        where: { id: exists.id },
        data: { desc_privilegio: priv.desc_privilegio, active: true },
      });
      console.log(`  🔄 Privilegio "${priv.codigo}" actualizado`);
    }
  }

  // ═══════════════════════════════════════════════════════════════
  // 2. MÓDULOS — Cada funcionalidad controlable del sistema
  // ═══════════════════════════════════════════════════════════════
  //
  // Mapeados 1:1 contra rutas frontend y controllers backend.
  // Cada módulo puede asignarse a un plan (suscripción) y
  // cada (módulo + privilegio) puede asignarse a un perfil (rol).
  //
  // Privilegios aplicables por módulo:
  //   L=LEER  C=CREAR  E=EDITAR  X=ELIMINAR
  //   A=ANULAR  P=PROCESAR  EX=EXPORTAR  IM=IMPRIMIR
  // ═══════════════════════════════════════════════════════════════

  const modulosData = [
    // ── Panel principal ──────────────────────────────────────────
    // Ruta: /  y  /dashboard
    // Backend: app.controller (estadísticas)
    // Privilegios: L, EX
    { codigo: 'DASHBOARD', descripcion: 'Panel de control y estadísticas' },

    // ── Punto de Venta ───────────────────────────────────────────
    // Ruta: /pos  (POSRetailTemplate — venta rápida táctil)
    // Backend: facturas.controller (createFacturaAutomatico)
    // Privilegios: L, C (crear venta), IM (imprimir ticket)
    { codigo: 'POS_RETAIL', descripcion: 'Punto de venta rápido (POS)' },

    // Ruta: /pos-admin  (POSAdminTemplate — facturación avanzada)
    // Backend: facturas.controller (create, createFacturaAutomatico)
    // Privilegios: L, C, E, IM
    { codigo: 'POS_ADMIN', descripcion: 'Facturación avanzada (POS Admin)' },

    // ── Facturación y documentos ─────────────────────────────────
    // Ruta: /ventas (FacturasTab)
    // Backend: facturas.controller (findAll, findOne, enviarLoteMiddleware, pendientesEnvio)
    // Privilegios: L, C, E, A (anular), P (timbrar/emitir SIFEN), EX, IM
    { codigo: 'FACTURACION', descripcion: 'Gestión de facturas electrónicas' },

    // Ruta: /ventas/notas-credito, /ventas/notas-credito/nueva
    // Backend: nota-creditos.controller (create, findAll, enviarLoteMiddleware)
    // Privilegios: L, C, P (timbrar), EX, IM
    { codigo: 'NOTAS_CREDITO', descripcion: 'Notas de crédito electrónicas' },

    // Ruta: /ventas/remisiones, /ventas/remisiones/nueva
    // Backend: nota-remision.controller (create, findAll, enviarMiddleware)
    // Privilegios: L, C, P (timbrar), EX, IM
    { codigo: 'REMISION', descripcion: 'Notas de remisión electrónicas' },

    // ── Presupuestos / Cotizaciones ──────────────────────────────
    // Ruta: /presupuestos (PresupuestosTemplate) + portal público /pub/presupuesto/:token
    // Backend: presupuestos.controller (CRUD, items, versionado, envío, conversión, dashboard)
    // Privilegios: L, C, E, X, EX, IM, PRES_APROBAR, PRES_CONVERTIR
    { codigo: 'PRESUPUESTOS', descripcion: 'Presupuestos / Cotizaciones comerciales' },

    // ── Cobros y cuentas por cobrar ──────────────────────────────
    // Ruta: /cobros  y  /recibos-multi (recibos multi-factura + retenciones)
    // Backend: cobros.controller + recibos.controller
    // Privilegios estándar: L, C, E, A (anular cobro), EX, IM
    // Privilegios específicos recibos multi:
    //   COB_REC_VER, COB_REC_CREAR, COB_REC_ANULAR, COB_REC_NC_FLEXIBLE,
    //   COB_REC_AJUSTE_MANUAL, COB_REC_RETENCION_REGISTRAR,
    //   COB_REC_LIBRO_RETENCIONES, COB_REC_OVERRIDE_FIFO
    // Matriz sugerida (referencia para configurar perfiles):
    //   COB_REC_VER                  → Cajero, Cobrador, Tesorero, Gerente
    //   COB_REC_CREAR                → Cajero, Cobrador, Tesorero
    //   COB_REC_ANULAR               → Tesorero, Gerente
    //   COB_REC_NC_FLEXIBLE          → Gerente, Contador
    //   COB_REC_AJUSTE_MANUAL        → Gerente
    //   COB_REC_RETENCION_REGISTRAR  → Cajero, Tesorero, Contador
    //   COB_REC_LIBRO_RETENCIONES    → Contador, Gerente
    //   COB_REC_OVERRIDE_FIFO        → Tesorero, Gerente
    { codigo: 'COBROS', descripcion: 'Gestión de cobros y recibos' },

    // Ruta: /cuentas-cobrar  y  tab Cuentas a Cobrar en Tesorería
    // Backend: cobros.controller (cuentas-cobrar/resumen, por-cliente)
    // Privilegios: L, EX
    { codigo: 'CUENTAS_COBRAR', descripcion: 'Cuentas por cobrar' },

    // ── Inventario: Productos y catálogo ─────────────────────────
    // Ruta: /inventario tab Productos, /configuracion/productos
    // Backend: productos.controller (CRUD, search, destacados, imágenes)
    // Privilegios: L, C, E, X, EX
    { codigo: 'PRODUCTOS', descripcion: 'Catálogo de productos y servicios' },

    // Ruta: /inventario tab Categorías, /configuracion/categorias
    // Backend: categorias.controller (CRUD, roots, children)
    // Privilegios: L, C, E, X
    { codigo: 'CATEGORIAS', descripcion: 'Gestión de categorías' },

    // Ruta: /inventario tab Marcas
    // Backend: marcas.controller (CRUD, toggle)
    // Privilegios: L, C, E, X
    { codigo: 'MARCAS', descripcion: 'Gestión de marcas' },

    // Ruta: /inventario tab Stock
    // Backend: stock.controller (findByDeposito, findByProducto, consulta, bajo-minimo)
    // Privilegios: L, EX
    { codigo: 'STOCK', descripcion: 'Consulta y control de stock' },

    // Ruta: /inventario tab Ajuste
    // Backend: stock.controller (ajustar)
    // Privilegios: L, C (crear ajuste)
    { codigo: 'AJUSTE_STOCK', descripcion: 'Ajustes de inventario' },

    // Ruta: /inventario tab Transferencias
    // Backend: stock.controller (transferir)
    // Privilegios: L, C (crear transferencia)
    { codigo: 'TRANSFERENCIAS', descripcion: 'Transferencias entre depósitos' },

    // Ruta: /inventario tab Movimientos
    // Backend: movimientos-inventario.controller (findAll, byProducto, byDeposito)
    // Privilegios: L, EX
    {
      codigo: 'MOVIMIENTOS_INV',
      descripcion: 'Historial de movimientos de inventario',
    },

    // Ruta: /inventario tab Ofertas
    // Backend: ofertas.controller (CRUD, evaluar, activas, usos, toggle)
    // Privilegios: L, C, E, X
    { codigo: 'OFERTAS', descripcion: 'Ofertas y promociones' },

    // No tiene ruta propia pero se usa en POS y Productos
    // Backend: lista-precios.controller (CRUD completo, asignaciones, duplicar, descuento masivo)
    // Privilegios: L, C, E, X
    { codigo: 'LISTA_PRECIOS', descripcion: 'Listas de precios' },

    // ── Pedidos y Ventas Mayoristas ──────────────────────────────
    // Módulo base de pedidos (preventa, pedidos internos, cobro en POS)
    // Backend: pedidos.controller (CRUD, confirmar, cancelar, facturar)
    // Privilegios: L, C, E, X, A (anular/cancelar pedido), EX
    { codigo: 'PEDIDOS', descripcion: 'Gestión de pedidos y preventa' },
    // Ruta: /ordenes-venta. Depende de PEDIDOS. Agrega: órdenes de venta con flujo confirmar→aprobar→facturar
    { codigo: 'ORDEN_VENTA', descripcion: 'Órdenes de venta' },

    // Ruta: /pedidos-mayoristas (negociación, descuento-global, contexto-negociacion)
    // Depende de PEDIDOS. Agrega: lista de precios mayorista, negociación de precios
    // Privilegios: L, C, E, X, A, EX
    { codigo: 'VENTAS_MAYORISTAS', descripcion: 'Ventas mayoristas y negociación' },

    // Ruta: /solicitudes-credito (crear, aprobar, rechazar, facturar)
    // Backend: solicitudes-credito.controller (CRUD, enviar-aprobacion, aprobar, rechazar, cancelar, facturar)
    // Privilegios: L, C, E, X, A (aprobar/rechazar)
    { codigo: 'SOLICITUD_CREDITO', descripcion: 'Solicitudes de crédito' },

    // ── Contactos ────────────────────────────────────────────────
    // Ruta: /clientes
    // Backend: clientes.controller (CRUD, search)
    // Privilegios: L, C, E, X, EX
    { codigo: 'CLIENTES', descripcion: 'Gestión de clientes' },

    // Ruta: /contactos
    // Backend: personas.controller (proveedores/contactos)
    // Privilegios: L, C, E, X
    { codigo: 'CONTACTOS', descripcion: 'Proveedores y contactos' },

    // Ruta: /compras
    // Backend: compras.controller (CRUD compras, anulación, búsqueda proveedores)
    // Privilegios: L, C, E, A, EX
    // Nota: se crea el módulo pero no se asigna por defecto a los planes.
    { codigo: 'COMPRAS', descripcion: 'Gestión de compras y cuentas por pagar' },

    // Ruta: /gastos
    // Backend: gastos.controller (CRUD gastos, anulación, tipos de gasto)
    // Privilegios: L, C, E, X, A, EX
    // Registra gastos con factura (luz, combustible, alquiler, etc.) — crédito IVA + IRE deducible.
    // Incluido en Profesional y Enterprise.
    { codigo: 'GASTOS', descripcion: 'Registro de gastos y crédito IVA' },

    // Ruta: /inventario tab Lotes y endpoints /lotes
    // Backend: lotes.controller + integración FIFO en compras/facturación
    // Privilegios: L, C, E, X, EX
    // Nota: se crea el módulo pero no se asigna por defecto a los planes.
    { codigo: 'LOTES', descripcion: 'Control de Lotes e Inventario FIFO' },

    // ── Tesorería y finanzas ─────────────────────────────────────
    // Ruta: /tesoreria tabs: Caja del Día, Movimientos, Historial de Arqueos
    // Backend: tesoreria.controller (abrirCaja, cerrarCaja, movimiento, sesiones, arqueos)
    //          cajas.controller (CRUD cajas)
    // Privilegios: L, C (abrir caja, registrar movimiento), E (cerrar caja), EX
    { codigo: 'FINANZAS', descripcion: 'Caja del día, recibos y pagos' },
    { codigo: 'TESORERIA', descripcion: 'Bancos, transferencias y conciliación' },

    // Ruta: /tesoreria tab Comisiones + tab Liquidaciones
    // Backend: vendedores-cobradores.controller (CRUD)
    //          asignacion-facturas.controller (asignar, masivo, comisiones)
    //          liquidaciones.controller (crear, pagar, anular)
    //          zonas-cobranza.controller (CRUD)
    // Privilegios: L, C, E, X, A (anular liquidación), EX
    {
      codigo: 'VENDEDORES',
      descripcion: 'Vendedores, cobradores y comisiones',
    },

    // Ruta: /tesoreria tab Rendiciones
    // Backend: rendiciones.controller (crear, aprobar, rechazar, resumen)
    //          rutas-cobranza.controller (crear, listar, detalle, estado)
    // Privilegios: L, C, E, A (aprobar/rechazar rendición), EX
    { codigo: 'RENDICIONES', descripcion: 'Rendiciones de cobranza' },

    // ── Retenciones recibidas (libro mensual) ────────────────────
    // Ruta: /recibos-multi/retenciones/*  (libro + marcar declaradas)
    // Backend: retenciones.controller
    // Privilegios específicos:
    //   COB_REC_LIBRO_RETENCIONES → consultar y exportar
    //   COB_REC_RETENCION_REGISTRAR → registrar (al crear recibo)
    // Roles sugeridos: Contador, Gerente (libro); Cajero/Tesorero/Contador (registrar)
    { codigo: 'RETENCIONES', descripcion: 'Libro de retenciones recibidas (IVA y Renta)' },

    // ── Reportes ─────────────────────────────────────────────────
    // Ruta: /reportes
    // Backend: (consume datos de facturas, productos, tesorería)
    // Privilegios: L, EX, IM
    { codigo: 'REPORTES', descripcion: 'Informes y reportes del sistema' },

    // ── Configuración: Empresa ───────────────────────────────────
    // Ruta: /configuracion/empresa (básicos, moneda, empresas list)
    // Backend: empresas.controller (findOne, update, logo, certificado)
    //          monedas.controller
    // Privilegios: L, E
    { codigo: 'CONFIG_EMPRESA', descripcion: 'Configuración de empresa' },

    // Ruta: /configuracion/sucursalcaja
    // Backend: sucursales.controller (CRUD, config)
    //          punto-expediciones.controller
    //          cajas.controller (CRUD)
    //          numeraciones.controller (CRUD)
    // Privilegios: L, C, E, X
    {
      codigo: 'CONFIG_SUCURSALES',
      descripcion: 'Sucursales, puntos de expedición y cajas',
    },

    // Ruta: /configuracion/usuarios
    // Backend: users.controller (CRUD, asignar-empresa, revocar, toggle)
    // Privilegios: L, C, E, X
    { codigo: 'CONFIG_USUARIOS', descripcion: 'Administración de usuarios' },

    // Dentro de la gestión de usuarios
    // Backend: perfiles.controller (CRUD), privilegios.controller
    // Privilegios: L, C, E, X
    { codigo: 'CONFIG_PERFILES', descripcion: 'Roles y permisos' },

    // Ruta: /configuracion/serializacion
    // Backend: numeraciones.controller (CRUD, reserve, increment, toggle)
    // Privilegios: L, C, E, X
    { codigo: 'CONFIG_NUMERACION', descripcion: 'Numeraciones y timbrados' },

    // Ruta: /configuracion/ticket
    // Backend: pos-config.controller (CRUD by sucursal)
    // Privilegios: L, E
    { codigo: 'CONFIG_TICKET', descripcion: 'Configuración de ticket' },

    // Ruta: /configuracion/impresoras
    // Backend: (configuración local)
    // Privilegios: L, E
    { codigo: 'CONFIG_IMPRESORAS', descripcion: 'Configuración de impresoras' },

    // Ruta: /configuracion/metodospago
    // Backend: medio-pago.controller (findByEmpresa, toggle, bulkToggle)
    // Privilegios: L, E
    { codigo: 'CONFIG_MEDIOS_PAGO', descripcion: 'Métodos de pago' },

    // Ruta: /configuracion/almacenes
    // Backend: depositos.controller (CRUD, toggle, principal)
    // Privilegios: L, C, E, X
    { codigo: 'CONFIG_ALMACENES', descripcion: 'Depósitos y almacenes' },

    // No tiene ruta propia, se usa en POS y facturación
    // Backend: condiciones-pago.controller (CRUD)
    // Privilegios: L, C, E, X
    { codigo: 'CONFIG_COND_PAGO', descripcion: 'Condiciones de pago' },

    // ── Módulos adicionales de configuración ──────────────────────

    // Ruta: /configuracion tab "Configuración POS"
    // Backend: pos-config.controller (CRUD, layout, fullscreen, etc.)
    // Privilegios: L, E
    { codigo: 'CONFIG_POS', descripcion: 'Configuración general del POS' },

    // Ruta: /configuracion tab "Planes de Cuotas"
    // Backend: planes-cuotas.controller (CRUD)
    // Privilegios: L, C, E, X

    // ── Módulos de procesos ────────────────────────────────────────

    // Funcionalidad SIFEN: Envío y consulta de DTE en módulo de Facturación
    // Backend: facturas.controller (enviarMiddleware, enviarLote, consultarEstado)
    // Privilegios: L, P (procesar/enviar)
    { codigo: 'SIFEN', descripcion: 'Envío y gestión de DTE electrónicos (SIFEN)' },

    // Ruta: /tesoreria tab Comisiones + tab Liquidaciones
    // Backend: asignacion-facturas.controller, liquidaciones.controller
    // Privilegios: L, C, E, A (anular liquidación), LIQUIDAR, EX
    { codigo: 'COMISIONES', descripcion: 'Comisiones y liquidaciones de vendedores' },

    // ── Suscripciones (solo holding/reseller) ────────────────────
    // Ruta: /suscripciones
    // Backend: suscripciones.controller, comisiones.controller (holding/reseller)
    //          planes.controller, empresas.controller (jerarquía)
    // Privilegios: L, C, E
    {
      codigo: 'SUSCRIPCIONES',
      descripcion: 'Gestión de suscripciones y planes',
    },

    // Impresión térmica Bluetooth vía app Novasis Print (Android)
    // Requiere app Novasis Print instalada en dispositivo Android del cobrador
    { codigo: 'PRINT_MOBILE', descripcion: 'Impresión móvil Bluetooth (Novasis Print)' },

    // Panel de agenda del cobrador: cuotas asignadas por vencimiento, promesas de pago
    // Habilitar por empresa para cobradores de campo. No requiere CUENTAS_COBRAR.
    { codigo: 'PANEL_COBRADOR', descripcion: 'Panel de agenda y cuotas para cobrador de campo' },

    // ── Integración IA ────────────────────────────────────────────
    // Ruta: /ai-dashboard
    // Backend: ai-dashboard.controller (resumen, metricas, alertas, chat, configuración)
    // Privilegios: L (ver dashboard), C (chat/consultas), E (configurar API key)
    { codigo: 'INTEGRACION_IA', descripcion: 'Dashboard inteligente y chat con IA' },

    // ── Recursos Humanos (add-on) ─────────────────────────────────
    // Ruta: /rrhh
    // Backend: rrhh/* (empleados, catálogos; futuras fases: liquidaciones, IPS, finiquitos)
    // Privilegios: RRHH_EMPLEADOS_GESTION, RRHH_ESTRUCTURA_GESTION, RRHH_*
    // Estado: add-on. No se asigna a planes por defecto; el admin lo activa por suscripción.
    { codigo: 'RRHH', descripcion: 'Recursos Humanos y nómina' },

    // ── Ecommerce ─────────────────────────────────────────────────
    // Ruta: /ecommerce
    // Backend: ecommerce/* (config pública, catálogo, checkout, pedidos)
    // Privilegios: L (ver/configurar), E (publicar diseño), ECOM_PED_* (operación)
    // Estado: add-on. Incluye Facturación; no requiere Contabilidad/Tesorería/Cobranzas.
    { codigo: 'ECOMMERCE', descripcion: 'Canal de venta online (tienda pública)' },
  ];

  console.log('📦 Creando módulos...');
  for (const mod of modulosData) {
    const exists = await prisma.modulos.findFirst({
      where: { codigo: mod.codigo },
    });
    if (!exists) {
      await prisma.modulos.create({ data: { ...mod, active: true } });
      console.log(`  ✅ Módulo "${mod.codigo}" creado`);
    } else {
      await prisma.modulos.update({
        where: { id: exists.id },
        data: { descripcion: mod.descripcion, active: true },
      });
      console.log(`  🔄 Módulo "${mod.codigo}" actualizado`);
    }
  }

  // ═══════════════════════════════════════════════════════════════
  // 3. PERFIL superAdmin — Se asegura que tenga TODOS los
  //    privilegios en TODOS los módulos
  // ═══════════════════════════════════════════════════════════════

  console.log('👤 Configurando perfil superAdmin...');
  const perfilAdmin = await prisma.perfiles.findFirst({
    where: { perfil: 'superAdmin' },
  });

  if (perfilAdmin) {
    const allModulos = await prisma.modulos.findMany({
      where: { active: true },
    });
    const allPrivilegios = await prisma.privilegios.findMany({
      where: { active: true },
    });

    let creados = 0;
    let existentes = 0;

    for (const mod of allModulos) {
      for (const priv of allPrivilegios) {
        const exists = await prisma.perfiles_privilegios.findFirst({
          where: {
            perfil_id: perfilAdmin.id,
            modulo_id: mod.id,
            privilegio_id: priv.id,
          },
        });
        if (!exists) {
          await prisma.perfiles_privilegios.create({
            data: {
              perfil_id: perfilAdmin.id,
              modulo_id: mod.id,
              privilegio_id: priv.id,
              active: true,
            },
          });
          creados++;
        } else {
          existentes++;
        }
      }
    }
    console.log(`  ✅ superAdmin: ${creados} permisos creados, ${existentes} ya existían`);
  } else {
    console.log('  ⚠️  Perfil superAdmin no encontrado — se creará en el registro de la primera empresa');
  }

  // ═══════════════════════════════════════════════════════════════
  // 4. PLANES CON MÓDULOS — Cada plan define qué funcionalidades
  //    están disponibles para una suscripción
  // ═══════════════════════════════════════════════════════════════

  console.log('📋 Creando planes con módulos...');

  // Obtener todos los módulos indexados por código
  const allMods = await prisma.modulos.findMany({ where: { active: true } });
  const modMap: Record<string, string> = {};
  for (const m of allMods) {
    if (m.codigo) modMap[m.codigo] = m.id;
  }

  // Helper: resolver IDs de módulos por código
  const resolveModIds = (codigos: string[]): string[] => codigos.map((c) => modMap[c]).filter(Boolean);

  // ── Módulos por tier ──────────────────────────────────────────
  const MODULOS_BASICO = [
    'DASHBOARD',
    'POS_RETAIL',
    'FACTURACION',
    'PRODUCTOS',
    'CATEGORIAS',
    'MARCAS',
    'CLIENTES',
    'STOCK',
    'CONFIG_EMPRESA',
    'CONFIG_SUCURSALES',
    'CONFIG_MEDIOS_PAGO',
    'CONFIG_TICKET',
  ];

  const MODULOS_PROFESIONAL = [
    ...MODULOS_BASICO,
    'POS_ADMIN',
    'NOTAS_CREDITO',
    'REMISION',
    'PRESUPUESTOS',
    'COBROS',
    'CUENTAS_COBRAR',
    'CONTACTOS',
    'AJUSTE_STOCK',
    'TRANSFERENCIAS',
    'MOVIMIENTOS_INV',
    'OFERTAS',
    'LISTA_PRECIOS',
    'PEDIDOS',
    'ORDEN_VENTA',
    'VENTAS_MAYORISTAS',
    'SOLICITUD_CREDITO',
    'FINANZAS',
    'TESORERIA',
    'REPORTES',
    'CONFIG_USUARIOS',
    'CONFIG_PERFILES',
    'CONFIG_NUMERACION',
    'CONFIG_ALMACENES',
    'CONFIG_COND_PAGO',
    'CONFIG_IMPRESORAS',
    'CONFIG_POS',
    'PLAN_CUOTAS',
    'SIFEN',
    'RENDICIONES',
    'RETENCIONES',
    'GASTOS',
  ];

  const MODULOS_ENTERPRISE = [...MODULOS_PROFESIONAL, 'VENDEDORES', 'COMISIONES', 'SUSCRIPCIONES', 'INTEGRACION_IA'];

  const planesData = [
    {
      codigo: 'PLAN_PRUEBA',
      descripcion: 'Plan de Prueba (Trial)',
      precio: 0,
      tipo_ciclo: 'mensual',
      max_user: 1,
      max_producto: 50,
      max_documentos: 20,
      periodo_prueba: 14,
      max_ducumento_prueba: 20,
      modulos: MODULOS_BASICO,
    },
    {
      codigo: 'PLAN_BASICO',
      descripcion: 'Plan Básico',
      precio: 150000,
      tipo_ciclo: 'mensual',
      max_user: 2,
      max_producto: 500,
      max_documentos: 300,
      periodo_prueba: 0,
      max_ducumento_prueba: 0,
      modulos: MODULOS_BASICO,
    },
    {
      codigo: 'PLAN_PRO',
      descripcion: 'Plan Profesional',
      precio: 300000,
      tipo_ciclo: 'mensual',
      max_user: 5,
      max_producto: 5000,
      max_documentos: 1500,
      periodo_prueba: 0,
      max_ducumento_prueba: 0,
      modulos: MODULOS_PROFESIONAL,
    },
    {
      codigo: 'PLAN_ENTERPRISE',
      descripcion: 'Plan Enterprise',
      precio: 600000,
      tipo_ciclo: 'mensual',
      max_user: 20,
      max_producto: 50000,
      max_documentos: 10000,
      periodo_prueba: 0,
      max_ducumento_prueba: 0,
      modulos: MODULOS_ENTERPRISE,
    },
  ];

  for (const plan of planesData) {
    const { modulos: modulosCodigos, ...planData } = plan;
    const moduloIds = resolveModIds(modulosCodigos);

    const exists = await prisma.planes.findFirst({
      where: { codigo: planData.codigo },
    });

    if (!exists) {
      // Crear plan
      const created = await prisma.planes.create({
        data: { ...planData, active: true },
      });
      // Asignar módulos
      if (moduloIds.length) {
        await prisma.$transaction(
          moduloIds.map((modId) =>
            prisma.plan_modulos.create({
              data: { plan_id: created.id, modulo_id: modId, active: true },
            }),
          ),
        );
      }
      console.log(`  ✅ Plan "${planData.codigo}" creado con ${moduloIds.length} módulos`);
    } else {
      // Actualizar datos del plan
      await prisma.planes.update({
        where: { id: exists.id },
        data: {
          descripcion: planData.descripcion,
          precio: planData.precio,
          tipo_ciclo: planData.tipo_ciclo,
          max_user: planData.max_user,
          max_producto: planData.max_producto,
          max_documentos: planData.max_documentos,
          periodo_prueba: planData.periodo_prueba,
          max_ducumento_prueba: planData.max_ducumento_prueba,
          active: true,
          updated_at: new Date(),
        },
      });
      // Sincronizar módulos: eliminar viejos, crear nuevos
      await prisma.plan_modulos.deleteMany({ where: { plan_id: exists.id } });
      if (moduloIds.length) {
        await prisma.$transaction(
          moduloIds.map((modId) =>
            prisma.plan_modulos.create({
              data: { plan_id: exists.id, modulo_id: modId, active: true },
            }),
          ),
        );
      }
      console.log(`  🔄 Plan "${planData.codigo}" actualizado con ${moduloIds.length} módulos`);
    }
  }

  // ═══════════════════════════════════════════════════════════════
  // 5. MAPEO MÓDULO → PRIVILEGIOS APLICABLES
  //    (Referencia para el frontend al configurar perfiles)
  //    No se guarda en DB, solo como documentación del seed.
  // ═══════════════════════════════════════════════════════════════
  //
  //  Módulo                  | L | C | E | X | A | P | EX | IM | Otros
  //  ─────────────────────── |---|---|---|---|---|---|----|-───|──────
  //  DASHBOARD               | ✓ |   |   |   |   |   | ✓  |    |
  //  POS_RETAIL              | ✓ | ✓ |   |   |   |   |    | ✓  |
  //  POS_ADMIN               | ✓ | ✓ | ✓ |   |   |   |    | ✓  |
  //  FACTURACION             | ✓ | ✓ | ✓ |   | ✓ | ✓ | ✓  | ✓  |
  //  NOTAS_CREDITO           | ✓ | ✓ |   |   |   | ✓ | ✓  | ✓  |
  //  COBROS                  | ✓ | ✓ | ✓ |   | ✓ |   | ✓  | ✓  |
  //  CUENTAS_COBRAR          | ✓ |   |   |   |   |   | ✓  |    |
  //  PRODUCTOS               | ✓ | ✓ | ✓ | ✓ |   |   | ✓  |    |
  //  CATEGORIAS              | ✓ | ✓ | ✓ | ✓ |   |   |    |    |
  //  MARCAS                  | ✓ | ✓ | ✓ | ✓ |   |   |    |    |
  //  STOCK                   | ✓ |   |   |   |   |   | ✓  |    |
  //  AJUSTE_STOCK            | ✓ | ✓ |   |   |   |   |    |    |
  //  TRANSFERENCIAS          | ✓ | ✓ |   |   |   |   |    |    |
  //  MOVIMIENTOS_INV         | ✓ |   |   |   |   |   | ✓  |    |
  //  OFERTAS                 | ✓ | ✓ | ✓ | ✓ |   |   |    |    |
  //  LISTA_PRECIOS           | ✓ | ✓ | ✓ | ✓ |   |   |    |    |
  //  PEDIDOS                 | ✓ | ✓ | ✓ | ✓ | ✓ |   | ✓  |    |
  //  VENTAS_MAYORISTAS       | ✓ | ✓ | ✓ | ✓ | ✓ |   | ✓  |    |
  //  SOLICITUD_CREDITO       | ✓ | ✓ | ✓ | ✓ | ✓ |   | ✓  |    |
  //  CLIENTES                | ✓ | ✓ | ✓ | ✓ |   |   | ✓  |    |
  //  CONTACTOS               | ✓ | ✓ | ✓ | ✓ |   |   |    |    |
  //  TESORERIA               | ✓ | ✓ | ✓ |   |   |   | ✓  |    | APERTURA_CIERRE
  //  VENDEDORES              | ✓ | ✓ | ✓ | ✓ | ✓ |   | ✓  |    |
  //  COMISIONES              | ✓ | ✓ | ✓ |   | ✓ |   | ✓  |    | LIQUIDAR
  //  RENDICIONES             | ✓ | ✓ | ✓ |   | ✓ |   | ✓  |    |
  //  REPORTES                | ✓ |   |   |   |   |   | ✓  | ✓  |
  //  CONFIG_EMPRESA          | ✓ |   | ✓ |   |   |   |    |    |
  //  CONFIG_SUCURSALES       | ✓ | ✓ | ✓ | ✓ |   |   |    |    | ASIGNAR
  //  CONFIG_USUARIOS         | ✓ | ✓ | ✓ | ✓ |   |   |    |    |
  //  CONFIG_PERFILES         | ✓ | ✓ | ✓ | ✓ |   |   |    |    |
  //  CONFIG_NUMERACION       | ✓ | ✓ | ✓ | ✓ |   |   |    |    |
  //  CONFIG_TICKET           | ✓ |   | ✓ |   |   |   |    |    |
  //  CONFIG_POS              | ✓ |   | ✓ |   |   |   |    |    |
  //  CONFIG_IMPRESORAS       | ✓ |   | ✓ |   |   |   |    |    |
  //  CONFIG_MEDIOS_PAGO      | ✓ |   | ✓ |   |   |   |    |    |
  //  CONFIG_ALMACENES        | ✓ | ✓ | ✓ | ✓ |   |   |    |    |
  //  CONFIG_COND_PAGO        | ✓ | ✓ | ✓ | ✓ |   |   |    |    |
  //  PLAN_CUOTAS             | ✓ | ✓ | ✓ | ✓ |   |   |    |    |
  //  SIFEN                   | ✓ |   |   |   |   | ✓ |    |    |
  //  SUSCRIPCIONES           | ✓ | ✓ | ✓ |   |   |   |    |    |

  // ═══════════════════════════════════════════════════════════════
  // 6. TIPOS DE GASTO — Catálogo global (empresa_id = null)
  //    Se mapea cada tipo a su cuenta contable del plan paraguayo.
  //    Si la cuenta no existe aún en cont_plan_cuentas, se crea con
  //    cuenta_contable_id = null (fallback al mapeo GASTOS_GENERALES).
  // ═══════════════════════════════════════════════════════════════
  console.log('💸 Creando tipos de gasto globales...');
  const tiposGastoSeed: Array<{
    descripcion: string;
    porcentaje_iva: number;
    codigoCuenta: string;
  }> = [
    { descripcion: 'Servicios básicos', porcentaje_iva: 10, codigoCuenta: '6.1.2.02' },
    { descripcion: 'Combustible', porcentaje_iva: 10, codigoCuenta: '6.1.2.11' },
    { descripcion: 'Alquiler', porcentaje_iva: 10, codigoCuenta: '6.1.2.01' },
    { descripcion: 'Viáticos', porcentaje_iva: 10, codigoCuenta: '6.1.2.12' },
    { descripcion: 'Papelería', porcentaje_iva: 10, codigoCuenta: '6.1.2.05' },
    { descripcion: 'Mantenimiento', porcentaje_iva: 10, codigoCuenta: '6.1.2.06' },
    { descripcion: 'Honorarios', porcentaje_iva: 10, codigoCuenta: '6.1.2.13' },
    { descripcion: 'Telefonía / Internet', porcentaje_iva: 10, codigoCuenta: '6.1.2.04' },
    { descripcion: 'Seguros', porcentaje_iva: 10, codigoCuenta: '6.1.2.07' },
    { descripcion: 'Otros', porcentaje_iva: 10, codigoCuenta: '6.1.2.99' },
  ];

  for (const tg of tiposGastoSeed) {
    // Resolver cuenta contable (sólo cuentas globales del plan — empresa_id null)
    const cuenta = await prisma.cont_plan_cuentas.findFirst({
      where: { empresa_id: null, codigo: tg.codigoCuenta },
      select: { id: true },
    });

    const exists = await prisma.tipo_gasto.findFirst({
      where: { empresa_id: null, descripcion: tg.descripcion },
    });

    if (!exists) {
      await prisma.tipo_gasto.create({
        data: {
          empresa_id: null,
          descripcion: tg.descripcion,
          aplica_iva: true,
          porcentaje_iva: tg.porcentaje_iva,
          deducible: true,
          cuenta_contable_id: cuenta?.id ?? null,
          activo: true,
        },
      });
      console.log(
        `  ✅ Tipo de gasto "${tg.descripcion}" creado${cuenta ? ` (cuenta ${tg.codigoCuenta})` : ' (sin cuenta — usará fallback)'}`,
      );
    } else {
      await prisma.tipo_gasto.update({
        where: { id: exists.id },
        data: {
          porcentaje_iva: tg.porcentaje_iva,
          cuenta_contable_id: cuenta?.id ?? exists.cuenta_contable_id,
          activo: true,
        },
      });
      console.log(`  🔄 Tipo de gasto "${tg.descripcion}" actualizado`);
    }
  }

  console.log('🎉 Seeding completado exitosamente!');
  console.log(`   ${privilegiosData.length} privilegios`);
  console.log(`   ${modulosData.length} módulos`);
  console.log(`   ${planesData.length} planes`);
  console.log(`   ${tiposGastoSeed.length} tipos de gasto globales`);
}

main()
  .catch((e) => {
    console.error('❌ Error durante el seeding:', e);
    process.exit(1);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
