import * as React from "react";
import {
  SupportedLanguage,
  ChatbotTranslations,
  translations,
  languages,
  DEFAULT_LANGUAGE,
  detectBrowserLanguage,
  t,
  isRTL,
  adjustTextLength,
} from "./i18n-config";

// I18n State Interface
interface I18nState {
  currentLanguage: SupportedLanguage;
  translations: ChatbotTranslations;
  isRTL: boolean;
  isLoading: boolean;
}

// I18n Actions
type I18nAction =
  | { type: "SET_LANGUAGE"; payload: SupportedLanguage }
  | { type: "SET_LOADING"; payload: boolean };

// I18n Context Interface
interface I18nContextType extends I18nState {
  changeLanguage: (language: SupportedLanguage) => void;
  t: (key: keyof ChatbotTranslations) => string;
  supportedLanguages: SupportedLanguage[];
  formatText: (text: string) => {
    isTruncated: boolean;
    displayText: string;
    maxLength: number;
  };
}

// Create Context
const I18nContext = React.createContext<I18nContextType | undefined>(undefined);

// I18n Reducer
function i18nReducer(state: I18nState, action: I18nAction): I18nState {
  switch (action.type) {
    case "SET_LANGUAGE":
      return {
        ...state,
        currentLanguage: action.payload,
        translations: translations[action.payload],
        isRTL: isRTL(action.payload),
        isLoading: false,
      };
    case "SET_LOADING":
      return {
        ...state,
        isLoading: action.payload,
      };
    default:
      return state;
  }
}

// I18n Provider Props
interface I18nProviderProps {
  children: React.ReactNode;
  defaultLanguage?: SupportedLanguage;
  enableAutoDetect?: boolean;
  enablePersistence?: boolean;
}

// Storage Keys
const STORAGE_KEY = "chatbot-language";

// I18n Provider Component
export function I18nProvider({
  children,
  defaultLanguage,
  enableAutoDetect = true,
  enablePersistence = true,
}: I18nProviderProps) {
  // Determine initial language
  const getInitialLanguage = (): SupportedLanguage => {
    // 1. Check localStorage if persistence is enabled
    if (enablePersistence && typeof window !== "undefined") {
      const stored = localStorage.getItem(STORAGE_KEY) as SupportedLanguage;
      if (stored && Object.keys(translations).includes(stored)) {
        return stored;
      }
    }

    // 2. Use provided default language
    if (defaultLanguage) {
      return defaultLanguage;
    }

    // 3. Auto-detect browser language if enabled
    if (enableAutoDetect) {
      return detectBrowserLanguage();
    }

    // 4. Fall back to DEFAULT_LANGUAGE
    return DEFAULT_LANGUAGE;
  };

  const initialLanguage = getInitialLanguage();

  // Initialize state
  const [state, dispatch] = React.useReducer(i18nReducer, {
    currentLanguage: initialLanguage,
    translations: translations[initialLanguage],
    isRTL: isRTL(initialLanguage),
    isLoading: false,
  });

  // Change language function
  const changeLanguage = React.useCallback(
    (language: SupportedLanguage) => {
      if (!Object.keys(translations).includes(language)) {
        console.warn(
          `Language '${language}' is not supported. Falling back to '${DEFAULT_LANGUAGE}'.`
        );
        language = DEFAULT_LANGUAGE;
      }

      dispatch({ type: "SET_LOADING", payload: true });

      // Simulate loading time for language switching
      setTimeout(() => {
        dispatch({ type: "SET_LANGUAGE", payload: language });

        // Persist language preference
        if (enablePersistence && typeof window !== "undefined") {
          try {
            localStorage.setItem(STORAGE_KEY, language);
          } catch (error) {
            console.warn("Failed to save language preference:", error);
          }
        }
      }, 100);
    },
    [enablePersistence]
  );

  // Translation function
  const translate = React.useCallback(
    (key: keyof ChatbotTranslations): string => {
      return t(key, state.currentLanguage);
    },
    [state.currentLanguage]
  );

  // Text formatting function
  const formatText = React.useCallback(
    (text: string) => {
      return adjustTextLength(text, state.currentLanguage);
    },
    [state.currentLanguage]
  );

  // Apply RTL direction to document
  React.useEffect(() => {
    if (typeof document !== "undefined") {
      const chatbotElements = document.querySelectorAll("[data-chatbot]");
      chatbotElements.forEach((element) => {
        (element as HTMLElement).dir = state.isRTL ? "rtl" : "ltr";
      });
    }
  }, [state.isRTL]);

  // Context value
  const contextValue: I18nContextType = {
    ...state,
    changeLanguage,
    t: translate,
    supportedLanguages: Object.keys(translations) as SupportedLanguage[],
    formatText,
  };

  return (
    <I18nContext.Provider value={contextValue}>{children}</I18nContext.Provider>
  );
}

// Custom hook to use I18n context
export function useI18n(): I18nContextType {
  const context = React.useContext(I18nContext);

  // If no provider is available, return default values
  if (context === undefined) {
    console.warn(
      "useI18n is being used outside of I18nProvider. Using default values."
    );

    const defaultContext: I18nContextType = {
      currentLanguage: DEFAULT_LANGUAGE,
      translations: translations[DEFAULT_LANGUAGE],
      isRTL: false,
      isLoading: false,
      changeLanguage: () => {},
      t: (key: keyof ChatbotTranslations) =>
        translations[DEFAULT_LANGUAGE][key] || key,
      supportedLanguages: Object.keys(translations) as SupportedLanguage[],
      formatText: (text: string) => ({
        isTruncated: false,
        displayText: text,
        maxLength: text.length,
      }),
    };

    return defaultContext;
  }

  return context;
}

// Language selector component
interface LanguageSelectorProps {
  className?: string;
  showFlags?: boolean;
  showNativeNames?: boolean;
  onLanguageChange?: (language: SupportedLanguage) => void;
}

export function LanguageSelector({
  className = "",
  showFlags = true,
  showNativeNames = true,
  onLanguageChange,
}: LanguageSelectorProps) {
  const { currentLanguage, changeLanguage, supportedLanguages, isRTL } =
    useI18n();

  const handleLanguageChange = (language: SupportedLanguage) => {
    changeLanguage(language);
    onLanguageChange?.(language);
  };

  return (
    <div
      className={`language-selector ${className}`}
      dir={isRTL ? "rtl" : "ltr"}
    >
      <select
        value={currentLanguage}
        onChange={(e) =>
          handleLanguageChange(e.target.value as SupportedLanguage)
        }
        className="
          bg-[var(--chatbot-surface)] 
          text-[var(--chatbot-text-primary)]
          border border-[var(--chatbot-border)]
          rounded-[var(--chatbot-radius-md)]
          px-[var(--chatbot-spacing-sm)]
          py-[var(--chatbot-spacing-xs)]
          text-[var(--chatbot-font-size-sm)]
          focus:border-[var(--chatbot-primary)]
          focus:ring-2 
          focus:ring-[var(--chatbot-primary)] 
          focus:ring-opacity-50
          transition-all 
          duration-200
        "
        aria-label="Select language"
      >
        {supportedLanguages.map((lang) => (
          <option key={lang} value={lang}>
            {showFlags && languages[lang]?.flag && `${languages[lang].flag} `}
            {showNativeNames
              ? languages[lang]?.nativeName
              : languages[lang]?.name}
          </option>
        ))}
      </select>
    </div>
  );
}

// Utility component for RTL-aware text rendering
interface RTLTextProps {
  children: React.ReactNode;
  className?: string;
  tag?: keyof JSX.IntrinsicElements;
}

export function RTLText({
  children,
  className = "",
  tag: Tag = "span",
}: RTLTextProps) {
  const { isRTL } = useI18n();

  return (
    <Tag
      className={`${className} ${isRTL ? "text-right" : "text-left"}`}
      dir={isRTL ? "rtl" : "ltr"}
    >
      {children}
    </Tag>
  );
}
