import { zodToJsonSchema } from 'zod-to-json-schema'

type JsonObject = Record<string, unknown>

// ── Vehicles ─────────────────────────────────────────────────────────────────
import {
  vehicleSchema,
  calendarBlockSchema,
  maintenanceLogSchema,
  publishSchema,
  statusSchema,
} from '../modules/vehicles/vehicle.schemas'

// ── Reservations ─────────────────────────────────────────────────────────────
import {
  createSchema as reservationCreateSchema,
  updateSchema as reservationUpdateSchema,
  checkinSchema,
  checkoutSchema,
  extendSchema,
  cancelSchema,
  approvalSchema,
  inspectionSchema,
  additionalDriverSchema,
} from '../modules/reservations/reservation.schemas'

// ── Customers ─────────────────────────────────────────────────────────────────
import {
  customerSchema,
  approveLicenseSchema,
  flagSchema,
} from '../modules/customers/customer.schemas'

// ── Offers ────────────────────────────────────────────────────────────────────
import { offerSchema } from '../modules/offers/offer.schemas'

// ── Payments ─────────────────────────────────────────────────────────────────
import {
  chargeSchema,
  manualPaymentSchema,
  refundSchema,
} from '../modules/payments/payment.schemas'

// ── Reviews ───────────────────────────────────────────────────────────────────
import { replySchema } from '../modules/reviews/review.schemas'

// ── Complaints ────────────────────────────────────────────────────────────────
import {
  createSchema as complaintCreateSchema,
  updateSchema as complaintUpdateSchema,
} from '../modules/complaints/complaint.schemas'

// ── Auth ──────────────────────────────────────────────────────────────────────
import { companySignupSchema } from '../modules/auth/auth.company.schemas'
import {
  employeeLoginSchema,
  employeeForgotPasswordSchema,
  employeeResetPasswordSchema,
  employeeLanguageSchema,
} from '../modules/auth/auth.employee.schemas'
import { renterUpdateSchema, renterFcmTokenSchema } from '../modules/auth/auth.renter.schemas'

// ─────────────────────────────────────────────────────────────────────────────

function s(schema: unknown): JsonObject {
  const { $schema, ...rest } = zodToJsonSchema(
    schema as Parameters<typeof zodToJsonSchema>[0],
    { target: 'openApi3' },
  ) as JsonObject
  return rest
}

const idPath = (name = 'id'): JsonObject => ({
  name,
  in: 'path' as const,
  required: true,
  schema: { type: 'string' },
})

const pagingParams: JsonObject[] = [
  { name: 'page',     in: 'query', schema: { type: 'integer', default: 1 } },
  { name: 'pageSize', in: 'query', schema: { type: 'integer', default: 20 } },
]

const jsonBody = (ref: string): JsonObject => ({
  required: true,
  content: { 'application/json': { schema: { $ref: ref } } },
})

const ok: JsonObject = { description: 'Success' }
const err4: JsonObject = { description: 'Validation error', content: { 'application/json': { schema: { type: 'object', properties: { error: { type: 'string' } } } } } }
const err401: JsonObject = { description: 'Unauthorized' }
const err404: JsonObject = { description: 'Not found' }

export const openApiDocument: JsonObject = {
  openapi: '3.0.3',
  info: {
    title: 'RentalDriveGo API',
    description: 'REST API for the RentalDriveGo car rental management platform.\n\n**Auth:** Most browser endpoints use HttpOnly session cookies issued by `/auth/employee/login`, `/admin/auth/login`, or renter auth. Trusted server/mobile contexts may still use Bearer JWTs where documented.',
    version: '1.0.0',
    contact: { name: 'RentalDriveGo', email: 'support@rentaldrivego.com' },
  },
  servers: [{ url: '/api/v1', description: 'v1' }],
  security: [{ bearerAuth: [] }],
  tags: [
    { name: 'Health',          description: 'Service health' },
    { name: 'Auth — Company',  description: 'Company account registration' },
    { name: 'Auth — Employee', description: 'Employee (dashboard) authentication' },
    { name: 'Auth — Renter',   description: 'Renter (mobile) authentication' },
    { name: 'Vehicles',        description: 'Fleet management' },
    { name: 'Reservations',    description: 'Booking lifecycle' },
    { name: 'Customers',       description: 'Customer profiles & documents' },
    { name: 'Offers',          description: 'Discounts & promo codes' },
    { name: 'Payments',        description: 'Charges, manual payments, refunds' },
    { name: 'Reviews',         description: 'Customer reviews' },
    { name: 'Complaints',      description: 'Complaint tracking' },
    { name: 'Analytics',       description: 'Dashboard & reports' },
    { name: 'Notifications',   description: 'In-app notifications' },
    { name: 'Companies',       description: 'Company profile & settings' },
    { name: 'Team',            description: 'Employee management' },
    { name: 'Subscriptions',   description: 'Plan management & billing' },
    { name: 'Carplace',     description: 'Public booking portal' },
    { name: 'Site',            description: 'White-label site API' },
    { name: 'Admin',           description: 'Platform administration' },
  ],
  components: {
    securitySchemes: {
      bearerAuth: { type: 'http', scheme: 'bearer', bearerFormat: 'JWT' },
    },
    schemas: {
      // ── Vehicles ────────────────────────────────────────────────
      VehicleInput:       s(vehicleSchema),
      CalendarBlock:      s(calendarBlockSchema),
      MaintenanceLog:     s(maintenanceLogSchema),
      VehiclePublish:     s(publishSchema),
      VehicleStatus:      s(statusSchema),
      // ── Reservations ────────────────────────────────────────────
      ReservationCreate:  s(reservationCreateSchema),
      ReservationUpdate:  s(reservationUpdateSchema),
      AdditionalDriver:   s(additionalDriverSchema),
      Inspection:         s(inspectionSchema),
      ReservationCheckin: s(checkinSchema),
      ReservationCheckout:s(checkoutSchema),
      ReservationExtend:  s(extendSchema),
      ReservationCancel:  s(cancelSchema),
      ReservationApproval:s(approvalSchema),
      // ── Customers ───────────────────────────────────────────────
      CustomerInput:      s(customerSchema),
      ApproveLicense:     s(approveLicenseSchema),
      FlagCustomer:       s(flagSchema),
      // ── Offers ──────────────────────────────────────────────────
      OfferInput:         s(offerSchema),
      // ── Payments ────────────────────────────────────────────────
      PaymentCharge:      s(chargeSchema),
      ManualPayment:      s(manualPaymentSchema),
      Refund:             s(refundSchema),
      // ── Reviews ─────────────────────────────────────────────────
      ReviewReply:        s(replySchema),
      // ── Complaints ──────────────────────────────────────────────
      ComplaintCreate:    s(complaintCreateSchema),
      ComplaintUpdate:    s(complaintUpdateSchema),
      // ── Auth ────────────────────────────────────────────────────
      CompanySignup:      s(companySignupSchema),
      EmployeeLogin:      s(employeeLoginSchema),
      EmployeeForgotPassword: s(employeeForgotPasswordSchema),
      EmployeeResetPassword:  s(employeeResetPasswordSchema),
      EmployeeLanguage:   s(employeeLanguageSchema),
      RenterUpdate:       s(renterUpdateSchema),
      RenterFcmToken:     s(renterFcmTokenSchema),
    },
  },
  paths: {
    // ════════════════════════════════════════════════════════════════
    // HEALTH  (no /api/v1 prefix — served directly from app root)
    // ════════════════════════════════════════════════════════════════
    '/health': {
      get: {
        tags: ['Health'],
        summary: 'Health check',
        security: [],
        servers: [{ url: '/' }],
        responses: {
          '200': { description: 'OK', content: { 'application/json': { schema: { type: 'object', properties: { status: { type: 'string', example: 'ok' }, version: { type: 'string' }, timestamp: { type: 'string', format: 'date-time' } } } } } },
        },
      },
    },

    // ════════════════════════════════════════════════════════════════
    // AUTH — COMPANY
    // ════════════════════════════════════════════════════════════════
    '/auth/company/signup': {
      post: {
        tags: ['Auth — Company'],
        summary: 'Register a new company',
        security: [],
        requestBody: jsonBody('#/components/schemas/CompanySignup'),
        responses: { '201': ok, '400': err4, '409': { description: 'Email already in use' } },
      },
    },

    // ════════════════════════════════════════════════════════════════
    // AUTH — EMPLOYEE
    // ════════════════════════════════════════════════════════════════
    '/auth/employee/login': {
      post: {
        tags: ['Auth — Employee'],
        summary: 'Login',
        security: [],
        requestBody: jsonBody('#/components/schemas/EmployeeLogin'),
        responses: {
          '200': { description: 'Token + employee object', content: { 'application/json': { schema: { type: 'object', properties: { token: { type: 'string' }, employee: { type: 'object' } } } } } },
          '401': err401,
        },
      },
    },
    '/auth/employee/forgot-password': {
      post: {
        tags: ['Auth — Employee'],
        summary: 'Request password-reset email',
        security: [],
        requestBody: jsonBody('#/components/schemas/EmployeeForgotPassword'),
        responses: { '200': ok },
      },
    },
    '/auth/employee/reset-password': {
      post: {
        tags: ['Auth — Employee'],
        summary: 'Reset password with token',
        security: [],
        requestBody: jsonBody('#/components/schemas/EmployeeResetPassword'),
        responses: { '200': ok, '400': err4 },
      },
    },
    '/auth/employee/me': {
      get: {
        tags: ['Auth — Employee'],
        summary: 'Current employee profile',
        responses: { '200': ok, '401': err401 },
      },
    },
    '/auth/employee/me/language': {
      patch: {
        tags: ['Auth — Employee'],
        summary: 'Update preferred language',
        requestBody: jsonBody('#/components/schemas/EmployeeLanguage'),
        responses: { '200': ok },
      },
    },

    // ════════════════════════════════════════════════════════════════
    // AUTH — RENTER
    // ════════════════════════════════════════════════════════════════
    '/auth/renter/me': {
      get: {
        tags: ['Auth — Renter'],
        summary: 'Current renter profile',
        responses: { '200': ok, '401': err401 },
      },
      patch: {
        tags: ['Auth — Renter'],
        summary: 'Update renter profile',
        requestBody: jsonBody('#/components/schemas/RenterUpdate'),
        responses: { '200': ok },
      },
    },
    '/auth/renter/me/fcm-token': {
      post: {
        tags: ['Auth — Renter'],
        summary: 'Register FCM push token',
        requestBody: jsonBody('#/components/schemas/RenterFcmToken'),
        responses: { '200': ok },
      },
    },

    // ════════════════════════════════════════════════════════════════
    // VEHICLES
    // ════════════════════════════════════════════════════════════════
    '/vehicles': {
      get: {
        tags: ['Vehicles'],
        summary: 'List vehicles',
        parameters: [
          { name: 'status',    in: 'query', schema: { type: 'string', enum: ['AVAILABLE','RESERVED','READY','RENTED','RETURNED','NEEDS_CLEANING','MAINTENANCE','DAMAGE_REVIEW','OUT_OF_SERVICE'] } },
          { name: 'category',  in: 'query', schema: { type: 'string', enum: ['ECONOMY','COMPACT','MIDSIZE','FULLSIZE','SUV','LUXURY','VAN','TRUCK'] } },
          { name: 'published', in: 'query', schema: { type: 'string', enum: ['true','false'] } },
          ...pagingParams,
        ],
        responses: { '200': ok },
      },
      post: {
        tags: ['Vehicles'],
        summary: 'Create vehicle',
        requestBody: jsonBody('#/components/schemas/VehicleInput'),
        responses: { '201': ok, '400': err4 },
      },
    },
    '/vehicles/{id}': {
      get: {
        tags: ['Vehicles'],
        summary: 'Get vehicle',
        parameters: [idPath()],
        responses: { '200': ok, '404': err404 },
      },
      patch: {
        tags: ['Vehicles'],
        summary: 'Update vehicle',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/VehicleInput'),
        responses: { '200': ok, '404': err404 },
      },
      delete: {
        tags: ['Vehicles'],
        summary: 'Delete vehicle',
        parameters: [idPath()],
        responses: { '200': ok },
      },
    },
    '/vehicles/{id}/status': {
      patch: {
        tags: ['Vehicles'],
        summary: 'Set vehicle status',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/VehicleStatus'),
        responses: { '200': ok },
      },
    },
    '/vehicles/{id}/publish': {
      patch: {
        tags: ['Vehicles'],
        summary: 'Publish / unpublish vehicle',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/VehiclePublish'),
        responses: { '200': ok },
      },
    },
    '/vehicles/{id}/photos': {
      post: {
        tags: ['Vehicles'],
        summary: 'Upload photos (multipart, max 10)',
        parameters: [idPath()],
        requestBody: { required: true, content: { 'multipart/form-data': { schema: { type: 'object', properties: { photos: { type: 'array', items: { type: 'string', format: 'binary' } } } } } } },
        responses: { '200': ok },
      },
    },
    '/vehicles/{id}/photos/{idx}': {
      delete: {
        tags: ['Vehicles'],
        summary: 'Delete photo by index',
        parameters: [idPath(), { name: 'idx', in: 'path', required: true, schema: { type: 'integer' } }],
        responses: { '200': ok },
      },
    },
    '/vehicles/{id}/availability': {
      get: {
        tags: ['Vehicles'],
        summary: 'Check availability for a date range',
        parameters: [
          idPath(),
          { name: 'startDate', in: 'query', required: true, schema: { type: 'string', format: 'date-time' } },
          { name: 'endDate',   in: 'query', required: true, schema: { type: 'string', format: 'date-time' } },
        ],
        responses: { '200': ok },
      },
    },
    '/vehicles/{id}/calendar': {
      get: {
        tags: ['Vehicles'],
        summary: 'Get monthly calendar events',
        parameters: [
          idPath(),
          { name: 'year',  in: 'query', required: true, schema: { type: 'integer' } },
          { name: 'month', in: 'query', required: true, schema: { type: 'integer', minimum: 1, maximum: 12 } },
        ],
        responses: { '200': ok },
      },
    },
    '/vehicles/{id}/calendar/blocks': {
      post: {
        tags: ['Vehicles'],
        summary: 'Create calendar block',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/CalendarBlock'),
        responses: { '201': ok },
      },
    },
    '/vehicles/{id}/calendar/blocks/{blockId}': {
      delete: {
        tags: ['Vehicles'],
        summary: 'Delete calendar block',
        parameters: [idPath(), idPath('blockId')],
        responses: { '200': ok },
      },
    },
    '/vehicles/{id}/maintenance': {
      get: {
        tags: ['Vehicles'],
        summary: 'List maintenance logs',
        parameters: [idPath()],
        responses: { '200': ok },
      },
      post: {
        tags: ['Vehicles'],
        summary: 'Add maintenance log',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/MaintenanceLog'),
        responses: { '201': ok },
      },
    },

    // ════════════════════════════════════════════════════════════════
    // RESERVATIONS
    // ════════════════════════════════════════════════════════════════
    '/reservations': {
      get: {
        tags: ['Reservations'],
        summary: 'List reservations',
        parameters: [
          { name: 'status',    in: 'query', schema: { type: 'string' } },
          { name: 'vehicleId', in: 'query', schema: { type: 'string' } },
          { name: 'source',    in: 'query', schema: { type: 'string' } },
          { name: 'startDate', in: 'query', schema: { type: 'string' } },
          { name: 'endDate',   in: 'query', schema: { type: 'string' } },
          ...pagingParams,
        ],
        responses: { '200': ok },
      },
      post: {
        tags: ['Reservations'],
        summary: 'Create reservation',
        requestBody: jsonBody('#/components/schemas/ReservationCreate'),
        responses: { '201': ok, '400': err4 },
      },
    },
    '/reservations/{id}': {
      get: {
        tags: ['Reservations'],
        summary: 'Get reservation',
        parameters: [idPath()],
        responses: { '200': ok, '404': err404 },
      },
      patch: {
        tags: ['Reservations'],
        summary: 'Update reservation',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/ReservationUpdate'),
        responses: { '200': ok },
      },
    },
    '/reservations/{id}/confirm': {
      post: {
        tags: ['Reservations'],
        summary: 'Confirm reservation',
        parameters: [idPath()],
        responses: { '200': ok },
      },
    },
    '/reservations/{id}/approve': {
      patch: {
        tags: ['Reservations'],
        summary: 'Approve or reject pending reservation',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/ReservationApproval'),
        responses: { '200': ok },
      },
    },
    '/reservations/{id}/checkin': {
      post: {
        tags: ['Reservations'],
        summary: 'Check in',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/ReservationCheckin'),
        responses: { '200': ok },
      },
    },
    '/reservations/{id}/checkout': {
      post: {
        tags: ['Reservations'],
        summary: 'Check out',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/ReservationCheckout'),
        responses: { '200': ok },
      },
    },
    '/reservations/{id}/close': {
      post: {
        tags: ['Reservations'],
        summary: 'Close reservation',
        parameters: [idPath()],
        responses: { '200': ok },
      },
    },
    '/reservations/{id}/extend': {
      post: {
        tags: ['Reservations'],
        summary: 'Extend reservation end date',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/ReservationExtend'),
        responses: { '200': ok },
      },
    },
    '/reservations/{id}/cancel': {
      post: {
        tags: ['Reservations'],
        summary: 'Cancel reservation',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/ReservationCancel'),
        responses: { '200': ok },
      },
    },
    '/reservations/{id}/contract': {
      get: {
        tags: ['Reservations'],
        summary: 'Download rental contract (PDF)',
        parameters: [idPath()],
        responses: { '200': { description: 'PDF file', content: { 'application/pdf': {} } } },
      },
    },
    '/reservations/{id}/billing': {
      get: {
        tags: ['Reservations'],
        summary: 'Get billing summary',
        parameters: [idPath()],
        responses: { '200': ok },
      },
    },
    '/reservations/{id}/inspections': {
      get: {
        tags: ['Reservations'],
        summary: 'List inspections',
        parameters: [idPath()],
        responses: { '200': ok },
      },
    },
    '/reservations/{id}/inspections/{type}': {
      put: {
        tags: ['Reservations'],
        summary: 'Save inspection (CHECKIN or CHECKOUT)',
        parameters: [
          idPath(),
          { name: 'type', in: 'path', required: true, schema: { type: 'string', enum: ['CHECKIN', 'CHECKOUT'] } },
        ],
        requestBody: jsonBody('#/components/schemas/Inspection'),
        responses: { '200': ok },
      },
    },
    '/reservations/{id}/photos': {
      get: {
        tags: ['Reservations'],
        summary: 'List reservation photos',
        parameters: [idPath()],
        responses: { '200': ok },
      },
      post: {
        tags: ['Reservations'],
        summary: 'Upload reservation photo',
        parameters: [idPath()],
        requestBody: { required: true, content: { 'multipart/form-data': { schema: { type: 'object', properties: { photo: { type: 'string', format: 'binary' } } } } } },
        responses: { '201': ok },
      },
    },
    '/reservations/{id}/photos/{photoId}': {
      delete: {
        tags: ['Reservations'],
        summary: 'Delete reservation photo',
        parameters: [idPath(), idPath('photoId')],
        responses: { '200': ok },
      },
    },
    '/reservations/{id}/additional-drivers/{driverId}/approval': {
      patch: {
        tags: ['Reservations'],
        summary: 'Approve/reject additional driver',
        parameters: [idPath(), idPath('driverId')],
        requestBody: jsonBody('#/components/schemas/ReservationApproval'),
        responses: { '200': ok },
      },
    },

    // ════════════════════════════════════════════════════════════════
    // CUSTOMERS
    // ════════════════════════════════════════════════════════════════
    '/customers': {
      get: {
        tags: ['Customers'],
        summary: 'List customers',
        parameters: [
          { name: 'q',       in: 'query', schema: { type: 'string' } },
          { name: 'flagged', in: 'query', schema: { type: 'string', enum: ['true', 'false'] } },
          ...pagingParams,
        ],
        responses: { '200': ok },
      },
      post: {
        tags: ['Customers'],
        summary: 'Create customer',
        requestBody: jsonBody('#/components/schemas/CustomerInput'),
        responses: { '201': ok, '400': err4 },
      },
    },
    '/customers/{id}': {
      get: {
        tags: ['Customers'],
        summary: 'Get customer',
        parameters: [idPath()],
        responses: { '200': ok, '404': err404 },
      },
      patch: {
        tags: ['Customers'],
        summary: 'Update customer',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/CustomerInput'),
        responses: { '200': ok },
      },
    },
    '/customers/{id}/flag': {
      post: {
        tags: ['Customers'],
        summary: 'Flag customer',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/FlagCustomer'),
        responses: { '200': ok },
      },
      delete: {
        tags: ['Customers'],
        summary: 'Unflag customer',
        parameters: [idPath()],
        responses: { '200': ok },
      },
    },
    '/customers/{id}/validate-license': {
      post: {
        tags: ['Customers'],
        summary: 'Validate customer driving license',
        parameters: [idPath()],
        responses: { '200': ok },
      },
    },
    '/customers/{id}/license-image': {
      post: {
        tags: ['Customers'],
        summary: 'Upload license image',
        parameters: [idPath()],
        requestBody: { required: true, content: { 'multipart/form-data': { schema: { type: 'object', properties: { file: { type: 'string', format: 'binary' } } } } } },
        responses: { '200': ok },
      },
    },
    '/customers/{id}/approve-license': {
      post: {
        tags: ['Customers'],
        summary: 'Approve or deny license',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/ApproveLicense'),
        responses: { '200': ok },
      },
    },

    // ════════════════════════════════════════════════════════════════
    // OFFERS
    // ════════════════════════════════════════════════════════════════
    '/offers': {
      get: {
        tags: ['Offers'],
        summary: 'List offers',
        parameters: [
          { name: 'active', in: 'query', schema: { type: 'string', enum: ['true', 'false'] } },
          { name: 'public', in: 'query', schema: { type: 'string', enum: ['true', 'false'] } },
        ],
        responses: { '200': ok },
      },
      post: {
        tags: ['Offers'],
        summary: 'Create offer',
        requestBody: jsonBody('#/components/schemas/OfferInput'),
        responses: { '201': ok, '400': err4 },
      },
    },
    '/offers/{id}': {
      get: {
        tags: ['Offers'],
        summary: 'Get offer',
        parameters: [idPath()],
        responses: { '200': ok, '404': err404 },
      },
      patch: {
        tags: ['Offers'],
        summary: 'Update offer',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/OfferInput'),
        responses: { '200': ok },
      },
      delete: {
        tags: ['Offers'],
        summary: 'Delete offer',
        parameters: [idPath()],
        responses: { '200': ok },
      },
    },
    '/offers/{id}/activate': {
      post: { tags: ['Offers'], summary: 'Activate offer',   parameters: [idPath()], responses: { '200': ok } },
    },
    '/offers/{id}/deactivate': {
      post: { tags: ['Offers'], summary: 'Deactivate offer', parameters: [idPath()], responses: { '200': ok } },
    },
    '/offers/{id}/stats': {
      get: { tags: ['Offers'], summary: 'Offer usage stats', parameters: [idPath()], responses: { '200': ok } },
    },

    // ════════════════════════════════════════════════════════════════
    // PAYMENTS
    // ════════════════════════════════════════════════════════════════
    '/payments/company': {
      get: {
        tags: ['Payments'],
        summary: 'List all company payments',
        responses: { '200': ok },
      },
    },
    '/payments/reservations/{id}': {
      get: {
        tags: ['Payments'],
        summary: 'Get payments for a reservation',
        parameters: [idPath()],
        responses: { '200': ok },
      },
    },
    '/payments/reservations/{id}/charge': {
      post: {
        tags: ['Payments'],
        summary: 'Initiate online payment (AmanPay / PayPal)',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/PaymentCharge'),
        responses: { '200': ok, '400': err4 },
      },
    },
    '/payments/reservations/{id}/capture-paypal': {
      post: {
        tags: ['Payments'],
        summary: 'Capture PayPal order',
        parameters: [idPath()],
        responses: { '200': ok },
      },
    },
    '/payments/reservations/{id}/manual': {
      post: {
        tags: ['Payments'],
        summary: 'Record manual payment',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/ManualPayment'),
        responses: { '201': ok, '400': err4 },
      },
    },
    '/payments/reservations/{reservationId}/payments/{paymentId}/refund': {
      post: {
        tags: ['Payments'],
        summary: 'Refund a payment',
        parameters: [idPath('reservationId'), idPath('paymentId')],
        requestBody: jsonBody('#/components/schemas/Refund'),
        responses: { '200': ok },
      },
    },

    // ════════════════════════════════════════════════════════════════
    // REVIEWS
    // ════════════════════════════════════════════════════════════════
    '/reviews': {
      get: {
        tags: ['Reviews'],
        summary: 'List reviews',
        parameters: [
          { name: 'rating', in: 'query', schema: { type: 'integer', minimum: 1, maximum: 5 } },
          ...pagingParams,
        ],
        responses: { '200': ok },
      },
    },
    '/reviews/stats': {
      get: { tags: ['Reviews'], summary: 'Review statistics', responses: { '200': ok } },
    },
    '/reviews/{id}': {
      get: { tags: ['Reviews'], summary: 'Get review', parameters: [idPath()], responses: { '200': ok, '404': err404 } },
    },
    '/reviews/{id}/reply': {
      patch: {
        tags: ['Reviews'],
        summary: 'Reply to review',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/ReviewReply'),
        responses: { '200': ok },
      },
    },
    '/reviews/{id}/remind': {
      post: { tags: ['Reviews'], summary: 'Send review reminder', parameters: [idPath()], responses: { '200': ok } },
    },

    // ════════════════════════════════════════════════════════════════
    // COMPLAINTS
    // ════════════════════════════════════════════════════════════════
    '/complaints': {
      get: {
        tags: ['Complaints'],
        summary: 'List complaints',
        parameters: [
          { name: 'status',   in: 'query', schema: { type: 'string' } },
          { name: 'severity', in: 'query', schema: { type: 'string' } },
          { name: 'category', in: 'query', schema: { type: 'string' } },
          ...pagingParams,
        ],
        responses: { '200': ok },
      },
      post: {
        tags: ['Complaints'],
        summary: 'Create complaint',
        requestBody: jsonBody('#/components/schemas/ComplaintCreate'),
        responses: { '201': ok, '400': err4 },
      },
    },
    '/complaints/{id}': {
      get: {
        tags: ['Complaints'],
        summary: 'Get complaint',
        parameters: [idPath()],
        responses: { '200': ok, '404': err404 },
      },
      patch: {
        tags: ['Complaints'],
        summary: 'Update complaint',
        parameters: [idPath()],
        requestBody: jsonBody('#/components/schemas/ComplaintUpdate'),
        responses: { '200': ok },
      },
      delete: {
        tags: ['Complaints'],
        summary: 'Delete complaint',
        parameters: [idPath()],
        responses: { '200': ok },
      },
    },

    // ════════════════════════════════════════════════════════════════
    // ANALYTICS
    // ════════════════════════════════════════════════════════════════
    '/analytics/summary': {
      get: { tags: ['Analytics'], summary: 'Quick summary stats', responses: { '200': ok } },
    },
    '/analytics/dashboard': {
      get: { tags: ['Analytics'], summary: 'Full dashboard analytics', responses: { '200': ok } },
    },
    '/analytics/sources': {
      get: { tags: ['Analytics'], summary: 'Reservation source breakdown', responses: { '200': ok } },
    },
    '/analytics/report': {
      get: {
        tags: ['Analytics'],
        summary: 'Detailed report (Manager+)',
        parameters: [
          { name: 'startDate', in: 'query', schema: { type: 'string', format: 'date' } },
          { name: 'endDate',   in: 'query', schema: { type: 'string', format: 'date' } },
        ],
        responses: { '200': ok },
      },
    },

    // ════════════════════════════════════════════════════════════════
    // NOTIFICATIONS
    // ════════════════════════════════════════════════════════════════
    '/notifications/company': {
      get: { tags: ['Notifications'], summary: 'Company notifications', responses: { '200': ok } },
    },
    '/notifications/unread-count': {
      get: { tags: ['Notifications'], summary: 'Unread count', responses: { '200': ok } },
    },
    '/notifications/company/{id}/read': {
      post: { tags: ['Notifications'], summary: 'Mark notification as read', parameters: [idPath()], responses: { '200': ok } },
    },
    '/notifications/company/read-all': {
      post: { tags: ['Notifications'], summary: 'Mark all notifications as read', responses: { '200': ok } },
    },
    '/notifications/company/preferences': {
      get:   { tags: ['Notifications'], summary: 'Get notification preferences',    responses: { '200': ok } },
      patch: { tags: ['Notifications'], summary: 'Update notification preferences', responses: { '200': ok } },
    },
    '/notifications/history': {
      get: { tags: ['Notifications'], summary: 'Notification history', responses: { '200': ok } },
    },

    // ════════════════════════════════════════════════════════════════
    // COMPANIES
    // ════════════════════════════════════════════════════════════════
    '/companies/me': {
      get:   { tags: ['Companies'], summary: 'Current company profile',   responses: { '200': ok } },
      patch: { tags: ['Companies'], summary: 'Update company profile (Owner)', responses: { '200': ok } },
    },
    '/companies/me/brand': {
      get:   { tags: ['Companies'], summary: 'Brand settings',        responses: { '200': ok } },
      patch: { tags: ['Companies'], summary: 'Update brand settings (Owner)', responses: { '200': ok } },
    },
    '/companies/me/brand/logo': {
      post: { tags: ['Companies'], summary: 'Upload brand logo', requestBody: { required: true, content: { 'multipart/form-data': { schema: { type: 'object', properties: { file: { type: 'string', format: 'binary' } } } } } }, responses: { '200': ok } },
    },
    '/companies/me/brand/hero': {
      post: { tags: ['Companies'], summary: 'Upload brand hero image', requestBody: { required: true, content: { 'multipart/form-data': { schema: { type: 'object', properties: { file: { type: 'string', format: 'binary' } } } } } }, responses: { '200': ok } },
    },
    '/companies/me/brand/subdomain/check': {
      post: { tags: ['Companies'], summary: 'Check subdomain availability', responses: { '200': ok } },
    },
    '/companies/me/brand/custom-domain': {
      post:   { tags: ['Companies'], summary: 'Set custom domain',    responses: { '200': ok } },
      delete: { tags: ['Companies'], summary: 'Remove custom domain', responses: { '200': ok } },
    },
    '/companies/me/brand/custom-domain/status': {
      get: { tags: ['Companies'], summary: 'Custom domain DNS status', responses: { '200': ok } },
    },
    '/companies/me/contract-settings': {
      get:   { tags: ['Companies'], summary: 'Contract settings',        responses: { '200': ok } },
      patch: { tags: ['Companies'], summary: 'Update contract settings', responses: { '200': ok } },
    },
    '/companies/me/insurance-policies': {
      get:  { tags: ['Companies'], summary: 'List insurance policies',  responses: { '200': ok } },
      post: { tags: ['Companies'], summary: 'Create insurance policy',  responses: { '201': ok } },
    },
    '/companies/me/insurance-policies/{id}': {
      patch:  { tags: ['Companies'], summary: 'Update insurance policy', parameters: [idPath()], responses: { '200': ok } },
      delete: { tags: ['Companies'], summary: 'Delete insurance policy', parameters: [idPath()], responses: { '200': ok } },
    },
    '/companies/me/pricing-rules': {
      get:  { tags: ['Companies'], summary: 'List pricing rules',  responses: { '200': ok } },
      post: { tags: ['Companies'], summary: 'Create pricing rule', responses: { '201': ok } },
    },
    '/companies/me/pricing-rules/{id}': {
      patch: { tags: ['Companies'], summary: 'Update pricing rule', parameters: [idPath()], responses: { '200': ok } },
    },

    // ════════════════════════════════════════════════════════════════
    // TEAM
    // ════════════════════════════════════════════════════════════════
    '/team': {
      get:  { tags: ['Team'], summary: 'List team members', responses: { '200': ok } },
    },
    '/team/stats': {
      get:  { tags: ['Team'], summary: 'Team statistics', responses: { '200': ok } },
    },
    '/team/invite': {
      post: { tags: ['Team'], summary: 'Invite member (Owner)', responses: { '201': ok } },
    },
    '/team/{id}/role': {
      patch: { tags: ['Team'], summary: 'Update member role (Owner)', parameters: [idPath()], responses: { '200': ok } },
    },
    '/team/{id}/deactivate': {
      post: { tags: ['Team'], summary: 'Deactivate member (Owner)', parameters: [idPath()], responses: { '200': ok } },
    },
    '/team/{id}/reactivate': {
      post: { tags: ['Team'], summary: 'Reactivate member (Owner)', parameters: [idPath()], responses: { '200': ok } },
    },
    '/team/{id}': {
      delete: { tags: ['Team'], summary: 'Remove member (Owner)', parameters: [idPath()], responses: { '200': ok } },
    },

    // ════════════════════════════════════════════════════════════════
    // SUBSCRIPTIONS
    // ════════════════════════════════════════════════════════════════
    '/subscriptions/plans': {
      get: { tags: ['Subscriptions'], summary: 'List available plans', security: [], responses: { '200': ok } },
    },
    '/subscriptions/features': {
      get: { tags: ['Subscriptions'], summary: 'Plan feature matrix', security: [], responses: { '200': ok } },
    },
    '/subscriptions/me': {
      get: { tags: ['Subscriptions'], summary: 'Current subscription', responses: { '200': ok } },
    },
    '/subscriptions/invoices': {
      get: { tags: ['Subscriptions'], summary: 'Billing invoices', responses: { '200': ok } },
    },
    '/subscriptions/events': {
      get: { tags: ['Subscriptions'], summary: 'Subscription events', responses: { '200': ok } },
    },
    '/subscriptions/entitlement': {
      get: { tags: ['Subscriptions'], summary: 'Feature entitlements', responses: { '200': ok } },
    },
    '/subscriptions/trial': {
      post: { tags: ['Subscriptions'], summary: 'Start trial (Owner)', responses: { '200': ok } },
    },
    '/subscriptions/checkout': {
      post: { tags: ['Subscriptions'], summary: 'Checkout new subscription (Owner)', responses: { '200': ok } },
    },
    '/subscriptions/change-plan': {
      post: { tags: ['Subscriptions'], summary: 'Change plan (Owner)', responses: { '200': ok } },
    },
    '/subscriptions/cancel': {
      post: { tags: ['Subscriptions'], summary: 'Cancel subscription (Owner)', responses: { '200': ok } },
    },
    '/subscriptions/reactivate': {
      post: { tags: ['Subscriptions'], summary: 'Reactivate subscription (Owner)', responses: { '200': ok } },
    },
    '/subscriptions/resume': {
      post: { tags: ['Subscriptions'], summary: 'Resume subscription (Owner)', responses: { '200': ok } },
    },

    // ════════════════════════════════════════════════════════════════
    // CARPLACE  (public — no auth required)
    // ════════════════════════════════════════════════════════════════
    '/carplace/cities': {
      get: { tags: ['Carplace'], summary: 'Cities with active companies', security: [], responses: { '200': ok } },
    },
    '/carplace/companies': {
      get: { tags: ['Carplace'], summary: 'List companies', security: [], responses: { '200': ok } },
    },
    '/carplace/offers': {
      get: { tags: ['Carplace'], summary: 'Public offers', security: [], responses: { '200': ok } },
    },
    '/carplace/search': {
      get: {
        tags: ['Carplace'],
        summary: 'Search available vehicles',
        security: [],
        parameters: [
          { name: 'city',      in: 'query', schema: { type: 'string' } },
          { name: 'startDate', in: 'query', schema: { type: 'string', format: 'date-time' } },
          { name: 'endDate',   in: 'query', schema: { type: 'string', format: 'date-time' } },
          { name: 'category',  in: 'query', schema: { type: 'string' } },
        ],
        responses: { '200': ok },
      },
    },
    '/carplace/reservations': {
      post: { tags: ['Carplace'], summary: 'Create carplace booking', security: [], responses: { '201': ok } },
    },
    '/carplace/offers/{code}/validate': {
      post: { tags: ['Carplace'], summary: 'Validate promo code', security: [], parameters: [{ name: 'code', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
    },
    '/carplace/review/{token}': {
      get:  { tags: ['Carplace'], summary: 'Get review form by token',    security: [], parameters: [{ name: 'token', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
      post: { tags: ['Carplace'], summary: 'Submit review',               security: [], parameters: [{ name: 'token', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
    },
    '/carplace/{slug}': {
      get: { tags: ['Carplace'], summary: 'Company public page', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
    },
    '/carplace/{slug}/reviews': {
      get: { tags: ['Carplace'], summary: 'Company reviews', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
    },
    '/carplace/{slug}/vehicles': {
      get: { tags: ['Carplace'], summary: 'Company vehicles', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
    },
    '/carplace/{slug}/vehicles/{id}': {
      get: { tags: ['Carplace'], summary: 'Vehicle details', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }, idPath()], responses: { '200': ok } },
    },
    '/carplace/{slug}/offers': {
      get: { tags: ['Carplace'], summary: 'Company offers', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
    },

    // ════════════════════════════════════════════════════════════════
    // SITE  (white-label)
    // ════════════════════════════════════════════════════════════════
    '/site/platform/homepage': {
      get: { tags: ['Site'], summary: 'Platform homepage content',      security: [], responses: { '200': ok } },
    },
    '/site/platform/pricing': {
      get: { tags: ['Site'], summary: 'Platform pricing page content',  security: [], responses: { '200': ok } },
    },
    '/site/{slug}/brand': {
      get: { tags: ['Site'], summary: 'Brand config for white-label site', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
    },
    '/site/{slug}/vehicles': {
      get: { tags: ['Site'], summary: 'Vehicles for white-label site', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
    },
    '/site/{slug}/vehicles/{id}': {
      get: { tags: ['Site'], summary: 'Vehicle detail', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }, idPath()], responses: { '200': ok } },
    },
    '/site/{slug}/offers': {
      get: { tags: ['Site'], summary: 'Offers for white-label site', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
    },
    '/site/{slug}/booking-options': {
      get: { tags: ['Site'], summary: 'Booking options', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
    },
    '/site/{slug}/availability': {
      post: { tags: ['Site'], summary: 'Check availability', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
    },
    '/site/{slug}/book/validate-code': {
      post: { tags: ['Site'], summary: 'Validate promo code', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
    },
    '/site/{slug}/book': {
      post: { tags: ['Site'], summary: 'Create booking', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }], responses: { '201': ok } },
    },
    '/site/{slug}/booking/{id}': {
      get: { tags: ['Site'], summary: 'Get booking status', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }, idPath()], responses: { '200': ok } },
    },
    '/site/{slug}/booking/{id}/pay': {
      post: { tags: ['Site'], summary: 'Pay booking', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }, idPath()], responses: { '200': ok } },
    },
    '/site/{slug}/contact': {
      post: { tags: ['Site'], summary: 'Contact form', security: [], parameters: [{ name: 'slug', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': ok } },
    },

    // ════════════════════════════════════════════════════════════════
    // ADMIN
    // ════════════════════════════════════════════════════════════════
    '/admin/auth/login': {
      post: { tags: ['Admin'], summary: 'Admin login', security: [], responses: { '200': ok } },
    },
    '/admin/auth/forgot-password': {
      post: { tags: ['Admin'], summary: 'Admin forgot password', security: [], responses: { '200': ok } },
    },
    '/admin/auth/reset-password': {
      post: { tags: ['Admin'], summary: 'Admin reset password', security: [], responses: { '200': ok } },
    },
    '/admin/auth/me': {
      get: { tags: ['Admin'], summary: 'Current admin profile', responses: { '200': ok } },
    },
    '/admin/auth/2fa/setup': {
      post: { tags: ['Admin'], summary: 'Setup 2FA', responses: { '200': ok } },
    },
    '/admin/auth/2fa/verify': {
      post: { tags: ['Admin'], summary: 'Verify 2FA code', responses: { '200': ok } },
    },
    '/admin/companies': {
      get: { tags: ['Admin'], summary: 'List all companies', responses: { '200': ok } },
    },
    '/admin/companies/{id}': {
      get:    { tags: ['Admin'], summary: 'Get company',    parameters: [idPath()], responses: { '200': ok } },
      patch:  { tags: ['Admin'], summary: 'Update company', parameters: [idPath()], responses: { '200': ok } },
      delete: { tags: ['Admin'], summary: 'Delete company (Admin)', parameters: [idPath()], responses: { '200': ok } },
    },
    '/admin/companies/{id}/status': {
      patch: { tags: ['Admin'], summary: 'Update company status', parameters: [idPath()], responses: { '200': ok } },
    },
    '/admin/companies/{id}/impersonate': {
      post: { tags: ['Admin'], summary: 'Impersonate company (Admin)', parameters: [idPath()], responses: { '200': ok } },
    },
    '/admin/renters': {
      get: { tags: ['Admin'], summary: 'List renters', responses: { '200': ok } },
    },
    '/admin/renters/{id}/block': {
      post: { tags: ['Admin'], summary: 'Block renter', parameters: [idPath()], responses: { '200': ok } },
    },
    '/admin/renters/{id}/unblock': {
      post: { tags: ['Admin'], summary: 'Unblock renter', parameters: [idPath()], responses: { '200': ok } },
    },
    '/admin/metrics': {
      get: { tags: ['Admin'], summary: 'Platform metrics (Finance)', responses: { '200': ok } },
    },
    '/admin/notifications': {
      get: { tags: ['Admin'], summary: 'Admin notifications', responses: { '200': ok } },
    },
    '/admin/audit-logs': {
      get: { tags: ['Admin'], summary: 'Audit logs (Admin)', responses: { '200': ok } },
    },
    '/admin/admins': {
      get:  { tags: ['Admin'], summary: 'List admins (Super Admin)',   responses: { '200': ok } },
      post: { tags: ['Admin'], summary: 'Create admin (Super Admin)', responses: { '201': ok } },
    },
  },
}
