const swaggerJsdoc = require('swagger-jsdoc');
const path = require('path');

const API_VERSION = process.env.API_VERSION || 'v1';
const API_BASE_PATH = `/api/${API_VERSION}`;

const options = {
    definition: {
        openapi: '3.0.0',
        info: {
            title: 'Tududi API',
            version: '1.0.0',
            description: 'REST API for Tududi task management application',
            contact: {
                name: 'Tududi',
                url: 'https://github.com/chrisvel/tududi',
            },
            license: {
                name: 'MIT',
                url: 'https://opensource.org/licenses/MIT',
            },
        },
        servers: [
            {
                url: 'http://localhost:3002',
                description: `Backend server (base path ${API_BASE_PATH})`,
            },
            {
                url: 'http://localhost:8080',
                description: `Frontend dev server (proxy to ${API_BASE_PATH})`,
            },
        ],
        components: {
            securitySchemes: {
                cookieAuth: {
                    type: 'apiKey',
                    in: 'cookie',
                    name: 'connect.sid',
                    description: 'Session cookie authentication',
                },
                BearerAuth: {
                    type: 'http',
                    scheme: 'bearer',
                    bearerFormat: 'JWT',
                    description:
                        'JWT token authentication via Authorization header',
                },
            },
            schemas: {
                Error: {
                    type: 'object',
                    properties: {
                        error: {
                            type: 'string',
                            description: 'Error type',
                        },
                        message: {
                            type: 'string',
                            description: 'Error message',
                        },
                    },
                },
                Task: {
                    type: 'object',
                    properties: {
                        id: {
                            type: 'integer',
                            description: 'Task ID',
                        },
                        uid: {
                            type: 'string',
                            description: 'Task unique identifier',
                        },
                        name: {
                            type: 'string',
                            description: 'Task name',
                        },
                        note: {
                            type: 'string',
                            description:
                                'Task description (Markdown supported)',
                        },
                        status: {
                            type: 'string',
                            enum: ['pending', 'completed', 'archived'],
                            description: 'Task status',
                        },
                        priority: {
                            type: 'string',
                            enum: ['low', 'medium', 'high'],
                            description: 'Task priority',
                        },
                        due_date: {
                            type: 'string',
                            format: 'date-time',
                            description: 'Task due date',
                        },
                        project_id: {
                            type: 'integer',
                            description: 'Associated project ID',
                        },
                        recurring_pattern: {
                            type: 'string',
                            enum: ['daily', 'weekly', 'monthly', 'yearly'],
                            description: 'Recurring pattern',
                        },
                        created_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                        updated_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                    },
                },
                Project: {
                    type: 'object',
                    properties: {
                        id: {
                            type: 'integer',
                            description: 'Project ID',
                        },
                        uid: {
                            type: 'string',
                            description: 'Project unique identifier',
                        },
                        name: {
                            type: 'string',
                            description: 'Project name',
                        },
                        description: {
                            type: 'string',
                            description: 'Project description',
                        },
                        status: {
                            type: 'string',
                            enum: [
                                'not_started',
                                'planned',
                                'in_progress',
                                'waiting',
                                'done',
                                'cancelled',
                            ],
                            description: 'Project status',
                        },
                        priority: {
                            type: 'string',
                            enum: ['low', 'medium', 'high'],
                            description: 'Project priority',
                        },
                        created_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                        updated_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                    },
                },
                Note: {
                    type: 'object',
                    properties: {
                        id: {
                            type: 'integer',
                            description: 'Note ID',
                        },
                        uid: {
                            type: 'string',
                            description: 'Note unique identifier',
                        },
                        title: {
                            type: 'string',
                            description: 'Note title',
                        },
                        content: {
                            type: 'string',
                            description: 'Note content (Markdown supported)',
                        },
                        color: {
                            type: 'string',
                            description: 'Note background color (hex)',
                        },
                        project_id: {
                            type: 'integer',
                            description: 'Associated project ID',
                        },
                        created_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                        updated_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                    },
                },
                Tag: {
                    type: 'object',
                    properties: {
                        id: {
                            type: 'integer',
                            description: 'Tag ID',
                        },
                        uid: {
                            type: 'string',
                            description: 'Tag unique identifier',
                        },
                        name: {
                            type: 'string',
                            description: 'Tag name',
                        },
                        created_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                        updated_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                    },
                },
                InboxItem: {
                    type: 'object',
                    properties: {
                        id: {
                            type: 'integer',
                            description: 'Inbox item ID',
                        },
                        uid: {
                            type: 'string',
                            description: 'Inbox item unique identifier',
                        },
                        content: {
                            type: 'string',
                            description: 'Inbox item content',
                        },
                        status: {
                            type: 'string',
                            enum: ['added', 'processed', 'ignored'],
                            description: 'Processing status',
                        },
                        created_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                        updated_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                    },
                },
                Area: {
                    type: 'object',
                    properties: {
                        id: {
                            type: 'integer',
                            description: 'Area ID',
                        },
                        uid: {
                            type: 'string',
                            description: 'Area unique identifier',
                        },
                        name: {
                            type: 'string',
                            description: 'Area name',
                        },
                        description: {
                            type: 'string',
                            description: 'Area description',
                        },
                        created_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                        updated_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                    },
                },
                ApiKey: {
                    type: 'object',
                    properties: {
                        id: { type: 'integer' },
                        name: {
                            type: 'string',
                            description: 'Friendly label for the API key',
                        },
                        token_prefix: {
                            type: 'string',
                            description:
                                'First characters displayed to help identify the key',
                        },
                        created_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                        updated_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                        last_used_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                        expires_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                        revoked_at: {
                            type: 'string',
                            format: 'date-time',
                        },
                    },
                },
            },
        },
        security: [
            {
                cookieAuth: [],
            },
        ],
    },
    apis: [path.join(__dirname, '..', 'docs', 'swagger', '*.js')], // Path to centralized Swagger documentation files
};

const swaggerSpec = swaggerJsdoc(options);

if (swaggerSpec?.paths) {
    const updatedPaths = {};

    Object.entries(swaggerSpec.paths).forEach(([pathKey, pathValue]) => {
        if (pathKey.startsWith('/api/')) {
            const versionedPath =
                API_BASE_PATH === '/api'
                    ? pathKey
                    : `${API_BASE_PATH}${pathKey.slice(4)}`;
            updatedPaths[versionedPath] = pathValue;
        } else {
            updatedPaths[pathKey] = pathValue;
        }
    });

    swaggerSpec.paths = updatedPaths;
}

module.exports = swaggerSpec;
