/**
 * Swagger/OpenAPI Configuration for ERP Generic Core
 */

import swaggerJSDoc from 'swagger-jsdoc';
import { Application } from 'express';
import swaggerUi from 'swagger-ui-express';
import path from 'path';

// Swagger definition
const swaggerDefinition = {
  openapi: '3.0.0',
  info: {
    title: 'ERP Generic - Core API',
    version: '0.1.0',
    description: `
      API para el sistema ERP genérico multitenant.

      ## Características principales
      - Autenticación JWT y gestión de sesiones
      - Multi-tenant con aislamiento de datos por empresa
      - Gestión financiera y contable completa
      - Control de inventario y almacenes
      - Módulos de compras y ventas
      - CRM y gestión de partners (clientes, proveedores)
      - Proyectos y recursos humanos
      - Sistema de permisos granular mediante API Keys

      ## Autenticación
      Todos los endpoints requieren autenticación mediante Bearer Token (JWT).
      El token debe incluirse en el header Authorization: Bearer <token>

      ## Multi-tenant
      El sistema identifica automáticamente la empresa (tenant) del usuario autenticado
      y filtra todos los datos según el contexto de la empresa.
    `,
    contact: {
      name: 'ERP Generic Support',
      email: 'support@erpgeneric.com',
    },
    license: {
      name: 'Proprietary',
    },
  },
  servers: [
    {
      url: 'http://localhost:3003/api/v1',
      description: 'Desarrollo local',
    },
    {
      url: 'https://api.erpgeneric.com/api/v1',
      description: 'Producción',
    },
  ],
  tags: [
    { name: 'Auth', description: 'Autenticación y autorización (JWT)' },
    { name: 'Users', description: 'Gestión de usuarios y perfiles' },
    { name: 'Companies', description: 'Gestión de empresas (multi-tenant)' },
    { name: 'Core', description: 'Configuración central y parámetros del sistema' },
    { name: 'Partners', description: 'Gestión de partners (clientes, proveedores, contactos)' },
    { name: 'Inventory', description: 'Control de inventario, productos y almacenes' },
    { name: 'Financial', description: 'Gestión financiera, contable y movimientos' },
    { name: 'Purchases', description: 'Módulo de compras y órdenes de compra' },
    { name: 'Sales', description: 'Módulo de ventas, cotizaciones y pedidos' },
    { name: 'Projects', description: 'Gestión de proyectos y tareas' },
    { name: 'System', description: 'Configuración del sistema, logs y auditoría' },
    { name: 'CRM', description: 'CRM, oportunidades y seguimiento comercial' },
    { name: 'HR', description: 'Recursos humanos, empleados y nómina' },
    { name: 'Reports', description: 'Reportes y analíticas del sistema' },
    { name: 'Health', description: 'Health checks y monitoreo' },
  ],
  components: {
    securitySchemes: {
      BearerAuth: {
        type: 'http',
        scheme: 'bearer',
        bearerFormat: 'JWT',
        description: 'Token JWT obtenido del endpoint de login',
      },
      ApiKeyAuth: {
        type: 'apiKey',
        in: 'header',
        name: 'X-API-Key',
        description: 'API Key para operaciones administrativas específicas',
      },
    },
    schemas: {
      ApiResponse: {
        type: 'object',
        properties: {
          success: {
            type: 'boolean',
          },
          data: {
            type: 'object',
          },
          error: {
            type: 'string',
          },
        },
      },
      PaginatedResponse: {
        type: 'object',
        properties: {
          success: {
            type: 'boolean',
            example: true,
          },
          data: {
            type: 'array',
            items: {
              type: 'object',
            },
          },
          pagination: {
            type: 'object',
            properties: {
              page: {
                type: 'integer',
                example: 1,
              },
              limit: {
                type: 'integer',
                example: 20,
              },
              total: {
                type: 'integer',
                example: 100,
              },
              totalPages: {
                type: 'integer',
                example: 5,
              },
            },
          },
        },
      },
    },
  },
  security: [
    {
      BearerAuth: [],
    },
  ],
};

// Options for swagger-jsdoc
const options: swaggerJSDoc.Options = {
  definition: swaggerDefinition,
  // Path to the API routes for JSDoc comments
  apis: [
    path.resolve(process.cwd(), 'src/modules/**/*.routes.ts'),
    path.resolve(process.cwd(), 'src/modules/**/*.routes.js'),
    path.resolve(process.cwd(), 'src/docs/openapi.yaml'),
  ],
};

// Initialize swagger-jsdoc
const swaggerSpec = swaggerJSDoc(options);

/**
 * Setup Swagger documentation for Express app
 */
export function setupSwagger(app: Application, prefix: string = '/api/v1') {
  // Swagger UI options
  const swaggerUiOptions = {
    customCss: `
      .swagger-ui .topbar { display: none }
      .swagger-ui .info { margin: 50px 0; }
      .swagger-ui .info .title { font-size: 36px; }
    `,
    customSiteTitle: 'ERP Generic - API Documentation',
    swaggerOptions: {
      persistAuthorization: true,
      displayRequestDuration: true,
      filter: true,
      tagsSorter: 'alpha',
      operationsSorter: 'alpha',
    },
  };

  // Serve Swagger UI
  app.use(`${prefix}/docs`, swaggerUi.serve);
  app.get(`${prefix}/docs`, swaggerUi.setup(swaggerSpec, swaggerUiOptions));

  // Serve OpenAPI spec as JSON
  app.get(`${prefix}/docs.json`, (req, res) => {
    res.setHeader('Content-Type', 'application/json');
    res.send(swaggerSpec);
  });

  console.log(`📚 Swagger docs available at: http://localhost:${process.env.PORT || 3003}${prefix}/docs`);
  console.log(`📄 OpenAPI spec JSON at: http://localhost:${process.env.PORT || 3003}${prefix}/docs.json`);
}

export { swaggerSpec };
