import {
  classifyLogoShape,
  resolveAdminBrand,
  type BrandAssetLike,
  type BrandSettings,
  type ColorMode,
  type LogoShape,
  type SidebarDensity,
} from '@actuate-media/cms-core/appearance'

import type { AdminBrandCache, AppearanceSnapshot } from '../components/ThemeProvider.js'

/** GET /appearance response shape (admin Appearance tab + boot hydration). */
export interface AppearanceApiResponse {
  appearance: {
    adminColorModeDefault: ColorMode
    adminAccentColor: string
    sidebarDensity: SidebarDensity
    contentFont: string
    reduceMotion: boolean
  }
  brand: BrandSettings
  resolved: { admin: { initials: string } }
  assets: BrandAssetLike[]
  siteTitle: string | null
}

export interface AssetPreview {
  id: string
  url: string
  mimeType: string
  width?: number
  height?: number
  shape: LogoShape
}

export function parseAppearanceAssets(assets: BrandAssetLike[]): Record<string, AssetPreview> {
  const next: Record<string, AssetPreview> = {}
  for (const a of assets ?? []) {
    next[a.id] = {
      id: a.id,
      url: a.publicUrl,
      mimeType: a.mimeType,
      width: a.width ?? undefined,
      height: a.height ?? undefined,
      shape: classifyLogoShape(a.width ?? undefined, a.height ?? undefined),
    }
  }
  return next
}

export function adminBrandToCache(
  brand: BrandSettings,
  assets: Record<string, AssetPreview>,
  siteTitle: string | null,
): AdminBrandCache {
  const map = new Map<string, BrandAssetLike>(
    Object.values(assets).map((a) => [
      a.id,
      { id: a.id, publicUrl: a.url, mimeType: a.mimeType, width: a.width, height: a.height },
    ]),
  )
  const resolved = resolveAdminBrand(brand, map, siteTitle)
  return {
    primaryUrl: resolved.primary?.url ?? null,
    markUrl: resolved.mark?.url ?? null,
    darkUrl: resolved.dark?.url ?? null,
    initials: resolved.initials,
  }
}

/** Map a stored appearance payload into the ThemeProvider snapshot. */
export function appearanceApiToSnapshot(data: AppearanceApiResponse): AppearanceSnapshot {
  const brand: BrandSettings = { ...data.brand, mode: data.brand?.mode ?? 'inheritPublicBrand' }
  const assets = parseAppearanceAssets(data.assets)
  return {
    theme: data.appearance.adminColorModeDefault,
    accent: data.appearance.adminAccentColor,
    density: data.appearance.sidebarDensity,
    font: data.appearance.contentFont,
    reduceMotion: data.appearance.reduceMotion,
    adminBrand: adminBrandToCache(brand, assets, data.siteTitle ?? null),
  }
}
