import React from 'react';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
import { Globe } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { type Language, useLanguage } from '../../../contexts/LanguageContext';

// Re-export the canonical Language type so consumers can import from either location.
export type { Language };

export interface LanguageSelectorProps {
  /** Whether to show text labels alongside the globe icon */
  showLabel?: boolean;
  /** UI variant style */
  variant?: 'minimal' | 'default';
  /** Whether to show the globe icon */
  showIcon?: boolean;
  /** Additional CSS classes */
  className?: string;
  /**
   * Whether to render the selector when only one language is configured.
   * When `false` (the default), the selector hides itself in monolingual apps.
   */
  showWhenMonolingual?: boolean;
}

/**
 * `LanguageSelector` — a self-contained language picker wired to `LanguageContext`.
 *
 * The list of languages displayed is read from `LanguageContext.availableLanguages`
 * (configured via the `availableLanguages` prop on `<LanguageProvider>` or
 * `<XerticaProvider>`). The component is fully data-driven: pass any number of
 * languages and they will all appear in the dropdown.
 *
 * Changing the selected language:
 * 1. Updates `LanguageContext` (persists to localStorage)
 * 2. Calls `i18n.changeLanguage()` (all `useTranslation()` consumers re-render)
 * 3. Invalidates the React Query cache (data-layer strings refresh)
 *
 * **Auto-hide:** When only one language is configured (`isMonolingual === true`),
 * the component renders `null` by default. Pass `showWhenMonolingual` to override.
 *
 * Must be rendered inside `<LanguageProvider>`.
 */
export function LanguageSelector({
  showLabel = false,
  variant = 'default',
  showIcon = true,
  className = '',
  showWhenMonolingual = false,
}: LanguageSelectorProps) {
  const { language, setLanguage, availableLanguages, isMonolingual } = useLanguage();
  const { t } = useTranslation();

  // Hide selector when only one language is configured
  if (isMonolingual && !showWhenMonolingual) {
    return null;
  }

  // Compute display labels with i18n fallback support.
  // Known codes (pt-BR, en, es) get their localized label from translations;
  // custom codes use the label provided in the LanguageDefinition.
  const items = availableLanguages.map(lang => {
    const knownLabelKey =
      lang.code === 'pt-BR'
        ? 'languageSelector.ptBR'
        : lang.code === 'en'
          ? 'languageSelector.en'
          : lang.code === 'es'
            ? 'languageSelector.es'
            : null;

    return {
      value: lang.code,
      label: knownLabelKey ? t(knownLabelKey, lang.label) : lang.label,
      // Fall back to the first two characters of the code if no shortLabel given
      minimalLabel: lang.shortLabel ?? lang.code.slice(0, 2).toUpperCase(),
    };
  });

  const currentItem = items.find(l => l.value === language) ?? items[0];
  const displayLabel = variant === 'minimal' ? currentItem.minimalLabel : currentItem.label;

  return (
    <Select value={language} onValueChange={val => setLanguage(val as Language)}>
      <SelectTrigger
        className={`h-9 gap-2 px-3 border-none shadow-none focus:ring-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground ${className}`}
        aria-label={t('languageSelector.label', 'Selecionar idioma')}
      >
        {showIcon && <Globe className="h-4 w-4 shrink-0" />}
        {/* We do not use SelectValue here because it overrides our custom minimal rendering with the SelectItem's children. */}
        <span className="text-sm">{displayLabel}</span>
      </SelectTrigger>
      <SelectContent align="end">
        {items.map(({ value, label }) => (
          <SelectItem key={value} value={value}>
            {label}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  );
}
