'use client'

import { useCallback, useSyncExternalStore } from 'react'
import { resolveLanguagePrefs, type LanguagePrefs } from '@/lib/domain/languages'

/**
 * Browser-side copy of the user's chat-language choice (Task 71 follow-up).
 *
 * Nash: "right now we do not have any API integration, so we should show what
 * happens if API would have worked. If the user goes to add additional
 * language, let that additional language appear… Do not look for API
 * integrations."
 *
 * The profile API is still called first. When it cannot persist (migration
 * 0011 not applied, backend down), the choice is kept here — per user, per
 * browser — so the UI behaves exactly as it will once the profile stores it:
 * the language appears on top, can be set as default, and survives a reload
 * and a trip change. Once the API succeeds the local copy is dropped, so the
 * profile is the single source of truth again.
 */

const EVENT = 'hha-language-prefs'
const keyFor = (userId: string) => `hha-language-prefs:${userId}`

export function readLocalLanguagePrefs(userId: string): LanguagePrefs | null {
  try {
    const raw = localStorage.getItem(keyFor(userId))
    if (!raw) return null
    const parsed = JSON.parse(raw)
    return resolveLanguagePrefs({ chat_languages: parsed?.languages, primary_language: parsed?.primary })
  } catch {
    return null
  }
}

export function writeLocalLanguagePrefs(userId: string, prefs: LanguagePrefs | null) {
  try {
    if (prefs) localStorage.setItem(keyFor(userId), JSON.stringify(prefs))
    else localStorage.removeItem(keyFor(userId))
  } catch {
    // storage unavailable — the in-memory state still updates
  }
  window.dispatchEvent(new CustomEvent(EVENT, { detail: keyFor(userId) }))
}

/** Subscribes to the local copy; returns null when there is none. */
export function useLocalLanguagePrefs(userId: string): LanguagePrefs | null {
  const key = keyFor(userId)
  const subscribe = useCallback(
    (onChange: () => void) => {
      const onEvent = (e: Event) => {
        if ((e as CustomEvent).detail === key) onChange()
      }
      window.addEventListener(EVENT, onEvent)
      return () => window.removeEventListener(EVENT, onEvent)
    },
    [key],
  )
  const getSnapshot = useCallback(() => {
    try {
      return localStorage.getItem(key) ?? ''
    } catch {
      return ''
    }
  }, [key])
  const raw = useSyncExternalStore(subscribe, getSnapshot, () => '')
  if (!raw) return null
  try {
    const parsed = JSON.parse(raw)
    return resolveLanguagePrefs({ chat_languages: parsed?.languages, primary_language: parsed?.primary })
  } catch {
    return null
  }
}

/**
 * Save through the API; if the server cannot store it yet, keep the choice
 * locally so the interface still reflects it. Returns the prefs to show.
 */
export async function persistLanguagePrefs(
  userId: string,
  next: { languages: string[]; primary: string },
): Promise<{ prefs: LanguagePrefs; persisted: boolean }> {
  const wanted = resolveLanguagePrefs({ chat_languages: next.languages, primary_language: next.primary })
  try {
    const res = await fetch('/api/profile/languages', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(next),
    })
    if (res.ok) {
      const json = await res.json().catch(() => ({}))
      const saved = resolveLanguagePrefs({ chat_languages: json.languages, primary_language: json.primary })
      writeLocalLanguagePrefs(userId, null)
      return { prefs: saved, persisted: true }
    }
  } catch {
    // network — fall through to the local copy
  }
  writeLocalLanguagePrefs(userId, wanted)
  return { prefs: wanted, persisted: false }
}
