import { useState, useCallback } from 'react';
import { Slider } from '../ui/Slider';
import { IconButton } from '../ui/IconButton';
import { PillToggle } from '../ui/PillToggle';
import { DestinationDropdown } from '../ui/DestinationDropdown';
import InfoPopup from '../ui/InfoPopup';
import { CloseIcon } from '../ui/icons/CloseIcon';
import { EyeIcon } from '../ui/icons/EyeIcon';
import { InfoIcon } from '../ui/icons/InfoIcon';
import { CarIcon } from '../ui/icons/CarIcon';
import { BicycleIcon } from '../ui/icons/BicycleIcon';
import { WalkingIcon } from '../ui/icons/WalkingIcon';
import { TransitIcon } from '../ui/icons/TransitIcon';
import { formatFilterValue } from '../../lib/format';
import { useTravelDestinations } from '../../hooks/useTravelDestinations';
import { MODE_LABELS, type TransportMode } from '../../hooks/useTravelTime';
import type { ComponentType } from 'react';

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

interface TravelTimeCardProps {
  mode: TransportMode;
  slug: string;
  label: string;
  timeRange: [number, number] | null;
  useBest: boolean;
  isPinned: boolean;
  onTogglePin: () => void;
  onSetDestination: (slug: string, label: string) => void;
  onTimeRangeChange: (range: [number, number]) => void;
  onToggleBest: () => void;
  onRemove: () => void;
}

export function TravelTimeCard({
  mode,
  slug,
  label,
  timeRange,
  useBest,
  isPinned,
  onTogglePin,
  onSetDestination,
  onTimeRangeChange,
  onToggleBest,
  onRemove,
}: TravelTimeCardProps) {
  const { destinations, loading: destinationsLoading } = useTravelDestinations(mode);
  const [showInfo, setShowInfo] = useState(false);
  const [showBestInfo, setShowBestInfo] = useState(false);

  const handleDestinationSelect = useCallback(
    (selectedSlug: string, selectedLabel: string) => {
      onSetDestination(selectedSlug, selectedLabel);
    },
    [onSetDestination]
  );

  const sliderMin = 0;
  const sliderMax = 120;
  const displayRange = timeRange ?? [sliderMin, sliderMax];

  const ModeIcon = MODE_ICONS[mode];

  return (
    <div
      className={`space-y-2 px-2 py-2 rounded ${isPinned ? 'ring-2 ring-teal-400 bg-teal-50/50 dark:bg-teal-900/20' : ''}`}
    >
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-1.5">
          <ModeIcon className="w-4 h-4 text-teal-600 dark:text-teal-400" />
          <span className="text-sm font-medium text-navy-950 dark:text-warm-100">
            Travel Time ({MODE_LABELS[mode]})
          </span>
        </div>
        <div className="flex items-center gap-0.5">
          <IconButton onClick={() => setShowInfo(true)} title="Feature info">
            <InfoIcon className="w-3.5 h-3.5" />
          </IconButton>
          {slug && (
            <IconButton
              onClick={onTogglePin}
              active={isPinned}
              title={isPinned ? 'Stop previewing' : 'Preview on map'}
            >
              <EyeIcon className="w-3.5 h-3.5" filled={isPinned} />
            </IconButton>
          )}
          <IconButton onClick={() => onRemove()} title="Remove travel time">
            <CloseIcon className="w-3.5 h-3.5" />
          </IconButton>
        </div>
      </div>

      {/* Destination */}
      <DestinationDropdown
        destinations={destinations}
        loading={destinationsLoading}
        onSelect={handleDestinationSelect}
        value={label || undefined}
        onClear={() => onSetDestination('', '')}
        placeholder="Select destination..."
      />

      {/* Best-case toggle — transit only, shown when destination is set */}
      {slug && mode === 'transit' && (
        <div className="flex items-center gap-1.5">
          <PillToggle label="Best case" active={useBest} onClick={onToggleBest} size="xs" />
          <IconButton onClick={() => setShowBestInfo(true)} title="What is best case?">
            <InfoIcon className="w-3 h-3" />
          </IconButton>
        </div>
      )}

      {showInfo && (
        <InfoPopup title={`Travel Time (${MODE_LABELS[mode]})`} onClose={() => setShowInfo(false)}>
          <p className="text-sm text-warm-700 dark:text-warm-300 leading-relaxed">
            Shows how long it takes to reach the selected destination from each area
            {mode === 'transit'
              ? ' by public transport (bus, rail, tube). Times are computed across a typical weekday morning window.'
              : mode === 'car'
                ? ' by car, based on typical road speeds and the road network.'
                : mode === 'bicycle'
                  ? ' by bicycle, using cycle-friendly routes.'
                  : ' on foot, using pedestrian paths and pavements.'}{' '}
            Use the slider to filter areas within your preferred commute time.
          </p>
        </InfoPopup>
      )}

      {showBestInfo && (
        <InfoPopup title="Best case travel time" onClose={() => setShowBestInfo(false)}>
          <p className="text-sm text-warm-700 dark:text-warm-300 leading-relaxed">
            Uses the <strong>5th percentile</strong> travel time - the fastest realistic journey if
            you time your departure to catch optimal connections. The default uses the{' '}
            <strong>median</strong>, representing a typical journey regardless of when you leave.
          </p>
        </InfoPopup>
      )}

      {/* Time range slider — only show when we have data */}
      {slug && (
        <div>
          <span className="text-[10px] font-medium text-warm-500 dark:text-warm-400 uppercase tracking-wide">
            Max time
          </span>
          <Slider
            min={sliderMin}
            max={sliderMax}
            step={1}
            value={[displayRange[0], displayRange[1]]}
            onValueChange={([min, max]) => onTimeRangeChange([min, max])}
          />
          <div className="relative h-4 mt-1 mx-2.5 text-[10px] text-warm-500 dark:text-warm-400 leading-tight">
            <span className="absolute left-0">{formatFilterValue(displayRange[0])} min</span>
            <span className="absolute right-0">{formatFilterValue(displayRange[1])} min</span>
          </div>
        </div>
      )}
    </div>
  );
}
