'use client'

import { createContext, useContext, useEffect, useMemo, useRef, useState } from 'react'
import { usePathname, useRouter } from 'next/navigation'
import { appPrivacyHref, footerPageHref } from '@/lib/footerContent'
import { MARKETPLACE_LANGUAGE_COOKIE, SHARED_LANGUAGE_COOKIE, isStorefrontLanguage, type StorefrontLanguage } from '@/lib/i18n'
import { SHARED_LANGUAGE_KEY, SHARED_THEME_KEY, readCurrentUserScopedPreference, readScopedPreference, writeScopedPreference } from '@/lib/preferences'

type Theme = 'light' | 'dark'

type Dictionary = {
  storefront: string
  explore: string
  signIn: string
  ownerSignIn: string
  language: string
  theme: string
  light: string
  dark: string
  preferences: string
}

const dictionaries: Record<StorefrontLanguage, Dictionary> = {
  en: {
    storefront: 'Home',
    explore: 'Storefront',
    signIn: 'Sign in',
    ownerSignIn: 'Create Agency Space',
    language: 'Language',
    theme: 'Theme',
    light: 'Light',
    dark: 'Dark',
    preferences: 'Storefront preferences',
  },
  fr: {
    storefront: 'Accueil',
    explore: 'Storefront',
    signIn: 'Connexion',
    ownerSignIn: "Créer un espace d'agence",
    language: 'Langue',
    theme: 'Mode',
    light: 'Clair',
    dark: 'Sombre',
    preferences: 'Préférences storefront',
  },
  ar: {
    storefront: 'الرئيسية',
    explore: 'السوق',
    signIn: 'تسجيل الدخول',
    ownerSignIn: 'إنشاء مساحة الوكالة',
    language: 'اللغة',
    theme: 'الوضع',
    light: 'فاتح',
    dark: 'داكن',
    preferences: 'تفضيلات السوق',
  },
}

const EMPLOYEE_PROFILE_KEY = 'employee_profile'

export const localeOptions: Array<{ value: StorefrontLanguage; label: string; flag: string }> = [
  { value: 'en', label: 'Global (English)', flag: '🇺🇸' },
  { value: 'ar', label: 'North Africa (Arabic)', flag: '🇲🇦' },
  { value: 'fr', label: 'Europe (French)', flag: '🇫🇷' },
]

export function getFooterContent(language: StorefrontLanguage): {
  primary: Array<{ label: string; href?: string }>
  secondary: Array<{ label: string; href?: string }>
  localeLabel: string
  rightsLabel: string
} {
  switch (language) {
    case 'fr':
      return {
        primary: [
          { label: 'À propos de nous', href: footerPageHref['about-us'] },
          { label: "Conditions d'utilisation", href: footerPageHref['terms-of-service'] },
          { label: 'Sécurité', href: footerPageHref.security },
          { label: 'Conformité', href: footerPageHref.compliance },
          { label: 'Politique de confidentialité', href: appPrivacyHref.fr },
          { label: 'Politique relative aux cookies', href: footerPageHref['cookie-policy'] },
        ],
        secondary: [
          { label: 'Newsletter', href: footerPageHref.newsletter },
          { label: 'Contacter les ventes', href: footerPageHref['contact-sales'] },
          { label: 'Conditions générales', href: footerPageHref['general-conditions'] },
        ],
        localeLabel: 'Europe (French)',
        rightsLabel: 'Tous droits réservés.',
      }
    case 'ar':
      return {
        primary: [
          { label: 'من نحن', href: footerPageHref['about-us'] },
          { label: 'شروط الاستخدام', href: footerPageHref['terms-of-service'] },
          { label: 'الأمان', href: footerPageHref.security },
          { label: 'الامتثال', href: footerPageHref.compliance },
          { label: 'سياسة الخصوصية', href: appPrivacyHref.ar },
          { label: 'سياسة ملفات تعريف الارتباط', href: footerPageHref['cookie-policy'] },
        ],
        secondary: [
          { label: 'النشرة الإخبارية', href: footerPageHref.newsletter },
          { label: 'تواصل مع المبيعات', href: footerPageHref['contact-sales'] },
          { label: 'الشروط العامة', href: footerPageHref['general-conditions'] },
        ],
        localeLabel: 'North Africa (Arabic)',
        rightsLabel: 'جميع الحقوق محفوظة.',
      }
    case 'en':
    default:
      return {
        primary: [
          { label: 'About Us', href: footerPageHref['about-us'] },
          { label: 'Terms of Service', href: footerPageHref['terms-of-service'] },
          { label: 'Security', href: footerPageHref.security },
          { label: 'Compliance', href: footerPageHref.compliance },
          { label: 'Privacy Policy', href: appPrivacyHref.en },
          { label: 'Cookie Policy', href: footerPageHref['cookie-policy'] },
        ],
        secondary: [
          { label: 'Newsletter', href: footerPageHref.newsletter },
          { label: 'Contact Sales', href: footerPageHref['contact-sales'] },
          { label: 'General Conditions', href: footerPageHref['general-conditions'] },
        ],
        localeLabel: 'Global (English)',
        rightsLabel: 'All rights reserved.',
      }
  }
}

export function hasCachedEmployeeProfile(): boolean {
  if (typeof window === 'undefined') return false

  try {
    return Boolean(window.localStorage.getItem(EMPLOYEE_PROFILE_KEY))
  } catch {
    return false
  }
}

export function clearCachedEmployeeProfile() {
  if (typeof window === 'undefined') return

  try {
    window.localStorage.removeItem(EMPLOYEE_PROFILE_KEY)
  } catch {}
}

function detectBrowserLanguage(): string | null {
  if (typeof navigator === 'undefined') return null
  const langs = Array.from(navigator.languages ?? [navigator.language])
  for (const lang of langs) {
    const code = lang.split('-')[0].toLowerCase()
    if (code === 'fr' || code === 'ar' || code === 'en') return code
  }
  return null
}

type PreferencesContextValue = {
  language: StorefrontLanguage
  theme: Theme
  dict: Dictionary
  companyName: string | null
  setLanguage: (language: StorefrontLanguage) => void
  setTheme: (theme: Theme) => void
}

const PreferencesContext = createContext<PreferencesContextValue | null>(null)

export function useStorefrontPreferences() {
  const context = useContext(PreferencesContext)
  if (!context) throw new Error('useStorefrontPreferences must be used within StorefrontShell')
  return context
}

export default function StorefrontShell({
  children,
  initialLanguage = 'en',
  initialTheme = 'light',
}: {
  children: React.ReactNode
  initialLanguage?: StorefrontLanguage
  initialTheme?: Theme
}) {
  const router = useRouter()
  const pathname = usePathname()
  const apiUrl = process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:4000/api/v1'
  const [language, setLanguageState] = useState<StorefrontLanguage>(initialLanguage)
  const [theme, setThemeState] = useState<Theme>(initialTheme)
  const [hydrated, setHydrated] = useState(false)
  const previousLanguage = useRef<StorefrontLanguage>(initialLanguage)
  const [companyName, setCompanyName] = useState<string | null>(null)

  function applyLanguage(nextLanguage: StorefrontLanguage) {
    if (nextLanguage === language) return

    if (typeof window !== 'undefined') {
      document.documentElement.lang = nextLanguage
      document.documentElement.dir = nextLanguage === 'ar' ? 'rtl' : 'ltr'
      try {
        sessionStorage.setItem('storefront-language', nextLanguage)
      } catch {}
      writeScopedPreference(SHARED_LANGUAGE_KEY, nextLanguage, ['storefront-language'])
    }

    setLanguageState(nextLanguage)
  }

  function applyTheme(nextTheme: Theme) {
    if (nextTheme === theme) return

    if (typeof window !== 'undefined') {
      document.documentElement.classList.toggle('dark', nextTheme === 'dark')
      document.documentElement.style.colorScheme = nextTheme === 'light' ? 'light' : 'dark'
      document.body.dataset.theme = nextTheme
      writeScopedPreference(SHARED_THEME_KEY, nextTheme, ['storefront-theme'])
    }

    setThemeState(nextTheme)
  }

  async function syncCompanyBrand() {
    if (!hasCachedEmployeeProfile()) {
      setCompanyName(null)
      return
    }

    try {
      const response = await fetch(`${apiUrl}/companies/me/brand`, {
        credentials: 'include',
      })

      if (!response.ok) {
        if (response.status === 401) {
          clearCachedEmployeeProfile()
        }
        setCompanyName(null)
        return
      }

      const json = await response.json()
      const name = json?.data?.displayName ?? json?.displayName ?? null
      setCompanyName(name)
    } catch {
      setCompanyName(null)
    }
  }

  function readSessionLanguage(): StorefrontLanguage | null {
    try {
      const val = sessionStorage.getItem('storefront-language')
      return isStorefrontLanguage(val) ? val : null
    } catch {
      return null
    }
  }

  function syncScopedPreferencesForSession() {
    const sessionLang = readSessionLanguage()
    if (sessionLang) {
      if (sessionLang !== language) setLanguageState(sessionLang)
    } else {
      const scopedLanguage = readCurrentUserScopedPreference(SHARED_LANGUAGE_KEY)
      if (isStorefrontLanguage(scopedLanguage) && scopedLanguage !== language) {
        setLanguageState(scopedLanguage)
      }
    }

    const scopedTheme = readCurrentUserScopedPreference(SHARED_THEME_KEY)
    if ((scopedTheme === 'light' || scopedTheme === 'dark') && scopedTheme !== theme) {
      setThemeState(scopedTheme)
    } else {
      writeScopedPreference(SHARED_THEME_KEY, theme, ['storefront-theme'])
    }
  }

  useEffect(() => {
    const sessionLang = readSessionLanguage()
    if (sessionLang) {
      setLanguageState(sessionLang)
      writeScopedPreference(SHARED_LANGUAGE_KEY, sessionLang, ['storefront-language'])
    } else {
      const storedLanguage = readScopedPreference(SHARED_LANGUAGE_KEY, ['storefront-language'])
      if (isStorefrontLanguage(storedLanguage)) {
        setLanguageState(storedLanguage)
        writeScopedPreference(SHARED_LANGUAGE_KEY, storedLanguage, ['storefront-language'])
      } else {
        const detected = detectBrowserLanguage()
        if (isStorefrontLanguage(detected)) {
          setLanguageState(detected)
          writeScopedPreference(SHARED_LANGUAGE_KEY, detected, ['storefront-language'])
        }
      }
    }

    const storedTheme = readScopedPreference(SHARED_THEME_KEY, ['storefront-theme']) as Theme | null
    if (storedTheme === 'light' || storedTheme === 'dark') {
      setThemeState(storedTheme)
    }

    setHydrated(true)
    void syncCompanyBrand()
  }, [])

  useEffect(() => {
    function handleWindowFocus() {
      syncScopedPreferencesForSession()
      void syncCompanyBrand()
    }

    function handleAuthMessage(event: MessageEvent) {
      if (!event.data || typeof event.data !== 'object') return

      const message = event.data as { type?: string }

      if (message.type === 'rentaldrivego:employee-login' || message.type === 'rentaldrivego:employee-logout') {
        syncScopedPreferencesForSession()
        void syncCompanyBrand()
      }
    }

    window.addEventListener('focus', handleWindowFocus)
    window.addEventListener('message', handleAuthMessage)
    document.addEventListener('visibilitychange', handleWindowFocus)

    return () => {
      window.removeEventListener('focus', handleWindowFocus)
      window.removeEventListener('message', handleAuthMessage)
      document.removeEventListener('visibilitychange', handleWindowFocus)
    }
  }, [language, theme])

  useEffect(() => {
    document.documentElement.lang = language
    document.documentElement.dir = language === 'ar' ? 'rtl' : 'ltr'

    if (!hydrated) return

    try { sessionStorage.setItem('storefront-language', language) } catch {}
    writeScopedPreference(SHARED_LANGUAGE_KEY, language, ['storefront-language'])

    if (previousLanguage.current !== language && pathname !== '/sign-in') {
      router.refresh()
    }
    previousLanguage.current = language
  }, [hydrated, language, pathname, router])

  useEffect(() => {
    document.documentElement.classList.toggle('dark', theme === 'dark')
    document.documentElement.style.colorScheme = theme === 'dark' ? 'dark' : 'light'
    document.body.dataset.theme = theme
    if (hydrated) {
      writeScopedPreference(SHARED_THEME_KEY, theme, ['storefront-theme'])
    }
  }, [theme, hydrated])

  const value = useMemo(
    () => ({ language, theme, dict: dictionaries[language], companyName, setLanguage: applyLanguage, setTheme: applyTheme }),
    [language, theme, companyName],
  )

  return <PreferencesContext.Provider value={value}>{children}</PreferencesContext.Provider>
}
