'use client';

import { useState, useEffect, useMemo } from 'react';
import { usePathname } from 'next/navigation';
import { useTranslations } from 'next-intl';
import { toast } from 'react-hot-toast';
import { ChevronDown, Globe } from 'lucide-react';
import { Language } from '@/types/language';
import { useLocaleAlternatesStore } from '@/store/localeAlternatesStore';

interface LanguageSwitcherProps {
  languages?: Language[];
  currentLocale?: string;
}

const FALLBACK_LANGUAGES: Language[] = [
  { id: '1', code: 'en', name: 'English', name_native: 'English', is_rtl: 0, is_default: 1, is_active: 1 },
  { id: '2', code: 'ur', name: 'Urdu', name_native: 'اردو', is_rtl: 1, is_default: 0, is_active: 1 },
];

export default function LanguageSwitcher({ 
  languages = [], 
  currentLocale = 'en' 
}: LanguageSwitcherProps) {
  const pathname = usePathname();
  const [isOpen, setIsOpen] = useState<boolean>(false);
  const pageAlternates = useLocaleAlternatesStore((s) => s.alternates);
  const pageDefaultLocale = useLocaleAlternatesStore((s) => s.defaultLocale);
  const t = useTranslations('LanguageSwitcher');

  const availableLanguages: Language[] = useMemo(() => {
    return languages.length > 0 ? languages : FALLBACK_LANGUAGES;
  }, [languages]);

  const currentLang: Language | undefined = useMemo(() => {
    return availableLanguages.find(
      (lang: Language) => lang.code === currentLocale
    ) || availableLanguages[0];
  }, [availableLanguages, currentLocale]);

  const switchLanguage = (langCode: string): void => {
    setIsOpen(false);

    // `effectiveLocale` is the locale of the page actually being navigated
    // to — usually `langCode`, but the fallback path below can land on a
    // different (default) locale's content instead. The cookie set at the
    // end must match whichever one that ends up being: setting it to the
    // requested `langCode` even when we fall back elsewhere would make
    // next-intl's cookie-based redirect bounce the very next unprefixed
    // visit straight back to the unavailable locale.
    let effectiveLocale = langCode;
    let targetPath: string | null = null;

    // A page can register the correct per-locale URL for itself (see
    // localeAlternatesStore.ts) when the current path isn't locale-agnostic
    // — e.g. a product detail page, whose slug differs per language.
    // Naively swapping the locale prefix and reusing the current slug would
    // 404 there, since product_translations.slug is only unique per language.
    if (pageAlternates) {
      if (pageAlternates[langCode]) {
        targetPath = pageAlternates[langCode];
      } else if (pageDefaultLocale && pageAlternates[pageDefaultLocale]) {
        // This exact content was never translated into the target language —
        // land on the default-locale version instead of a dead 404.
        effectiveLocale = pageDefaultLocale;
        targetPath = pageAlternates[pageDefaultLocale];
        const targetLang = availableLanguages.find((lang) => lang.code === langCode);
        toast.error(t('notAvailable', { language: targetLang?.name_native ?? langCode }));
      }
    }

    if (!targetPath) {
      // With localePrefix: 'as-needed', the default locale has no URL prefix
      // (e.g. "/products"), while every other locale does (e.g. "/ur/products").
      // So the current pathname may or may not start with a locale segment —
      // only strip it if it actually is one — and the target path only gets a
      // prefix if the language being switched to isn't the default one.
      const segments = pathname.split('/').filter(Boolean);
      const localeCodes = availableLanguages.map((lang) => lang.code);
      const hasLocaleSegment = segments.length > 0 && localeCodes.includes(segments[0]);
      const pathSegments = hasLocaleSegment ? segments.slice(1) : segments;
      const rest = pathSegments.join('/');

      const targetLang = availableLanguages.find((lang) => lang.code === langCode);
      const isDefault = targetLang?.is_default === 1 || targetLang?.is_default === true;

      targetPath = (isDefault ? `/${rest}` : `/${langCode}${rest ? `/${rest}` : ''}`) || '/';
    }

    // next-intl's middleware does cookie-based locale detection by default:
    // visiting "/ur/..." sets a NEXT_LOCALE=ur cookie, and any later visit to
    // an unprefixed URL (e.g. switching back to the default locale) gets
    // redirected back to "/ur/..." based on that stale cookie unless we sync
    // it here to match the explicit choice being made right now. Safe: this
    // only runs inside the onClick handler below, never during render.
    // eslint-disable-next-line react-hooks/immutability
    document.cookie = `NEXT_LOCALE=${effectiveLocale}; path=/; max-age=${60 * 60 * 24 * 365}`;

    // Hard navigation on purpose, NOT router.push(). In production, <Link>s in
    // the header/footer (plain next/link with unprefixed hrefs like "/products")
    // are prefetched while the *old* NEXT_LOCALE cookie is still set, so the
    // middleware answers those prefetches with a redirect to the old locale
    // ("/ur/products") — and the client Router Cache keeps that redirect. After
    // the switch, router.push("/products") reuses the cached redirect and lands
    // back on the old locale until a manual reload. `next dev` doesn't prefetch,
    // which is why this only ever showed up on the live server. A full page load
    // bypasses the Router Cache; language switching is rare enough that the
    // reload cost is fine.
    window.location.assign(targetPath);
  };

  // ─── Handle RTL ──────────────────────────────────────────────────────────
  useEffect(() => {
    const isRTL: boolean = currentLang?.is_rtl === 1 || currentLang?.is_rtl === true;
    
    if (isRTL) {
      document.documentElement.dir = 'rtl';
      document.body.classList.add('rtl');
    } else {
      document.documentElement.dir = 'ltr';
      document.body.classList.remove('rtl');
    }
  }, [currentLang]);

  // ─── Close dropdown on outside click ──────────────────────────────────
  useEffect(() => {
    const handleClickOutside = (e: MouseEvent): void => {
      const target = e.target as HTMLElement;
      if (!target.closest('.language-switcher')) {
        setIsOpen(false);
      }
    };
    
    document.addEventListener('click', handleClickOutside);
    return () => document.removeEventListener('click', handleClickOutside);
  }, []);

  return (
    <div className="language-switcher relative">
      <button
        onClick={() => setIsOpen(!isOpen)}
        className="flex items-center gap-1.5 px-3 py-1.5 rounded-full hover:bg-gray-100 transition-colors duration-300 text-sm font-medium"
        aria-expanded={isOpen}
        aria-label="Switch language"
      >
        <Globe size={16} className="text-gray-custom" />
        <span className="uppercase">{currentLocale}</span>
        <ChevronDown 
          size={14} 
          className={`transition-transform duration-300 ${isOpen ? 'rotate-180' : ''}`}
        />
      </button>

      {isOpen && (
        <div className="absolute top-full right-0 mt-2 bg-white rounded-lg shadow-lg border border-gray-100 py-1 min-w-40 z-50">
          {availableLanguages.map((lang: Language) => (
            <button
              key={lang.id}
              onClick={() => switchLanguage(lang.code)}
              className={`w-full text-left px-4 py-2 hover:bg-gray-50 transition-colors duration-200 text-sm flex items-center justify-between ${
                lang.code === currentLocale ? 'bg-primary/5 text-primary font-semibold' : 'text-gray-700'
              }`}
            >
              <span className="flex items-center gap-2">
                <span className="uppercase text-xs font-bold text-gray-400 w-6">
                  {lang.code}
                </span>
                <span>{lang.name_native}</span>
              </span>
              {lang.code === currentLocale && (
                <span className="text-primary text-xs">✓</span>
              )}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}