import { sql } from 'drizzle-orm'
import type { Querier } from '@platform-modules/db'
import type { InventorySchema } from './schema.js'

export class InventoryMigrateError extends Error {
  override readonly name = 'InventoryMigrateError'
  readonly code = 'INVENTORY_MIGRATE' as const

  constructor(readonly detail: string) {
    super(`inventory migrate: ${detail}`)
  }
}

export function isInventoryMigrateError(e: unknown): e is InventoryMigrateError {
  return (
    typeof e === 'object' &&
    e !== null &&
    (e as { name?: unknown }).name === 'InventoryMigrateError' &&
    (e as { code?: unknown }).code === 'INVENTORY_MIGRATE'
  )
}

const MIGRATION_STATEMENTS = [
  sql`
    CREATE TABLE IF NOT EXISTS inventory_item (
      sku_id uuid PRIMARY KEY,
      vendor_id text,
      quantity_total integer,
      quantity_sold integer NOT NULL DEFAULT 0,
      created_at timestamptz NOT NULL DEFAULT NOW(),
      updated_at timestamptz NOT NULL DEFAULT NOW()
    )
  `,
  sql`
    CREATE TABLE IF NOT EXISTS stock_reservation (
      id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
      sku_id uuid NOT NULL,
      qty integer NOT NULL,
      holder_ref text NOT NULL,
      expires_at timestamptz NOT NULL,
      consumed_at timestamptz,
      released_at timestamptz,
      created_at timestamptz NOT NULL DEFAULT NOW()
    )
  `,
  sql`
    CREATE UNIQUE INDEX IF NOT EXISTS uq_active_holder
    ON stock_reservation (sku_id, holder_ref)
    WHERE consumed_at IS NULL AND released_at IS NULL
  `,
  sql`
    CREATE INDEX IF NOT EXISTS ix_active_sku
    ON stock_reservation (sku_id)
    WHERE consumed_at IS NULL AND released_at IS NULL
  `,
]

export async function pushSchema(db: Querier<InventorySchema>): Promise<void> {
  try {
    for (const statement of MIGRATION_STATEMENTS) {
      await db.execute(statement)
    }
  } catch (e) {
    throw new InventoryMigrateError(e instanceof Error ? e.message : String(e))
  }
}
