import { useState, useMemo, useEffect } from 'react';
import { useCollapsibleGroups } from '../../hooks/useCollapsibleGroups';
import { SearchInput } from '../ui/SearchInput';
import { FilterIcon } from '../ui/icons';
import { CollapsibleGroupHeader } from '../ui/CollapsibleGroupHeader';
import { EmptyState } from '../ui/EmptyState';
import type { FeatureMeta } from '../../types';
import { groupFeaturesByCategory } from '../../lib/features';
import { FeatureInfoPopup } from '../ui/FeatureInfoPopup';
import { FeatureActions } from '../ui/FeatureIcons';
import { FeatureLabel } from '../ui/FeatureLabel';
import { CarIcon, BicycleIcon, WalkingIcon, TransitIcon, PlusIcon } from '../ui/icons';
import type { ComponentType } from 'react';
import { IconButton } from '../ui/IconButton';
import { TRANSPORT_MODES, MODE_LABELS, MODE_DESCRIPTIONS, type TransportMode, type TravelTimeEntry } from '../../hooks/useTravelTime';

const MODE_ICONS: Record<TransportMode, ComponentType<{ className?: string }>> = {
  car: CarIcon,
  bicycle: BicycleIcon,
  walking: WalkingIcon,
  transit: TransitIcon,
};

interface FeatureBrowserProps {
  availableFeatures: FeatureMeta[];
  allFeatures: FeatureMeta[];
  pinnedFeature: string | null;
  onAddFilter: (name: string) => void;
  onTogglePin: (name: string) => void;
  onNavigateToSource?: (slug: string, featureName: string) => void;
  openInfoFeature?: string | null;
  onClearOpenInfoFeature?: () => void;
  travelTimeEntries: TravelTimeEntry[];
  onAddTravelTimeEntry: (mode: TransportMode) => void;
  isLicensed: boolean;
  onUpgradeClick?: () => void;
}

export default function FeatureBrowser({
  availableFeatures,
  allFeatures,
  pinnedFeature,
  onAddFilter,
  onTogglePin,
  onNavigateToSource,
  openInfoFeature,
  onClearOpenInfoFeature,
  travelTimeEntries,
  onAddTravelTimeEntry,
  isLicensed,
  onUpgradeClick,
}: FeatureBrowserProps) {
  const [search, setSearch] = useState('');
  const [infoFeature, setInfoFeature] = useState<FeatureMeta | null>(null);
  const [expandedGroups, toggleGroup] = useCollapsibleGroups();

  useEffect(() => {
    if (openInfoFeature) {
      const feat = allFeatures.find((f) => f.name === openInfoFeature);
      if (feat) setInfoFeature(feat);
      onClearOpenInfoFeature?.();
    }
  }, [openInfoFeature, allFeatures, onClearOpenInfoFeature]);

  const filtered = useMemo(() => {
    if (!search) return availableFeatures;
    const lower = search.toLowerCase();
    return availableFeatures.filter((f) => f.name.toLowerCase().includes(lower));
  }, [availableFeatures, search]);

  const grouped = useMemo(() => groupFeaturesByCategory(filtered), [filtered]);

  // When searching, expand all groups so results are visible
  const isSearching = search.length > 0;

  // All modes are always available (can add multiple entries per mode)
  const showTravelModes =
    !search || 'travel time journey commute car bicycle walking transit'.includes(search.toLowerCase());

  return (
    <>
      <div className="shrink-0 p-2 border-b border-warm-200 dark:border-navy-700">
        <SearchInput value={search} onChange={setSearch} placeholder="Search features..." />
      </div>
      <div className="md:min-h-0 md:flex-1 md:overflow-y-auto flex flex-col">
        {showTravelModes && (
          <div className="shrink-0">
            <CollapsibleGroupHeader
              name="Travel Time"
              expanded={isSearching || expandedGroups.has('Travel Time')}
              onToggle={() => toggleGroup('Travel Time')}
              className="px-3 py-2.5 text-sm font-bold text-navy-950 bg-warm-200 dark:bg-navy-900 dark:text-warm-100 sticky top-0 z-10 hover:bg-warm-200 dark:hover:bg-warm-800"
            >
              <span className="text-xs font-medium text-warm-400 dark:text-warm-500">
                {TRANSPORT_MODES.length}
              </span>
            </CollapsibleGroupHeader>
            {(isSearching || expandedGroups.has('Travel Time')) && TRANSPORT_MODES.map((mode) => {
              const ModeIcon = MODE_ICONS[mode];
              return (
                <div
                  key={mode}
                  className="flex items-start justify-between px-3 py-1.5 hover:bg-teal-50 dark:hover:bg-teal-900/30 cursor-pointer"
                >
                  <div className="flex items-center gap-2 min-w-0" onClick={() => onAddTravelTimeEntry(mode)}>
                    <ModeIcon className="w-4 h-4 text-teal-600 dark:text-teal-400 shrink-0" />
                    <div className="min-w-0">
                      <span className="text-sm font-medium text-navy-950 dark:text-warm-100">
                        {MODE_LABELS[mode]}
                      </span>
                      <span className="text-xs text-warm-400 dark:text-warm-500 block">
                        {MODE_DESCRIPTIONS[mode]}
                      </span>
                    </div>
                  </div>
                  <div className="flex items-center gap-0.5 shrink-0">
                    <IconButton onClick={() => onAddTravelTimeEntry(mode)} title={`Add ${MODE_LABELS[mode]} travel time`} size="md">
                      <PlusIcon className="w-7 h-7 md:w-3.5 md:h-3.5" />
                    </IconButton>
                  </div>
                </div>
              );
            })}
          </div>
        )}
        {grouped.map((group) => {
          const isExpanded = isSearching || expandedGroups.has(group.name);
          return (
            <div key={group.name} className="shrink-0">
              <CollapsibleGroupHeader
                name={group.name}
                expanded={isExpanded}
                onToggle={() => toggleGroup(group.name)}
                className="px-3 py-2.5 text-sm font-bold text-navy-950 bg-warm-200 dark:bg-navy-900 dark:text-warm-100 sticky top-0 z-10 hover:bg-warm-200 dark:hover:bg-warm-800"
              >
                <span className="text-xs font-medium text-warm-400 dark:text-warm-500">
                  {group.features.length}
                </span>
              </CollapsibleGroupHeader>
              {isExpanded &&
                group.features.map((f) => {
                  const isPinned = pinnedFeature === f.name;
                  return (
                    <div
                      key={f.name}
                      className="flex items-start justify-between px-3 py-1.5 hover:bg-teal-50 dark:hover:bg-teal-900/30 dark:text-warm-300"
                    >
                      <div className="min-w-0 mr-2">
                        <FeatureLabel feature={f} onShowInfo={setInfoFeature} size="sm" />
                        {f.description && (
                          <span className="text-xs text-warm-400 dark:text-warm-500 truncate block">
                            {f.description}
                          </span>
                        )}
                      </div>
                      <FeatureActions
                        feature={f}
                        isPinned={isPinned}
                        onTogglePin={onTogglePin}
                        onAdd={onAddFilter}
                      />
                    </div>
                  );
                })}
            </div>
          );
        })}
        {grouped.length === 0 ? (
          <EmptyState
            icon={<FilterIcon className="w-8 h-8 text-warm-300 dark:text-warm-600" />}
            title={search ? 'No matching features' : 'All features are active'}
            description={
              search ? 'Try a different search term' : 'Remove a filter to see available features'
            }
            className="px-3 py-4"
          />
        ) : isLicensed ? (
          <p className="flex-1 flex items-center justify-center px-4 py-6 text-xs text-center text-warm-400 dark:text-warm-500">
            Everyone cares about different things. Pick the filters that matter most to you.
          </p>
        ) : (
          <div className="mt-auto flex flex-col items-center px-5 pt-6 pb-0">
            <p className="text-sm text-warm-600 dark:text-warm-400 text-center leading-relaxed mb-1">
              The biggest financial decision of your life deserves proper tools behind it.
            </p>
            <p className="text-xs text-warm-400 dark:text-warm-500 text-center mb-4">
              Don&apos;t leave it to chance.
            </p>
            <button
              onClick={onUpgradeClick}
              className="px-5 py-2.5 rounded-lg bg-gradient-to-r from-teal-500 to-teal-600 hover:from-teal-600 hover:to-teal-700 text-white font-medium text-sm shadow-sm hover:shadow-md"
            >
              Upgrade to full map
            </button>
            <svg viewBox="0 120 1600 230" className="w-full mt-4 block shrink-0" preserveAspectRatio="xMidYMax meet">
              <path d="M0,350 C400,150 1200,150 1600,350 Z" className="fill-green-500 dark:fill-green-600" />
              <path d="M100,350 C450,180 1150,180 1500,350 Z" fill="#000" opacity="0.08" />
              <path d="M250,350 C550,220 1050,220 1350,350 Z" fill="#000" opacity="0.06" />
              <image href="/house.png" x="735" y="110" width="130" height="120" />
            </svg>
          </div>
        )}
      </div>
      {infoFeature && (
        <FeatureInfoPopup
          feature={infoFeature}
          onClose={() => setInfoFeature(null)}
          onNavigateToSource={onNavigateToSource}
        />
      )}
    </>
  );
}
