import React, { useMemo, useState, useEffect } from 'react';
import Select, { components, StylesConfig, type SingleValue } from 'react-select';
import { matchSorter } from 'match-sorter';
import { LANGUAGE_MAP, ACCURATE_LANGUAGES } from '../utils/languages';
import { getScriptName, getScriptDescription } from '../utils/scripts';
import { getSupportedLanguages } from '../services/transcriptionApi';

interface LanguageSelectorProps {
  selectedLanguage: string | null;
  selectedScript: string | null;
  onLanguageAndScriptSelect: (language: string | null, script: string | null) => void;
  disabled?: boolean;
}

interface OptionType {
  value: string; // The full code_script combination
  label: string;
  languageName: string;
  scriptName: string;
  languageCode: string;
  scriptCode: string;
}

const parseLanguage = (languageString: string): OptionType | null => {
  const parts = languageString.split('_');

  // Always expect format: "eng_Latn"
  if (parts.length === 2) {
    const [languageCode, scriptCode] = parts;
    const languageName = (LANGUAGE_MAP as Record<string, string>)[languageCode] || languageCode;
    const scriptName = getScriptName(scriptCode);

    return {
      value: languageString,
      label: `${languageName} ${scriptName} (${languageString})`,
      languageName,
      scriptName,
      languageCode,
      scriptCode,
    };
  }

  return null;
};

// Custom Option component to show language, script, and code with tooltip
const Option = (props: any) => {
  const scriptDescription = getScriptDescription(props.data.scriptCode);

  return (
    <components.Option {...props}>
      <div className="flex flex-col" title={scriptDescription || undefined}>
        <div className="font-medium text-sm">{props.data.languageName}</div>
        <div className="text-xs text-gray-400">{props.data.scriptName} ({props.data.value})</div>
      </div>
    </components.Option>
  );
};

// Custom SingleValue component for selected value
const SingleValue = (props: any) => (
  <components.SingleValue {...props}>
    <div className="flex flex-col">
      <div className="font-medium text-sm leading-tight">{props.data.languageName}</div>
      <div className="text-xs text-gray-400 leading-tight">{props.data.scriptName} ({props.data.value})</div>
    </div>
  </components.SingleValue>
);

// Custom styles to match the dark theme
const customStyles: StylesConfig<OptionType> = {
  control: (styles, { isDisabled, isFocused }) => ({
    ...styles,
    backgroundColor: isDisabled ? '#374151' : '#374151', // gray-700
    borderColor: isFocused ? '#3b82f6' : '#4b5563', // blue-500 : gray-600
    borderRadius: '0.375rem',
    minHeight: '40px',
    boxShadow: isFocused ? '0 0 0 1px #3b82f6' : 'none',
    '&:hover': {
      borderColor: isDisabled ? '#4b5563' : '#6b7280', // gray-600 : gray-500
      backgroundColor: isDisabled ? '#374151' : '#4b5563', // gray-700 : gray-600
    },
    cursor: isDisabled ? 'not-allowed' : 'pointer',
  }),
  singleValue: (styles) => ({
    ...styles,
    color: '#f9fafb', // gray-50
  }),
  placeholder: (styles) => ({
    ...styles,
    color: '#9ca3af', // gray-400
  }),
  input: (styles) => ({
    ...styles,
    color: '#f9fafb', // gray-50
  }),
  menu: (styles) => ({
    ...styles,
    backgroundColor: '#374151', // gray-700
    border: '1px solid #4b5563', // gray-600
    borderRadius: '0.5rem',
    boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
    zIndex: 50,
  }),
  menuList: (styles) => ({
    ...styles,
    maxHeight: '200px',
    padding: 0,
  }),
  option: (styles, { isFocused, isSelected }) => ({
    ...styles,
    backgroundColor: isSelected
      ? '#2563eb' // blue-600
      : isFocused
        ? '#4b5563' // gray-600
        : 'transparent',
    color: '#f9fafb', // gray-50
    cursor: 'pointer',
    padding: '8px 12px',
    '&:hover': {
      backgroundColor: isSelected ? '#2563eb' : '#4b5563', // blue-600 : gray-600
    },
  }),
  indicatorSeparator: (styles) => ({
    ...styles,
    backgroundColor: '#4b5563', // gray-600
  }),
  dropdownIndicator: (styles, { isDisabled }) => ({
    ...styles,
    color: isDisabled ? '#6b7280' : '#9ca3af', // gray-500 : gray-400
    '&:hover': {
      color: isDisabled ? '#6b7280' : '#d1d5db', // gray-500 : gray-300
    },
  }),
  clearIndicator: (styles) => ({
    ...styles,
    color: '#9ca3af', // gray-400
    '&:hover': {
      color: '#d1d5db', // gray-300
    },
  }),
  noOptionsMessage: (styles) => ({
    ...styles,
    color: '#9ca3af', // gray-400
  }),
};

const LanguageSelector: React.FC<LanguageSelectorProps> = ({
  selectedLanguage,
  selectedScript,
  onLanguageAndScriptSelect,
  disabled = false
}) => {
  const [supportedLanguages, setSupportedLanguages] = useState<string[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // Fetch supported languages from API
  useEffect(() => {
    const fetchSupportedLanguages = async () => {
      try {
        setIsLoading(true);
        const languages = await getSupportedLanguages();
        setSupportedLanguages(languages);
      } catch (err) {
        console.error('Failed to fetch supported languages:', err);
        setError('Failed to load supported languages');
      } finally {
        setIsLoading(false);
      }
    };

    fetchSupportedLanguages();
  }, []);

  // Convert supported languages to options
  const languageOptions = useMemo(() => {
    const allowAllLanguages = import.meta.env.VITE_ALLOW_ALL_LANGUAGES === 'true';

    return supportedLanguages
      .map(parseLanguage)
      .filter((option): option is OptionType => option !== null)
      .filter((option) => {
        if (allowAllLanguages) {
          return true;
        }
        return ACCURATE_LANGUAGES.includes(option.languageCode);
      })
      .sort((a, b) => a.languageName.localeCompare(b.languageName));
  }, [supportedLanguages]);

  // Find the selected option
  const selectedOption = useMemo(() => {
    if (!selectedLanguage || !selectedScript) return null;
    const combinedValue = `${selectedLanguage}_${selectedScript}`;
    return languageOptions.find(option => option.value === combinedValue) || null;
  }, [selectedLanguage, selectedScript, languageOptions]);

  const handleChange = (newValue: SingleValue<OptionType>) => {
    if (newValue) {
      onLanguageAndScriptSelect(newValue.languageCode, newValue.scriptCode);
    } else {
      onLanguageAndScriptSelect(null, null);
    }
  };

  // Custom filterOption function using match-sorter
  const filterOptions = useMemo(() => {
    return (option: { label: string; value: string; data: OptionType }, inputValue: string) => {
      if (!inputValue.trim()) return true;

      // Use match-sorter to check if this individual option matches
      const matches = matchSorter([option.data], inputValue, {
        keys: [
          'languageName',     // Primary: language name
          'scriptName',       // Secondary: script name
          'languageCode',     // Tertiary: language code
          'scriptCode',       // Quaternary: script code
          'label',            // Fallback: full label
        ],
        threshold: matchSorter.rankings.CONTAINS,
      });

      return matches.length > 0;
    };
  }, []);

  if (error) {
    return (
      <div className="text-red-400 text-sm p-2 bg-red-900/20 rounded">
        {error}
      </div>
    );
  }

  return (
    <Select<OptionType>
      value={selectedOption}
      onChange={handleChange}
      options={languageOptions}
      placeholder={isLoading ? "Loading languages..." : "Select language..."}
      isClearable
      isDisabled={disabled || isLoading}
      isSearchable
      filterOption={(option, inputValue) => filterOptions(option, inputValue)}
      components={{ Option, SingleValue }}
      styles={customStyles}
      menuPortalTarget={document.body}
      menuPosition="fixed"
      noOptionsMessage={({ inputValue }) =>
        `No languages found matching "${inputValue}"`
      }
      // Performance optimizations
      menuIsOpen={undefined} // Let react-select manage this
      blurInputOnSelect={true}
      closeMenuOnSelect={true}
      hideSelectedOptions={false}
    />
  );
};

export default LanguageSelector;
