'use client';

/**
 * EN: I18n Provider wrapper component
 * VI: Component wrapper I18n Provider
 *
 * This component wraps the next-intl provider with our custom context
 */

import { NextIntlClientProvider } from 'next-intl';
import { I18nContext } from './i18n-context';
import { defaultTimeZone } from './i18n-config';
import * as React from 'react';
import enMessages from '../shared/i18n/en.json';
import viMessages from '../shared/i18n/vi.json';

/**
 * EN: Get locale from localStorage or browser (duplicate from i18n-context to avoid circular dependency)
 * VI: Lấy locale từ localStorage hoặc browser (duplicate từ i18n-context để tránh circular dependency)
 * 
 * @param skipBrowserDetection - Skip browser language detection (for hydration)
 */
function getStoredLocale(skipBrowserDetection: boolean = false): 'en' | 'vi' {
  if (typeof window === 'undefined') {
    return 'en'; // defaultLocale
  }

  // EN: Try to get from localStorage preferences / VI: Thử lấy từ localStorage preferences
  try {
    const stored = localStorage.getItem('preferences');
    if (stored) {
      const parsed = JSON.parse(stored);
      if (parsed.language && (parsed.language === 'en' || parsed.language === 'vi')) {
        return parsed.language;
      }
    }
  } catch {
    // EN: Invalid stored data, continue to browser detection / VI: Dữ liệu lưu không hợp lệ, tiếp tục detect browser
  }

  // EN: Skip browser detection during hydration to prevent mismatch
  // VI: Bỏ qua browser detection trong hydration để tránh mismatch
  if (skipBrowserDetection) {
    return 'en'; // defaultLocale
  }

  // EN: Detect from browser language / VI: Phát hiện từ ngôn ngữ browser
  if (typeof navigator !== 'undefined') {
    const browserLang = navigator.language || navigator.languages?.[0] || '';
    const langCode = browserLang.split('-')[0].toLowerCase();
    if (langCode === 'vi') {
      return 'vi';
    }
  }

  return 'en'; // defaultLocale
}

/**
 * EN: Main I18n Provider component
 * VI: Component I18n Provider chính
 */
export function I18nProvider({ children }: { children: React.ReactNode }) {
  // EN: Track if component has mounted (hydrated) to prevent hydration mismatch
  // VI: Theo dõi nếu component đã mount (hydrated) để tránh hydration mismatch
  const [mounted, setMounted] = React.useState(false);

  // EN: Initialize with default locale to prevent hydration mismatch
  // VI: Khởi tạo với locale mặc định để tránh hydration mismatch
  // Server always renders with defaultLocale, so client must start with same value
  const [locale, setLocaleState] = React.useState<'en' | 'vi'>('en');

  /**
   * EN: Set locale and persist to localStorage
   * VI: Đặt locale và lưu vào localStorage
   */
  const setLocale = React.useCallback((newLocale: 'en' | 'vi') => {
    if (newLocale !== 'en' && newLocale !== 'vi') {
      console.warn(`Invalid locale: ${newLocale}`);
      return;
    }

    setLocaleState(newLocale);

    // EN: Update localStorage preferences / VI: Cập nhật localStorage preferences
    if (typeof window !== 'undefined') {
      try {
        const stored = localStorage.getItem('preferences');
        const preferences = stored ? JSON.parse(stored) : {};
        preferences.language = newLocale;
        localStorage.setItem('preferences', JSON.stringify(preferences));
      } catch (error) {
        console.error('Failed to save locale preference:', error);
      }

      // EN: Update HTML lang attribute / VI: Cập nhật thuộc tính lang của HTML
      document.documentElement.lang = newLocale;
    }
  }, []);

  /**
   * EN: Get current locale
   * VI: Lấy locale hiện tại
   */
  const getLocale = React.useCallback(() => {
    return locale;
  }, [locale]);

  // EN: Mark as mounted AFTER hydration (no auto-detection, keep default 'en')
  // VI: Đánh dấu đã mount SAU khi hydration (không tự động phát hiện, giữ mặc định 'en')
  React.useEffect(() => {
    setMounted(true);
    // EN: Check ONLY localStorage for explicit user choice (no browser detection)
    // VI: Chỉ kiểm tra localStorage cho lựa chọn rõ ràng của người dùng (không phát hiện browser)
    try {
      const stored = localStorage.getItem('preferences');
      if (stored) {
        const parsed = JSON.parse(stored);
        if (parsed.language && (parsed.language === 'en' || parsed.language === 'vi')) {
          setLocaleState(parsed.language);
        }
      }
    } catch {
      // EN: Keep default 'en' if localStorage read fails
      // VI: Giữ mặc định 'en' nếu đọc localStorage thất bại
    }
  }, []); // Run once on mount

  // EN: Initialize HTML lang attribute on mount / VI: Khởi tạo thuộc tính lang của HTML khi mount
  React.useEffect(() => {
    if (typeof document !== 'undefined' && mounted) {
      document.documentElement.lang = locale;
    }
  }, [locale, mounted]);

  // EN: Get messages based on locale / VI: Lấy messages dựa trên locale
  // EN: Logic to be applied: ensure we use 'en' until mounted to match server
  const activeLocale = mounted ? locale : 'en';

  const messages = React.useMemo(() => {
    return activeLocale === 'vi' ? viMessages : enMessages;
  }, [activeLocale]);

  const customContextValue = React.useMemo(
    () => ({
      locale: activeLocale,
      setLocale,
      getLocale,
    }),
    [activeLocale, setLocale, getLocale]
  );

  // EN: AGGRESSIVE HYDRATION FIX: Don't render translated content until after mount
  // VI: FIX HYDRATION MẠNH: Không render nội dung đã dịch cho đến sau khi mount
  // This prevents ANY hydration mismatch by ensuring both server and client
  // render the same null/skeleton content initially, then client renders
  // the full content with translations after hydration is complete.
  if (!mounted) {
    return (
      <I18nContext.Provider value={customContextValue}>
        <NextIntlClientProvider
          locale="en"
          messages={enMessages}
          timeZone={defaultTimeZone}
        >
          {/* 
            EN: Render children with default English during SSR/hydration
            VI: Render children với English mặc định trong SSR/hydration
            This ensures server and client match during hydration.
            After mount, we'll re-render with the user's locale preference.
          */}
          {children}
        </NextIntlClientProvider>
      </I18nContext.Provider>
    );
  }

  return (
    <I18nContext.Provider value={customContextValue}>
      <NextIntlClientProvider
        key={activeLocale}
        locale={activeLocale}
        messages={messages}
        timeZone={defaultTimeZone}
      >
        {children}
      </NextIntlClientProvider>
    </I18nContext.Provider>
  );
}
