export interface OpenApiBuildOptions {
  baseUrl: string;
  appVersion: string;
}

export function buildOpenApiDocument(options: OpenApiBuildOptions): unknown {
  const { baseUrl, appVersion } = options;

  return {
    openapi: '3.1.0',
    info: {
      title: 'MetoYou Local Desktop API',
      version: appVersion,
      description:
        'Authenticated local HTTP API exposed by the MetoYou desktop app. '
        + 'Authentication is performed against a configured signaling server. '
        + 'Bearer tokens issued here are scoped to this device only.'
    },
    servers: [{ url: baseUrl }],
    components: {
      securitySchemes: {
        bearerAuth: {
          type: 'http',
          scheme: 'bearer',
          bearerFormat: 'opaque'
        }
      },
      schemas: {
        Error: {
          type: 'object',
          required: ['error'],
          properties: {
            error: { type: 'string' },
            errorCode: { type: 'string' }
          }
        },
        LoginRequest: {
          type: 'object',
          required: [
            'username',
            'password',
            'serverUrl'
          ],
          properties: {
            username: { type: 'string' },
            password: { type: 'string' },
            serverUrl: {
              type: 'string',
              format: 'uri',
              description: 'Base URL of the signaling server to authenticate against. Must be in the allowed list configured in the desktop app.'
            }
          }
        },
        LoginResponse: {
          type: 'object',
          required: [
            'token',
            'expiresAt',
            'user'
          ],
          properties: {
            token: { type: 'string' },
            expiresAt: { type: 'integer', format: 'int64' },
            user: { $ref: '#/components/schemas/AuthUser' }
          }
        },
        AuthUser: {
          type: 'object',
          required: [
            'id',
            'username',
            'displayName'
          ],
          properties: {
            id: { type: 'string' },
            username: { type: 'string' },
            displayName: { type: 'string' }
          }
        },
        Profile: {
          type: 'object',
          properties: {
            id: { type: 'string' },
            username: { type: 'string' },
            displayName: { type: 'string' },
            description: { type: 'string' },
            avatarUrl: { type: 'string' },
            status: { type: 'string' }
          }
        },
        Room: {
          type: 'object',
          properties: {
            id: { type: 'string' },
            name: { type: 'string' }
          },
          additionalProperties: true
        },
        Message: {
          type: 'object',
          properties: {
            id: { type: 'string' },
            roomId: { type: 'string' },
            channelId: { type: 'string' },
            senderId: { type: 'string' },
            senderName: { type: 'string' },
            content: { type: 'string' },
            timestamp: { type: 'integer', format: 'int64' },
            editedAt: { type: 'integer', format: 'int64' },
            isDeleted: { type: 'boolean' }
          },
          additionalProperties: true
        }
      }
    },
    security: [{ bearerAuth: [] }],
    paths: {
      '/api/health': {
        get: {
          security: [],
          summary: 'Liveness probe',
          responses: {
            '200': {
              description: 'Service is alive',
              content: {
                'application/json': {
                  schema: {
                    type: 'object',
                    properties: {
                      status: { type: 'string' },
                      version: { type: 'string' }
                    }
                  }
                }
              }
            }
          }
        }
      },
      '/api/openapi.json': {
        get: {
          security: [],
          summary: 'OpenAPI specification',
          responses: { '200': { description: 'This document' } }
        }
      },
      '/api/auth/login': {
        post: {
          security: [],
          summary: 'Exchange username/password (validated by a signaling server) for a bearer token',
          requestBody: {
            required: true,
            content: {
              'application/json': {
                schema: { $ref: '#/components/schemas/LoginRequest' }
              }
            }
          },
          responses: {
            '200': {
              description: 'Token issued',
              content: {
                'application/json': {
                  schema: { $ref: '#/components/schemas/LoginResponse' }
                }
              }
            },
            '401': {
              description: 'Invalid credentials',
              content: {
                'application/json': { schema: { $ref: '#/components/schemas/Error' } }
              }
            },
            '403': {
              description: 'Signaling server URL not allowed',
              content: {
                'application/json': { schema: { $ref: '#/components/schemas/Error' } }
              }
            }
          }
        }
      },
      '/api/auth/logout': {
        post: {
          summary: 'Revoke the current bearer token',
          responses: { '204': { description: 'Token revoked' } }
        }
      },
      '/api/profile': {
        get: {
          summary: 'Get the current user profile',
          responses: {
            '200': {
              description: 'Current user profile',
              content: {
                'application/json': {
                  schema: { $ref: '#/components/schemas/Profile' }
                }
              }
            },
            '404': {
              description: 'No current user is set on this device',
              content: {
                'application/json': { schema: { $ref: '#/components/schemas/Error' } }
              }
            }
          }
        }
      },
      '/api/rooms': {
        get: {
          summary: 'List rooms (servers) known to this device',
          responses: {
            '200': {
              description: 'Rooms array',
              content: {
                'application/json': {
                  schema: {
                    type: 'array',
                    items: { $ref: '#/components/schemas/Room' }
                  }
                }
              }
            }
          }
        }
      },
      '/api/rooms/{roomId}/messages': {
        get: {
          summary: 'List messages for a room',
          parameters: [
            { name: 'roomId', in: 'path', required: true, schema: { type: 'string' } },
            { name: 'limit', in: 'query', required: false, schema: { type: 'integer', minimum: 1, maximum: 500 } },
            { name: 'offset', in: 'query', required: false, schema: { type: 'integer', minimum: 0 } }
          ],
          responses: {
            '200': {
              description: 'Messages array',
              content: {
                'application/json': {
                  schema: {
                    type: 'array',
                    items: { $ref: '#/components/schemas/Message' }
                  }
                }
              }
            }
          }
        }
      }
    }
  };
}
