'use client';

import React, { createContext, useContext, useEffect, useState } from 'react';
import { useSalesChannel } from './sales-channel-context';

/**
 * ============================================
 * UI TRANSLATION (SNIPPETS)
 * ============================================
 * Loads Shopware storefront snippets for the active locale from our own
 * /api/snippets proxy and exposes a `t(key, fallback)` helper.
 *
 *   const { t } = useTranslation();
 *   <button>{t('listing.boxAddProduct', 'Add to cart')}</button>
 *
 * `t` always renders something: the snippet value if present, otherwise the
 * provided fallback, otherwise the key itself. This lets the UI migrate to
 * snippets key-by-key without ever showing a blank label.
 */

const DEFAULT_LOCALE = process.env.NEXT_PUBLIC_LOCALE || 'en-GB';

interface I18nContextType {
  locale: string;
  ready: boolean;
  t: (key: string, fallback?: string) => string;
}

const I18nContext = createContext<I18nContextType | undefined>(undefined);

// Module-level cache so switching back to an already-seen locale is instant
// and we don't refetch on every mount.
const cache: Record<string, Record<string, string>> = {};

export function I18nProvider({ children }: { children: React.ReactNode }) {
  const { currentLocale } = useSalesChannel();
  const locale = currentLocale || DEFAULT_LOCALE;

  const [snippets, setSnippets] = useState<Record<string, string>>(
    () => cache[locale] || {}
  );
  const [ready, setReady] = useState<boolean>(() => Boolean(cache[locale]));

  useEffect(() => {
    let cancelled = false;

    if (cache[locale]) {
      setSnippets(cache[locale]);
      setReady(true);
      return;
    }

    setReady(false);
    fetch(`/api/snippets?locale=${encodeURIComponent(locale)}`)
      .then((r) => (r.ok ? r.json() : { snippets: {} }))
      .then((data: { snippets?: Record<string, string> }) => {
        if (cancelled) return;
        const map = data.snippets || {};
        cache[locale] = map;
        setSnippets(map);
      })
      .catch(() => {
        if (!cancelled) setSnippets({});
      })
      .finally(() => {
        if (!cancelled) setReady(true);
      });

    return () => {
      cancelled = true;
    };
  }, [locale]);

  const t = (key: string, fallback?: string): string =>
    snippets[key] ?? fallback ?? key;

  return (
    <I18nContext.Provider value={{ locale, ready, t }}>
      {children}
    </I18nContext.Provider>
  );
}

export function useTranslation() {
  const ctx = useContext(I18nContext);
  if (!ctx) throw new Error('useTranslation must be used within I18nProvider');
  return ctx;
}
