import { useState, useEffect } from "react";
import { getLocalizedPath } from "@/i18n/utils";
import type { Lang } from "@/types/i18n";
import { languages as i18nLanguages, defaultLang } from "@/i18n/ui";
import { Check, ChevronDown } from "lucide-react";
import { type LanguageSwitcherProps } from "@/types";

const availableLanguages = Object.entries(i18nLanguages).map(([code, name]) => ({
  code: code as Lang,
  name,
  icon: code === 'en' ? '🇬🇧' : code === 'zh' ? '🇨🇳' : '🌐'
}));

export default function LanguageSwitcher({ lang: propLang }: LanguageSwitcherProps) {
  const [isOpen, setIsOpen] = useState(false);
  const [currentLang, setCurrentLang] = useState<Lang>(propLang || defaultLang);

  useEffect(() => {
    if (typeof window !== "undefined") {
      const pathLang = window.location.pathname.startsWith("/zh") ? "zh" : "en";
      if (pathLang !== currentLang) {
        setCurrentLang(pathLang);
      }
      return;
    }

    if (typeof document !== "undefined") {
      const htmlLang = document.documentElement.lang as Lang;
      if (htmlLang && (!propLang || htmlLang !== currentLang)) {
        setCurrentLang(htmlLang);
      }
    }
  }, [propLang, currentLang]);

  const [selectedLanguage, setSelectedLanguage] = useState(() => {
    return availableLanguages.find(l => l.code === currentLang) ||
           availableLanguages.find(l => l.code === defaultLang) ||
           availableLanguages[0];
  });

  useEffect(() => {
    const currentLangObject = availableLanguages.find(l => l.code === currentLang);
    if (currentLangObject && currentLangObject.code !== selectedLanguage.code) {
      setSelectedLanguage(currentLangObject);
    }
  }, [currentLang, selectedLanguage.code]);

  const toggleOpen = () => setIsOpen(!isOpen);

  const handleSelectLanguage = (languageOpt: typeof availableLanguages[0]) => {
    setSelectedLanguage(languageOpt);
    setIsOpen(false);
    if (typeof window !== "undefined") {
      const currentPathname = window.location.pathname;
      const basePath = currentPathname.replace(/^\/(en|zh)(?=\/|$)/, "") || "/";
      const targetPath = getLocalizedPath(basePath, languageOpt.code);

      const normalize = (value: string) => value.replace(/\/+$/, "") || "/";
      if (normalize(targetPath) !== normalize(currentPathname)) {
        window.location.assign(targetPath);
      }
    }
  };

  return (
    <div className="relative">
      <button
        onClick={toggleOpen}
        className="flex items-center p-2 rounded-md hover:bg-accent hover:text-accent-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-sm active:scale-95"
        aria-label={`Change language, current language is ${selectedLanguage.name}`}
      >
        <span className="mr-1.5">{selectedLanguage.icon}</span>
        <span className="hidden sm:inline">{selectedLanguage.name}</span>
        <span className="sm:hidden">{selectedLanguage.code.toUpperCase()}</span>
        <ChevronDown size={16} className={`ml-1.5 transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`} />
      </button>
      {isOpen && (
        <div
          className="absolute right-0 mt-2 w-40 origin-top-right rounded-md bg-popover text-popover-foreground shadow-md focus:outline-none z-50 border border-border/20 animate-in fade-in slide-in-from-top-2"
        >
          <div className="p-1" role="menu" aria-orientation="vertical" aria-labelledby="options-menu">
            {availableLanguages.map((lang) => (
              <button
                key={lang.code}
                onClick={() => handleSelectLanguage(lang)}
                className="w-full text-left px-3 py-1.5 text-sm rounded-sm hover:bg-accent hover:text-accent-foreground flex items-center justify-between cursor-pointer focus:bg-accent focus:outline-none"
                role="menuitem"
              >
                <span className="flex items-center">
                  <span className="mr-2">{lang.icon}</span>
                  {lang.name}
                </span>
                {selectedLanguage.code === lang.code && <Check size={16} className="text-primary" />}
              </button>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}
