import {
  OpenAPIRegistry,
  OpenApiGeneratorV3,
} from "@asteasolutions/zod-to-openapi";

import {
  ProductCodeParamSchema,
  ProductIdParamSchema,
  ProductListQuerySchema,
  ProductListResponseSchema,
  ProductSingleResponseSchema,
} from "../modules/products/products.schema";

const registry = new OpenAPIRegistry();

registry.registerComponent("securitySchemes", "ApiKeyAuth", {
  type: "apiKey",
  in: "header",
  name: "X-API-Key",
});

registry.registerPath({
  method: "get",
  path: "/products",
  summary: "Listar y filtrar productos",
  description:
    "Obtiene productos activos con precio de venta activo. Permite filtrar por nombre, código interno, código fabricante, marca, categoría y unidad de negocio. No expone costos.",
  tags: ["Productos"],
  security: [{ ApiKeyAuth: [] }],
  request: {
    query: ProductListQuerySchema,
  },
  responses: {
    200: {
      description: "Lista de productos",
      content: {
        "application/json": {
          schema: ProductListResponseSchema,
        },
      },
    },
    400: {
      description: "Parámetros inválidos",
    },
    401: {
      description: "API Key inválida o faltante",
    },
    429: {
      description: "Demasiadas solicitudes",
    },
    500: {
      description: "Error interno del servidor",
    },
  },
});

registry.registerPath({
  method: "get",
  path: "/products/{id}",
  summary: "Obtener producto por ID",
  description: "Obtiene un producto activo por su productoId.",
  tags: ["Productos"],
  security: [{ ApiKeyAuth: [] }],
  request: {
    params: ProductIdParamSchema,
  },
  responses: {
    200: {
      description: "Producto encontrado",
      content: {
        "application/json": {
          schema: ProductSingleResponseSchema,
        },
      },
    },
    400: {
      description: "ID inválido",
    },
    401: {
      description: "API Key inválida o faltante",
    },
    404: {
      description: "Producto no encontrado",
    },
    500: {
      description: "Error interno del servidor",
    },
  },
});

registry.registerPath({
  method: "get",
  path: "/products/code/{code}",
  summary: "Buscar producto por código o nombre",
  description:
    "Busca un producto por similitud en código interno, código fabricante o nombre del producto.",
  tags: ["Productos"],
  security: [{ ApiKeyAuth: [] }],
  request: {
    params: ProductCodeParamSchema,
  },
  responses: {
    200: {
      description: "Producto encontrado",
      content: {
        "application/json": {
          schema: ProductSingleResponseSchema,
        },
      },
    },
    400: {
      description: "Código inválido",
    },
    401: {
      description: "API Key inválida o faltante",
    },
    404: {
      description: "Producto no encontrado",
    },
    500: {
      description: "Error interno del servidor",
    },
  },
});

const generator = new OpenApiGeneratorV3(registry.definitions);

export const openApiDocument = generator.generateDocument({
  openapi: "3.0.0",
  info: {
    title: "G-API",
    version: "1.0.0",
    description: "API de consulta para indupal-cloud",
  },
  servers: [
    {
      url: "http://localhost:3000/api/v1",
      description: "Servidor ASURE",
    },
  ],
});
