import type { Vendor, VendorStatus } from '@platform-modules/commerce-marketplace'
import { MarketplaceWireError } from './errors.js'

const VENDOR_STATUSES: readonly VendorStatus[] = ['pending', 'approved', 'suspended']

function asObject(v: unknown, ctx: string): Record<string, unknown> {
  if (typeof v !== 'object' || v === null) {
    throw new MarketplaceWireError(`${ctx}: expected an object, got ${v === null ? 'null' : typeof v}`)
  }
  return v as Record<string, unknown>
}

function asString(v: unknown, ctx: string): string {
  if (typeof v !== 'string') throw new MarketplaceWireError(`${ctx}: expected a string, got ${typeof v}`)
  return v
}

function reviveRequiredDate(v: unknown, field: string): Date {
  if (v instanceof Date) return v
  if (typeof v === 'string' || typeof v === 'number') {
    const d = new Date(v)
    if (Number.isNaN(d.getTime())) throw new MarketplaceWireError(`reviveVendor: ${field} is not a valid date: ${String(v)}`)
    return d
  }
  throw new MarketplaceWireError(`reviveVendor: ${field} is required`)
}

function asCommissionBps(v: unknown, ctx: string): number {
  if (typeof v !== 'number' || !Number.isSafeInteger(v) || v < 0 || v > 10000) {
    throw new MarketplaceWireError(`${ctx}: expected a non-negative safe integer in [0, 10000], got ${String(v)}`)
  }
  return v
}

export function reviveVendor(v: unknown): Vendor {
  const o = asObject(v, 'reviveVendor')
  const status = asString(o.status, 'vendor.status')
  if (!(VENDOR_STATUSES as readonly string[]).includes(status)) {
    throw new MarketplaceWireError(`vendor.status: unknown VendorStatus ${JSON.stringify(status)}`)
  }
  return {
    id: asString(o.id, 'id'),
    ownerUserId: asString(o.ownerUserId, 'ownerUserId'),
    name: asString(o.name, 'name'),
    status: status as VendorStatus,
    commissionBps: asCommissionBps(o.commissionBps, 'commissionBps'),
    createdAt: reviveRequiredDate(o.createdAt, 'createdAt'),
    updatedAt: reviveRequiredDate(o.updatedAt, 'updatedAt'),
  }
}

export function reviveOptionalVendor(v: unknown): Vendor | null {
  if (v === null || v === undefined) return null
  return reviveVendor(v)
}
