'use client'

import { createContext, useContext, useEffect, useState, useCallback, useRef } from 'react'
import type { ReactNode } from 'react'
import { SupportedLanguage, loadTranslations, getTranslationValue, Translations } from './load-translations'

type LanguageContextType = {
  language: SupportedLanguage
  setLanguage: (lang: SupportedLanguage) => void
  t: (key: string, params?: Record<string, string | number>) => string
  translations: Translations
}

const LanguageContext = createContext<LanguageContextType | undefined>(undefined)

const RTL_LANGUAGES: SupportedLanguage[] = ['ar', 'fa']

function updateDocumentDirection(lang: SupportedLanguage) {
  document.documentElement.lang = lang
  document.documentElement.dir = RTL_LANGUAGES.includes(lang) ? 'rtl' : 'ltr'
}

export function LanguageProvider({ children, initialLanguage = 'en' }: {
  children: ReactNode
  initialLanguage?: SupportedLanguage
}) {
  const [language, setLanguageState] = useState<SupportedLanguage>(initialLanguage)
  const [translations, setTranslations] = useState<Translations | null>(null)
  const cacheRef = useRef<Map<SupportedLanguage, Translations>>(new Map())

  // Load translations when language changes (with caching)
  useEffect(() => {
    const cached = cacheRef.current.get(language)
    if (cached) {
      setTranslations(cached)
      updateDocumentDirection(language)
      return
    }

    const loadLang = async () => {
      const loaded = await loadTranslations(language)
      cacheRef.current.set(language, loaded)
      setTranslations(loaded)
      updateDocumentDirection(language)
    }
    loadLang()
  }, [language])

  // Load saved language from localStorage on mount
  useEffect(() => {
    const saved = localStorage.getItem('user-language') as SupportedLanguage
    if (saved) {
      setLanguageState(saved)
    } else {
      // Auto-detect from browser language
      const browserLang = navigator.language.split('-')[0] as SupportedLanguage
      const supportedLangs: SupportedLanguage[] = ['en', 'fr', 'es', 'de', 'fa', 'it', 'pt', 'ru', 'zh', 'ja', 'ko', 'ar', 'hi', 'nl', 'pl']

      if (supportedLangs.includes(browserLang)) {
        setLanguageState(browserLang)
        localStorage.setItem('user-language', browserLang)
      }
    }
  }, [])

  const setLanguage = useCallback((lang: SupportedLanguage) => {
    setLanguageState(lang)
    localStorage.setItem('user-language', lang)
    updateDocumentDirection(lang)
  }, [])

  const t = useCallback((key: string, params?: Record<string, string | number>) => {
    if (!translations) return key

    let value: any = getTranslationValue(translations, key)

    // Replace parameters like {count}, {percentage}, etc.
    if (params && typeof value === 'string') {
      Object.entries(params).forEach(([param, paramValue]) => {
        value = value.replace(`{${param}}`, String(paramValue))
      })
    }

    return typeof value === 'string' ? value : key
  }, [translations])

  // During initial load, show children with the initial language as fallback
  // to prevent blank flash
  if (!translations) {
    return (
      <LanguageContext.Provider value={{
        language: initialLanguage,
        setLanguage,
        t: (key: string) => key,
        translations: {} as Translations
      }}>
        {children}
      </LanguageContext.Provider>
    )
  }

  return (
    <LanguageContext.Provider value={{ language, setLanguage, t, translations }}>
      {children}
    </LanguageContext.Provider>
  )
}

export function useLanguage() {
  const context = useContext(LanguageContext)
  if (context === undefined) {
    throw new Error('useLanguage must be used within a LanguageProvider')
  }
  return context
}
