/**
 * ProviderSelector Component
 *
 * Wiederverwendbare Komponente zur Auswahl von AICore-Providern.
 * Kann im AI Workspace und Automation Editor verwendet werden.
 *
 * Selektionsmodell:
 *   ProviderSelection { include: string[], exclude: string[] }
 *   - include(["ALL"]), exclude([])          → alle verfügbaren Provider (dynamisch)
 *   - include(["ALL"]), exclude(["private"])  → alle ausser "private" (dynamisch)
 *   - include(["anthropic"]), exclude([])     → nur Anthropic
 *   - include([]), exclude([])                → keiner ausgewählt
 *
 * resolveProviders(selection, allowedProviders) liefert die konkrete Liste.
 */

import React, { useEffect, useMemo, useState, useRef, useCallback } from 'react';
import { useBilling } from '../../hooks/useBilling';
import styles from './ProviderSelector.module.css';

import { useLanguage } from '../../providers/language/LanguageContext';

// ============================================================================
// TYPES & HELPERS
// ============================================================================

export const PROVIDER_ALL = 'ALL';

export interface ProviderSelection {
  include: string[];
  exclude: string[];
}

export function _defaultProviderSelection(): ProviderSelection {
  return { include: [PROVIDER_ALL], exclude: [] };
}

export function _resolveProviders(
  selection: ProviderSelection,
  allowedProviders: string[],
): string[] {
  if (selection.include.includes(PROVIDER_ALL)) {
    return allowedProviders.filter((p) => !selection.exclude.includes(p));
  }
  return selection.include.filter((p) => allowedProviders.includes(p));
}

export function _isAllSelected(selection: ProviderSelection): boolean {
  return selection.include.includes(PROVIDER_ALL) && selection.exclude.length === 0;
}

export function _isNoneSelected(
  selection: ProviderSelection,
  allowedProviders: string[],
): boolean {
  return _resolveProviders(selection, allowedProviders).length === 0;
}

/**
 * Migrate legacy string[] (old model) to ProviderSelection.
 * [] → ALL, [...ids] → include those ids.
 */
export function _migrateFromLegacy(providers: string[]): ProviderSelection {
  if (providers.length === 0) return _defaultProviderSelection();
  return { include: providers, exclude: [] };
}

/**
 * Convert ProviderSelection to flat list for backend API calls.
 * Returns [] when ALL are selected (= no restriction / legacy behaviour).
 */
export function _toBackendProviders(
  selection: ProviderSelection,
  allowedProviders: string[],
): string[] {
  if (_isAllSelected(selection)) return [];
  return _resolveProviders(selection, allowedProviders);
}

const _PROVIDER_LABEL_KEYS: Record<string, string> = {
  anthropic: 'Anthropic (Claude)',
  openai: 'OpenAI (GPT)',
  mistral: 'Mistral (Le Chat)',
  perplexity: 'Perplexity',
  tavily: 'Tavily (Web Search)',
  privatellm: 'Private LLM',
  internal: 'Internal',
};

function _providerLabel(provider: string): string {
  const key = _PROVIDER_LABEL_KEYS[provider];
  return key ? key : provider;
}

const PROVIDER_ICONS: Record<string, string> = {
  anthropic: '🤖',
  openai: '💬',
  mistral: '🇫🇷',
  perplexity: '🔍',
  tavily: '🌐',
  privatellm: '🔒',
  internal: '🏠',
};

// ============================================================================
// SINGLE SELECT COMPONENT
// ============================================================================

interface ProviderSelectProps {
  value: string;
  onChange: (provider: string) => void;
  disabled?: boolean;
  className?: string;
  label?: string;
  showLabel?: boolean;
}

export const ProviderSelect: React.FC<ProviderSelectProps> = ({ value,
  onChange,
  disabled = false,
  className,
  label,
  showLabel = true,
}) => {
  const { t } = useLanguage();
  const resolvedLabel = label ?? t('AI-Provider');
  const { allowedProviders, loadAllowedProviders, loading } = useBilling();

  useEffect(() => {
    if (allowedProviders.length === 0 && !loading) {
      loadAllowedProviders();
    }
  }, []);

  const providerOptions = useMemo(() => {
    return allowedProviders.map((provider) => ({
      value: provider,
      label: `${PROVIDER_ICONS[provider] || '🔌'} ${_providerLabel(provider)}`,
    }));
  }, [allowedProviders, t]);

  return (
    <div className={`${styles.providerSelect} ${className || ''}`}>
      {showLabel && <label className={styles.label}>{resolvedLabel}</label>}
      <select
        value={value}
        onChange={(e) => onChange(e.target.value)}
        disabled={disabled || loading}
        className={styles.select}
      >
        <option value="">{t('Auto')}</option>
        {providerOptions.map((option) => (
          <option key={option.value} value={option.value}>
            {option.label}
          </option>
        ))}
      </select>
    </div>
  );
};

// ============================================================================
// MULTI SELECT COMPONENT (Checkbox List) — include / exclude model
// ============================================================================

interface ProviderMultiSelectProps {
  selection: ProviderSelection;
  onChange: (selection: ProviderSelection) => void;
  disabled?: boolean;
  className?: string;
  label?: string;
  showLabel?: boolean;
  defaultExpanded?: boolean;
  excludeByDefault?: string[];
}

export const ProviderMultiSelect: React.FC<ProviderMultiSelectProps> = ({
  selection,
  onChange,
  disabled = false,
  className,
  label,
  showLabel = true,
  defaultExpanded = false,
  excludeByDefault = [],
}) => {
  const { t } = useLanguage();
  const resolvedLabel = label ?? t('AI-Provider');
  const [isExpanded, setIsExpanded] = useState(defaultExpanded);
  const [initialExcludeApplied, setInitialExcludeApplied] = useState(false);
  const containerRef = useRef<HTMLDivElement>(null);
  const { allowedProviders, loadAllowedProviders, loading } = useBilling();

  useEffect(() => {
    if (allowedProviders.length === 0 && !loading) {
      loadAllowedProviders();
    }
  }, []);

  // Apply default exclusions once when providers first load
  useEffect(() => {
    if (
      !initialExcludeApplied &&
      allowedProviders.length > 0 &&
      excludeByDefault.length > 0 &&
      _isAllSelected(selection)
    ) {
      onChange({ include: [PROVIDER_ALL], exclude: [...excludeByDefault] });
      setInitialExcludeApplied(true);
    }
  }, [allowedProviders, excludeByDefault, initialExcludeApplied, selection, onChange]);

  const _handleClickOutside = useCallback((event: MouseEvent) => {
    if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
      setIsExpanded(false);
    }
  }, []);

  useEffect(() => {
    if (isExpanded) {
      document.addEventListener('mousedown', _handleClickOutside);
      return () => document.removeEventListener('mousedown', _handleClickOutside);
    }
  }, [isExpanded, _handleClickOutside]);

  const effectiveSelection = useMemo(
    () => _resolveProviders(selection, allowedProviders),
    [selection, allowedProviders],
  );

  const allSelected = _isAllSelected(selection);
  const noneSelected = effectiveSelection.length === 0;

  const _handleToggle = (provider: string) => {
    const isChecked = effectiveSelection.includes(provider);

    if (selection.include.includes(PROVIDER_ALL)) {
      // Currently ALL-based: toggle modifies exclude list
      if (isChecked) {
        onChange({ include: [PROVIDER_ALL], exclude: [...selection.exclude, provider] });
      } else {
        const nextExclude = selection.exclude.filter((p) => p !== provider);
        onChange({ include: [PROVIDER_ALL], exclude: nextExclude });
      }
    } else {
      // Explicit include list
      if (isChecked) {
        onChange({ include: selection.include.filter((p) => p !== provider), exclude: [] });
      } else {
        const nextInclude = [...selection.include, provider];
        if (nextInclude.length === allowedProviders.length) {
          onChange({ include: [PROVIDER_ALL], exclude: [] });
        } else {
          onChange({ include: nextInclude, exclude: [] });
        }
      }
    }
  };

  const _handleSelectAll = () => {
    onChange({ include: [PROVIDER_ALL], exclude: [] });
  };

  const summaryIcon = useMemo(() => {
    if (noneSelected) return '⊘';
    if (effectiveSelection.length === 1) {
      return PROVIDER_ICONS[effectiveSelection[0]] || '🔌';
    }
    return '⚡';
  }, [effectiveSelection, noneSelected]);

  const summaryHint = useMemo(() => {
    if (noneSelected) return t('Kein Provider ausgewählt');
    if (allSelected) return t('Alle Provider aktiv (dynamisch)');
    if (selection.include.includes(PROVIDER_ALL)) {
      return t('Alle ausser {count} Provider', { count: String(selection.exclude.length) });
    }
    return t('{n} von {total} Provider', { n: String(effectiveSelection.length), total: String(allowedProviders.length) });
  }, [noneSelected, allSelected, selection, effectiveSelection, allowedProviders, t]);

  return (
    <div
      ref={containerRef}
      className={`${styles.providerMultiSelect} ${className || ''} ${isExpanded ? styles.expanded : styles.collapsed}`}
    >
      <button
        type="button"
        className={styles.triggerButton}
        onClick={() => setIsExpanded(!isExpanded)}
        disabled={disabled}
        title={t('Provider auswählen')}
      >
        <span className={styles.buttonIcon}>{summaryIcon}</span>
      </button>

      {isExpanded && (
        <div className={styles.dropdownContent}>
          {showLabel && <div className={styles.dropdownHeader}>{resolvedLabel}</div>}

          <div className={styles.selectActions}>
            <button
              type="button"
              onClick={_handleSelectAll}
              disabled={disabled}
              className={`${styles.actionButton} ${allSelected ? styles.active : ''}`}
            >
              {t('Alle')}
            </button>
          </div>

          {loading ? (
            <div className={styles.loading}>{t('Laden')}</div>
          ) : (
            <div className={styles.checkboxList}>
              {allowedProviders.map((provider) => (
                <label
                  key={provider}
                  className={`${styles.checkboxItem} ${disabled ? styles.disabled : ''}`}
                >
                  <input
                    type="checkbox"
                    checked={effectiveSelection.includes(provider)}
                    onChange={() => _handleToggle(provider)}
                    disabled={disabled}
                  />
                  <span className={styles.icon}>{PROVIDER_ICONS[provider] || '🔌'}</span>
                  <span className={styles.providerName}>
                    {_providerLabel(provider)}
                  </span>
                </label>
              ))}
            </div>
          )}

          <div className={styles.hint}>{summaryHint}</div>
        </div>
      )}
    </div>
  );
};

// ============================================================================
// COMPACT PROVIDER BADGE LIST
// ============================================================================

interface ProviderBadgesProps {
  providers: string[];
  className?: string;
}

export const ProviderBadges: React.FC<ProviderBadgesProps> = ({
  providers,
  className,
}) => {
  const { t } = useLanguage();
  if (providers.length === 0) {
    return <span className={styles.allProviders}>{t('Alle Provider')}</span>;
  }

  return (
    <div className={`${styles.providerBadges} ${className || ''}`}>
      {providers.map((provider) => (
        <span key={provider} className={styles.badge}>
          {PROVIDER_ICONS[provider] || '🔌'} {_providerLabel(provider)}
        </span>
      ))}
    </div>
  );
};

export default ProviderSelect;
