/* Pure transform from Payload documents to the EXACT `window.EPC` overlay shape
   the front-end consumes. Kept dependency-free so it can be unit-tested in
   isolation (see scripts/assemble.test.cjs). Uploads must be populated (depth>=1)
   so `image`/`heroImage` are objects carrying `.url`. */

type Up = { url?: string } | string | number | null | undefined
const urlOf = (u: Up): string | undefined =>
  u && typeof u === 'object' && typeof u.url === 'string' ? u.url : undefined

export type AssembleInput = {
  markets: any[]
  pricing: any[]
  addons: any[]
  pillars: any[]
  cityScenes: any[]
  product: any
  images: any
}

export function assemble(input: AssembleInput) {
  const { markets = [], pricing = [], addons = [], pillars = [], cityScenes = [], product = {}, images = {} } = input

  const MARKETS: Record<string, any> = {}
  for (const m of markets) {
    MARKETS[m.code] = {
      code: m.code, name: m.name, fullName: m.fullName, flag: m.flag,
      currency: m.currency, hub: m.hub, hubAddress: m.hubAddress,
      partners: m.partners || [], upcomingHubs: m.upcomingHubs || [],
      phone: m.phone, email: m.email,
      fleetStats: m.fleetStats || {},
      ...(urlOf(m.heroImage) ? { heroImg: urlOf(m.heroImage) } : {}),
      ...(m.heroKicker ? { heroKicker: m.heroKicker } : {}),
    }
  }

  const specsObj: Record<string, any> = {}
  for (const s of product.specs || []) {
    specsObj[s.key] = { label: s.label, value: s.value, sub: s.sub, icon: s.icon }
  }
  const EPCO_X1 = {
    name: product.name, tagline: product.tagline, pitch: product.pitch,
    specs: specsObj,
    features: (product.features || []).map((f: any) => ({ tag: f.tag, label: f.label })),
    views: (product.views || []).map((v: any) => ({
      id: v.viewId, label: v.label, en: v.en, file: urlOf(v.image) || v.file,
    })),
    details: (product.details || []).map((d: any) => ({
      id: d.detailId, label: d.label, en: d.en, desc: d.desc, file: urlOf(d.image) || d.file,
    })),
    colorways: (product.colorways || []).map((c: any) => ({
      id: c.colorId, name: c.name, hex: c.hex, file: urlOf(c.image) || c.file,
    })),
  }

  const PRICING: Record<string, any> = {}
  for (const p of pricing) {
    const clean = (t: any) => t && ({ rate: t.rate, per: t.per, popular: !!t.popular, ...(t.save ? { save: t.save } : {}) })
    PRICING[p.market] = { daily: clean(p.daily), weekly: clean(p.weekly), monthly: clean(p.monthly) }
  }

  const ADDONS: Record<string, any[]> = {}
  for (const a of addons) {
    ADDONS[a.market] = (a.items || []).map((it: any) => ({
      id: it.addonId, name: it.name,
      ...(it.price != null ? { price: it.price } : {}),
      ...(it.suggested ? { suggested: true } : {}),
      ...(it.included ? { included: true } : {}),
    }))
  }

  const PILLARS = [...pillars]
    .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
    .map((p) => ({ n: p.n, title: p.title, sub: p.sub, body: p.body, metric: p.metric, metricLabel: p.metricLabel, cite: p.cite }))

  const CITY_SCENES = [...cityScenes]
    .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
    .map((c) => ({ id: c.sceneId, label: c.label, img: urlOf(c.image) || c.fallbackImg }))

  const IMAGES: Record<string, string> = {}
  for (const key of ['hero3pl', 'hero3plMobile', 'rentalHeroAlt', 'partnerForm', 'appBackground']) {
    const u = urlOf(images?.[key])
    if (u) IMAGES[key] = u // omit unset -> front-end keeps its baked placeholder
  }

  return { MARKETS, EPCO_X1, PRICING, ADDONS, PILLARS, CITY_SCENES, IMAGES }
}
