// src/config/swagger.ts
/**
 * @file OpenAPI/Swagger configuration for API documentation.
 * Implements ADR-018: API Documentation Strategy.
 *
 * This file configures swagger-jsdoc to generate an OpenAPI 3.0 specification
 * from JSDoc annotations in route files. The specification is used by
 * swagger-ui-express to serve interactive API documentation.
 */
import swaggerJsdoc from 'swagger-jsdoc';

const options: swaggerJsdoc.Options = {
  definition: {
    openapi: '3.0.0',
    info: {
      title: 'Flyer Crawler API',
      version: '1.0.0',
      description:
        'API for the Flyer Crawler application - a platform for discovering grocery deals, managing recipes, and tracking budgets.',
      contact: {
        name: 'API Support',
      },
      license: {
        name: 'Private',
      },
    },
    servers: [
      {
        url: '/api',
        description: 'API server',
      },
    ],
    components: {
      securitySchemes: {
        bearerAuth: {
          type: 'http',
          scheme: 'bearer',
          bearerFormat: 'JWT',
          description: 'JWT token obtained from /auth/login or /auth/register',
        },
      },
      schemas: {
        // Standard success response wrapper (ADR-028)
        SuccessResponse: {
          type: 'object',
          properties: {
            success: {
              type: 'boolean',
              example: true,
            },
            data: {
              type: 'object',
              description: 'Response payload - structure varies by endpoint',
            },
          },
          required: ['success', 'data'],
        },
        // Standard error response wrapper (ADR-028)
        ErrorResponse: {
          type: 'object',
          properties: {
            success: {
              type: 'boolean',
              example: false,
            },
            error: {
              type: 'object',
              properties: {
                code: {
                  type: 'string',
                  description: 'Machine-readable error code',
                  example: 'VALIDATION_ERROR',
                },
                message: {
                  type: 'string',
                  description: 'Human-readable error message',
                  example: 'Invalid request parameters',
                },
              },
              required: ['code', 'message'],
            },
          },
          required: ['success', 'error'],
        },
        // Common service health status
        ServiceHealth: {
          type: 'object',
          properties: {
            status: {
              type: 'string',
              enum: ['healthy', 'degraded', 'unhealthy'],
            },
            latency: {
              type: 'number',
              description: 'Response time in milliseconds',
            },
            message: {
              type: 'string',
              description: 'Additional status information',
            },
            details: {
              type: 'object',
              description: 'Service-specific details',
            },
          },
          required: ['status'],
        },
        // Achievement schema
        Achievement: {
          type: 'object',
          properties: {
            achievement_id: {
              type: 'integer',
              example: 1,
            },
            name: {
              type: 'string',
              example: 'First-Upload',
            },
            description: {
              type: 'string',
              example: 'Upload your first flyer',
            },
            icon: {
              type: 'string',
              example: 'upload-cloud',
            },
            points_value: {
              type: 'integer',
              example: 25,
            },
            created_at: {
              type: 'string',
              format: 'date-time',
            },
          },
        },
        // User achievement (with achieved_at)
        UserAchievement: {
          allOf: [
            { $ref: '#/components/schemas/Achievement' },
            {
              type: 'object',
              properties: {
                user_id: {
                  type: 'string',
                  format: 'uuid',
                },
                achieved_at: {
                  type: 'string',
                  format: 'date-time',
                },
              },
            },
          ],
        },
        // Leaderboard entry
        LeaderboardUser: {
          type: 'object',
          properties: {
            user_id: {
              type: 'string',
              format: 'uuid',
            },
            full_name: {
              type: 'string',
              example: 'John Doe',
            },
            avatar_url: {
              type: 'string',
              nullable: true,
            },
            points: {
              type: 'integer',
              example: 150,
            },
            rank: {
              type: 'integer',
              example: 1,
            },
          },
        },
      },
    },
    tags: [
      {
        name: 'Health',
        description: 'Server health and readiness checks',
      },
      {
        name: 'Auth',
        description: 'Authentication and authorization',
      },
      {
        name: 'Users',
        description: 'User profile management',
      },
      {
        name: 'Achievements',
        description: 'Gamification and leaderboards',
      },
      {
        name: 'Flyers',
        description: 'Flyer uploads and retrieval',
      },
      {
        name: 'Recipes',
        description: 'Recipe management',
      },
      {
        name: 'Budgets',
        description: 'Budget tracking and analysis',
      },
      {
        name: 'Admin',
        description: 'Administrative operations (requires admin role)',
      },
      {
        name: 'System',
        description: 'System status and monitoring',
      },
    ],
  },
  // Path to the API routes files with JSDoc annotations
  apis: ['./src/routes/*.ts'],
};

export const swaggerSpec = swaggerJsdoc(options);
