import { eq } from 'drizzle-orm'
import type { Querier } from '@platform-modules/db'
import type { Actor } from '@platform-modules/commerce-orders'
import { VendorNotFoundError, VendorStateError } from './errors.js'
import { vendor, type MarketplaceDbSchema } from './schema.js'
import { UUID_RE, type Vendor, type VendorStatus } from './types.js'

function toVendor(row: typeof vendor.$inferSelect): Vendor {
  return {
    id: row.id,
    ownerUserId: row.ownerUserId,
    name: row.name,
    status: row.status,
    commissionBps: row.commissionBps,
    createdAt: row.createdAt,
    updatedAt: row.updatedAt,
  }
}

export async function requireVendorForActor(
  q: Querier<MarketplaceDbSchema>,
  actor: Actor,
): Promise<Vendor> {
  if (!actor.userId) throw new VendorNotFoundError()

  const [row] = await q.select().from(vendor).where(eq(vendor.ownerUserId, actor.userId)).limit(1)
  if (!row) throw new VendorNotFoundError()

  return toVendor(row)
}

export async function assertVendorOwnership(
  q: Querier<MarketplaceDbSchema>,
  actor: Actor,
  vendorId: string,
): Promise<void> {
  if (actor.isAdmin) return

  // Malformed id is indistinguishable from a nonexistent one (no oracle): a non-UUID
  // would otherwise reach the uuid column and raise a raw driver 500 leaking SQL.
  if (!UUID_RE.test(vendorId)) throw new VendorNotFoundError({ vendorId })

  const [row] = await q.select().from(vendor).where(eq(vendor.id, vendorId)).limit(1)
  if (!row || row.ownerUserId !== actor.userId) {
    throw new VendorNotFoundError({ vendorId })
  }
}

export async function assertVendorCanSell(
  q: Querier<MarketplaceDbSchema>,
  vendorId: string,
): Promise<void> {
  if (!UUID_RE.test(vendorId)) throw new VendorNotFoundError({ vendorId })

  const [row] = await q.select().from(vendor).where(eq(vendor.id, vendorId)).limit(1)
  if (!row) throw new VendorNotFoundError({ vendorId })

  if (row.status !== 'approved') {
    throw new VendorStateError({
      vendorId,
      from: row.status as VendorStatus,
      to: 'approved',
    })
  }
}
