/**
 * OpenAPI 3.1 document builder — tenant-public-api (wave-11 leaf-D).
 * Returns the full API schema as a plain JS object for serialization.
 */

export interface OpenAPIObject {
  openapi: string
  info: { title: string; version: string; description?: string }
  servers: Array<{ url: string; description?: string }>
  components: {
    securitySchemes: Record<string, unknown>
    schemas: Record<string, unknown>
  }
  security: Array<Record<string, unknown>>
  paths: Record<string, unknown>
}

export function buildOpenApiDocument(): OpenAPIObject {
  return {
    openapi: '3.1.0',
    info: {
      title: 'Zync Public API',
      version: '1.0.0',
      description: 'Machine-to-machine REST API for Zync Business+ tenants. Base URL: https://api.zync.is/v1',
    },
    servers: [{ url: 'https://api.zync.is', description: 'Production' }],
    components: {
      securitySchemes: {
        bearerApiKey: {
          type: 'http',
          scheme: 'bearer',
          bearerFormat: 'zyk_live_<key>',
          description: 'API key obtained from Settings → API Keys. Requires Business plan or higher.',
        },
      },
      schemas: {
        CustomerObject: {
          type: 'object',
          properties: {
            id: { type: 'string', format: 'uuid' },
            name: { type: 'string' },
            company: { type: ['string', 'null'] },
            email: { type: ['string', 'null'] },
            phone: { type: ['string', 'null'] },
            address: { type: ['object', 'null'] },
            status: { type: 'string', enum: ['active', 'archived'] },
            created_at: { type: 'string', format: 'date-time' },
            updated_at: { type: 'string', format: 'date-time' },
          },
          required: ['id', 'name', 'status', 'created_at', 'updated_at'],
        },
        InvoiceObject: {
          type: 'object',
          description: 'Monetary fields are decimal strings (not floats).',
          properties: {
            id: { type: 'string', format: 'uuid' },
            customer_id: { type: ['string', 'null'], format: 'uuid' },
            status: { type: 'string', enum: ['DRAFT', 'SENT', 'APPROVED', 'REJECTED', 'TAX_ISSUED', 'PAID', 'VOID', 'BAD_DEBT'] },
            currency: { type: 'string' },
            subtotal: { type: 'string', description: 'Decimal string, e.g. "1000.00"' },
            vat_amount: { type: 'string' },
            total: { type: 'string' },
            lines: { type: 'array', items: { '$ref': '#/components/schemas/InvoiceLineObject' } },
            created_at: { type: 'string', format: 'date-time' },
            updated_at: { type: 'string', format: 'date-time' },
          },
        },
        InvoiceLineObject: {
          type: 'object',
          properties: {
            id: { type: 'string', format: 'uuid' },
            description: { type: 'string' },
            quantity: { type: 'string' },
            unit_price: { type: 'string' },
            discount_pct: { type: 'string' },
            line_total: { type: 'string' },
            taxable: { type: 'boolean' },
            position: { type: 'integer' },
          },
        },
        TaskObject: {
          type: 'object',
          properties: {
            id: { type: 'string', format: 'uuid' },
            title: { type: 'string' },
            description_text: { type: ['string', 'null'], description: 'Plain-text extraction from Tiptap JSONB; raw JSONB not exposed.' },
            priority: { type: 'string', enum: ['low', 'medium', 'high', 'urgent'] },
            status_id: { type: 'string', format: 'uuid' },
            source: { type: 'string', description: 'Always "api" for API-created tasks.' },
            created_at: { type: 'string', format: 'date-time' },
            updated_at: { type: 'string', format: 'date-time' },
          },
        },
        EventObject: {
          type: 'object',
          properties: {
            id: { type: 'string', format: 'uuid' },
            endpoint_url: { type: 'string', description: 'Truncated to scheme+host+first-path-segment.' },
            event_type: { type: 'string' },
            status: { type: 'string', enum: ['pending', 'delivered', 'failed', 'test'] },
            response_status: { type: ['integer', 'null'] },
            latency_ms: { type: ['integer', 'null'] },
            attempt: { type: 'integer' },
            created_at: { type: 'string', format: 'date-time' },
          },
        },
        ApiError: {
          type: 'object',
          properties: {
            error: { type: 'string', description: 'Machine-readable snake_case code.' },
            message: { type: 'string' },
            field: { type: 'string', description: 'Present on 422 validation errors.' },
            required: { type: 'string', description: 'Present on 403 insufficient_scope.' },
            minimum_tier: { type: 'string', description: 'Present on 403 tier_required.' },
            retry_after: { type: 'integer', description: 'Seconds until retry allowed; present on 429.' },
          },
          required: ['error', 'message'],
        },
      },
    },
    security: [{ bearerApiKey: [] }],
    paths: {
      '/v1/customers': {
        get: {
          summary: 'List customers',
          operationId: 'listCustomers',
          tags: ['Customers'],
          parameters: [
            { name: 'limit', in: 'query', schema: { type: 'integer', default: 20, maximum: 100 } },
            { name: 'cursor', in: 'query', schema: { type: 'string' } },
            { name: 'status', in: 'query', schema: { type: 'string', enum: ['active', 'archived'] } },
            { name: 'search', in: 'query', schema: { type: 'string' } },
          ],
          responses: {
            '200': { description: 'Paginated customer list', content: { 'application/json': { schema: { type: 'object', properties: { data: { type: 'array', items: { '$ref': '#/components/schemas/CustomerObject' } } } } } } },
            '403': { description: 'Insufficient scope' },
          },
        },
        post: {
          summary: 'Create a customer',
          operationId: 'createCustomer',
          tags: ['Customers'],
          requestBody: { required: true, content: { 'application/json': { schema: { type: 'object', required: ['name'], properties: { name: { type: 'string' }, email: { type: 'string' }, phone: { type: 'string' } } } } } },
          responses: { '201': { description: 'Customer created' }, '422': { description: 'Validation error' } },
        },
      },
      '/v1/customers/{id}': {
        get: {
          summary: 'Get a customer',
          operationId: 'getCustomer',
          tags: ['Customers'],
          parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string', format: 'uuid' } }],
          responses: { '200': { description: 'Customer object' }, '404': { description: 'Not found' } },
        },
        patch: {
          summary: 'Update a customer',
          operationId: 'updateCustomer',
          tags: ['Customers'],
          parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string', format: 'uuid' } }],
          requestBody: { required: true, content: { 'application/json': { schema: { type: 'object' } } } },
          responses: { '200': { description: 'Updated customer' }, '404': { description: 'Not found' } },
        },
      },
      '/v1/invoices': {
        get: {
          summary: 'List invoices',
          operationId: 'listInvoices',
          tags: ['Invoices'],
          parameters: [
            { name: 'limit', in: 'query', schema: { type: 'integer', default: 20 } },
            { name: 'cursor', in: 'query', schema: { type: 'string' } },
            { name: 'status', in: 'query', schema: { type: 'string' } },
            { name: 'customer_id', in: 'query', schema: { type: 'string', format: 'uuid' } },
          ],
          responses: { '200': { description: 'Paginated invoice list' } },
        },
        post: {
          summary: 'Create a draft invoice',
          operationId: 'createInvoice',
          tags: ['Invoices'],
          responses: { '201': { description: 'Invoice created' } },
        },
      },
      '/v1/invoices/{id}': {
        get: {
          summary: 'Get an invoice with lines',
          operationId: 'getInvoice',
          tags: ['Invoices'],
          parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string', format: 'uuid' } }],
          responses: { '200': { description: 'Invoice with lines' }, '404': { description: 'Not found' } },
        },
      },
      '/v1/invoices/{id}/status': {
        patch: {
          summary: 'Update invoice status',
          operationId: 'updateInvoiceStatus',
          tags: ['Invoices'],
          parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string', format: 'uuid' } }],
          requestBody: { required: true, content: { 'application/json': { schema: { type: 'object', required: ['status'], properties: { status: { type: 'string' } } } } } },
          responses: { '200': { description: 'Updated invoice' } },
        },
      },
      '/v1/tasks': {
        get: {
          summary: 'List tasks',
          operationId: 'listTasks',
          tags: ['Tasks'],
          parameters: [
            { name: 'limit', in: 'query', schema: { type: 'integer', default: 20 } },
            { name: 'cursor', in: 'query', schema: { type: 'string' } },
            { name: 'project_id', in: 'query', schema: { type: 'string', format: 'uuid' } },
          ],
          responses: { '200': { description: 'Paginated task list' } },
        },
        post: {
          summary: 'Create a task',
          operationId: 'createTask',
          tags: ['Tasks'],
          requestBody: { required: true, content: { 'application/json': { schema: { type: 'object', required: ['title', 'status_id'] } } } },
          responses: { '201': { description: 'Task created' } },
        },
      },
      '/v1/tasks/{id}': {
        get: {
          summary: 'Get a task',
          operationId: 'getTask',
          tags: ['Tasks'],
          parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string', format: 'uuid' } }],
          responses: { '200': { description: 'Task object' }, '404': { description: 'Not found' } },
        },
        patch: {
          summary: 'Update a task',
          operationId: 'updateTask',
          tags: ['Tasks'],
          parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string', format: 'uuid' } }],
          requestBody: { required: true, content: { 'application/json': { schema: { type: 'object' } } } },
          responses: { '200': { description: 'Updated task' } },
        },
      },
      '/v1/events': {
        get: {
          summary: 'List webhook delivery events',
          operationId: 'listEvents',
          tags: ['Events'],
          parameters: [
            { name: 'limit', in: 'query', schema: { type: 'integer', default: 20 } },
            { name: 'status', in: 'query', schema: { type: 'string', enum: ['pending', 'delivered', 'failed', 'test'] } },
          ],
          responses: { '200': { description: 'Event list' } },
        },
      },
    },
  }
}
