/**
 * TimelineSlider.tsx
 * 
 * A horizontal timeline slider for filtering heritage institutions by temporal extent.
 * Displays a time range selector that allows users to see institutions that existed
 * during a specific period.
 * 
 * Features:
 * - Dual-handle range slider (start year to end year)
 * - Visual histogram showing institution density by decade
 * - Quick presets (Ancient, Medieval, Modern, Contemporary)
 * - Shows count of institutions visible in selected range
 * - Collapsible to minimize map obstruction
 * - Highlights destroyed/defunct institutions
 * 
 * Uses CIDOC-CRM E52_Time-Span pattern conceptually:
 * - Institution visible if: founding_year <= selectedEnd AND (dissolution_year >= selectedStart OR is_operational)
 */

import React, { useState, useMemo, useCallback, useRef, useEffect } from 'react';
import './TimelineSlider.css';

export interface TemporalData {
  founding_year?: number;
  founding_decade?: number;
  dissolution_year?: number;  // Extracted from temporal_extent.dissolution_date
  is_operational?: boolean;
  is_defunct?: boolean;
}

export interface TimelineSliderProps {
  /** All institutions with temporal data */
  institutions: Array<{ temporal?: TemporalData; name: string }>;
  /** Current selected year range [start, end] */
  selectedRange: [number, number];
  /** Called when range changes */
  onRangeChange: (range: [number, number]) => void;
  /** Whether the timeline filter is active */
  isActive: boolean;
  /** Toggle timeline filter on/off */
  onToggleActive: () => void;
  /** Translation function */
  t: (nl: string, en: string) => string;
  /** Current language */
  language: 'nl' | 'en';
}

// Timeline bounds - covers ancient to modern heritage institutions
const MIN_YEAR = 0;  // Year 0 to support ancient custodians
const MAX_YEAR = new Date().getFullYear();
const DECADE_WIDTH = 10;

// Quick preset ranges
const PRESETS = [
  { id: 'all', nl: 'Alles', en: 'All', range: [MIN_YEAR, MAX_YEAR] as [number, number] },
  { id: 'ancient', nl: 'Oudheid', en: 'Ancient', range: [0, 500] as [number, number] },
  { id: 'medieval', nl: 'Middeleeuwen', en: 'Medieval', range: [500, 1500] as [number, number] },
  { id: 'early-modern', nl: 'Vroegmodern', en: 'Early Modern', range: [1500, 1800] as [number, number] },
  { id: 'modern', nl: '19e eeuw', en: '19th Century', range: [1800, 1900] as [number, number] },
  { id: 'contemporary', nl: '20e eeuw+', en: '20th Century+', range: [1900, MAX_YEAR] as [number, number] },
];

export const TimelineSlider: React.FC<TimelineSliderProps> = ({
  institutions,
  selectedRange,
  onRangeChange,
  isActive,
  onToggleActive,
  t,
  language,
}) => {
  const [isCollapsed, setIsCollapsed] = useState(false);
  const [isDragging, setIsDragging] = useState<'start' | 'end' | null>(null);
  const sliderRef = useRef<HTMLDivElement>(null);

  // Calculate decade histogram - count institutions founded per decade
  const histogram = useMemo(() => {
    const decades: Record<number, { founded: number; active: number; dissolved: number }> = {};
    
    // Initialize all decades
    for (let year = MIN_YEAR; year <= MAX_YEAR; year += DECADE_WIDTH) {
      decades[year] = { founded: 0, active: 0, dissolved: 0 };
    }

    institutions.forEach(inst => {
      const temporal = inst.temporal;
      if (!temporal?.founding_year && !temporal?.founding_decade) return;

      const foundingYear = temporal.founding_year || (temporal.founding_decade ? temporal.founding_decade : null);
      if (!foundingYear) return;

      const foundingDecade = Math.floor(foundingYear / 10) * 10;
      if (foundingDecade >= MIN_YEAR && foundingDecade <= MAX_YEAR) {
        decades[foundingDecade].founded++;
      }

      // Count as dissolved if has dissolution year
      if (temporal.dissolution_year || temporal.is_defunct) {
        const dissolutionYear = temporal.dissolution_year;
        if (dissolutionYear) {
          const dissolutionDecade = Math.floor(dissolutionYear / 10) * 10;
          if (dissolutionDecade >= MIN_YEAR && dissolutionDecade <= MAX_YEAR) {
            decades[dissolutionDecade].dissolved++;
          }
        }
      }
    });

    // Calculate max for normalization
    const maxFounded = Math.max(...Object.values(decades).map(d => d.founded), 1);

    return { decades, maxFounded };
  }, [institutions]);

  // Calculate visible institutions count in selected range
  const visibleCount = useMemo(() => {
    if (!isActive) return institutions.length;

    return institutions.filter(inst => {
      const temporal = inst.temporal;
      
      const foundingYear = temporal?.founding_year || temporal?.founding_decade;
      const dissolutionYear = temporal?.dissolution_year;
      
      // If no temporal data at all, HIDE the institution when timeline filter is active
      if (!foundingYear && !dissolutionYear) return false;
      
      // If ONLY dissolution_year exists (no founding_year), we cannot determine
      // when the institution was founded, so we HIDE it (conservative approach)
      // Alternatively: assume it existed since year 0 (but user should enrich data)
      if (!foundingYear && dissolutionYear) {
        // Conservative: hide institutions without founding date
        // They need enrichment to be properly filtered
        return false;
      }

      // Institution is visible if:
      // 1. Founded before or during the selected end year
      // 2. AND (still operational OR dissolved after the selected start year)
      if (foundingYear && foundingYear > selectedRange[1]) return false;
      if (dissolutionYear && dissolutionYear < selectedRange[0]) return false;

      return true;
    }).length;
  }, [institutions, selectedRange, isActive]);

  // Count of defunct/destroyed institutions in range
  const defunctCount = useMemo(() => {
    if (!isActive) return 0;

    return institutions.filter(inst => {
      const temporal = inst.temporal;
      if (!temporal?.is_defunct && !temporal?.dissolution_year) return false;

      const foundingYear = temporal.founding_year || temporal.founding_decade;
      const dissolutionYear = temporal.dissolution_year;

      if (foundingYear && foundingYear > selectedRange[1]) return false;
      if (dissolutionYear && dissolutionYear < selectedRange[0]) return false;

      return true;
    }).length;
  }, [institutions, selectedRange, isActive]);

  // Convert pixel position to year
  const positionToYear = useCallback((clientX: number) => {
    if (!sliderRef.current) return selectedRange[0];
    const rect = sliderRef.current.getBoundingClientRect();
    const percentage = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
    return Math.round(MIN_YEAR + percentage * (MAX_YEAR - MIN_YEAR));
  }, [selectedRange]);

  // Handle mouse/touch events for dragging
  const handleMouseDown = useCallback((handle: 'start' | 'end') => (e: React.MouseEvent | React.TouchEvent) => {
    e.preventDefault();
    setIsDragging(handle);
  }, []);

  const handleMouseMove = useCallback((e: MouseEvent | TouchEvent) => {
    if (!isDragging) return;

    const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX;
    const year = positionToYear(clientX);

    if (isDragging === 'start') {
      onRangeChange([Math.min(year, selectedRange[1] - 10), selectedRange[1]]);
    } else {
      onRangeChange([selectedRange[0], Math.max(year, selectedRange[0] + 10)]);
    }
  }, [isDragging, positionToYear, selectedRange, onRangeChange]);

  const handleMouseUp = useCallback(() => {
    setIsDragging(null);
  }, []);

  // Global event listeners for dragging
  useEffect(() => {
    if (isDragging) {
      window.addEventListener('mousemove', handleMouseMove);
      window.addEventListener('mouseup', handleMouseUp);
      window.addEventListener('touchmove', handleMouseMove);
      window.addEventListener('touchend', handleMouseUp);
    }

    return () => {
      window.removeEventListener('mousemove', handleMouseMove);
      window.removeEventListener('mouseup', handleMouseUp);
      window.removeEventListener('touchmove', handleMouseMove);
      window.removeEventListener('touchend', handleMouseUp);
    };
  }, [isDragging, handleMouseMove, handleMouseUp]);

  // Calculate handle positions as percentages
  const startPercent = ((selectedRange[0] - MIN_YEAR) / (MAX_YEAR - MIN_YEAR)) * 100;
  const endPercent = ((selectedRange[1] - MIN_YEAR) / (MAX_YEAR - MIN_YEAR)) * 100;

  if (isCollapsed) {
    return (
      <div className="timeline-slider timeline-slider--collapsed">
        <button 
          className="timeline-slider__expand-btn"
          onClick={() => setIsCollapsed(false)}
          title={t('Tijdlijn uitvouwen', 'Expand timeline')}
        >
          <span className="timeline-slider__expand-icon">📅</span>
          <span className="timeline-slider__expand-text">
            {isActive 
              ? `${selectedRange[0]} - ${selectedRange[1]}` 
              : t('Tijdlijn', 'Timeline')}
          </span>
        </button>
      </div>
    );
  }

  return (
    <div className={`timeline-slider ${isActive ? 'timeline-slider--active' : ''}`}>
      {/* Header */}
      <div className="timeline-slider__header">
        <div className="timeline-slider__title">
          <span className="timeline-slider__icon">📅</span>
          <span>{t('Tijdlijn', 'Timeline')}</span>
        </div>

        <div className="timeline-slider__controls">
          {/* Toggle switch */}
          <label className="timeline-slider__toggle">
            <input 
              type="checkbox" 
              checked={isActive}
              onChange={() => onToggleActive()}
            />
            <span className="timeline-slider__toggle-slider"></span>
            <span className="timeline-slider__toggle-label">
              {isActive ? t('Aan', 'On') : t('Uit', 'Off')}
            </span>
          </label>

          {/* Collapse button */}
          <button 
            className="timeline-slider__collapse-btn"
            onClick={() => setIsCollapsed(true)}
            title={t('Tijdlijn inklappen', 'Collapse timeline')}
          >
            ▼
          </button>
        </div>
      </div>

      {/* Stats */}
      <div className="timeline-slider__stats">
        <span className="timeline-slider__stat">
          {visibleCount.toLocaleString()} {t('zichtbaar', 'visible')}
        </span>
        {isActive && defunctCount > 0 && (
          <span className="timeline-slider__stat timeline-slider__stat--defunct">
            ⚠️ {defunctCount} {t('opgeheven', 'defunct')}
          </span>
        )}
        <span className="timeline-slider__range-display">
          {selectedRange[0]} — {selectedRange[1]}
        </span>
      </div>

      {/* Presets */}
      <div className="timeline-slider__presets">
        {PRESETS.map(preset => (
          <button
            key={preset.id}
            className={`timeline-slider__preset ${
              selectedRange[0] === preset.range[0] && selectedRange[1] === preset.range[1]
                ? 'timeline-slider__preset--active'
                : ''
            }`}
            onClick={() => onRangeChange(preset.range)}
            disabled={!isActive}
          >
            {language === 'nl' ? preset.nl : preset.en}
          </button>
        ))}
      </div>

      {/* Histogram and Slider */}
      <div className="timeline-slider__track-container">
        {/* Histogram bars */}
        <div className="timeline-slider__histogram">
          {Object.entries(histogram.decades).map(([decadeStr, data]) => {
            const decade = parseInt(decadeStr);
            const height = (data.founded / histogram.maxFounded) * 100;
            const left = ((decade - MIN_YEAR) / (MAX_YEAR - MIN_YEAR)) * 100;
            const isInRange = decade >= selectedRange[0] && decade <= selectedRange[1];
            const hasDissolved = data.dissolved > 0;

            return (
              <div
                key={decade}
                className={`timeline-slider__histogram-bar ${isInRange ? 'timeline-slider__histogram-bar--in-range' : ''} ${hasDissolved ? 'timeline-slider__histogram-bar--dissolved' : ''}`}
                style={{
                  left: `${left}%`,
                  height: `${Math.max(height, 2)}%`,
                }}
                title={`${decade}s: ${data.founded} ${t('opgericht', 'founded')}${hasDissolved ? `, ${data.dissolved} ${t('opgeheven', 'dissolved')}` : ''}`}
              />
            );
          })}
        </div>

        {/* Slider track */}
        <div 
          className="timeline-slider__track" 
          ref={sliderRef}
        >
          {/* Selected range highlight */}
          <div 
            className="timeline-slider__range-highlight"
            style={{
              left: `${startPercent}%`,
              width: `${endPercent - startPercent}%`,
            }}
          />

          {/* Start handle */}
          <div
            className={`timeline-slider__handle timeline-slider__handle--start ${isDragging === 'start' ? 'timeline-slider__handle--dragging' : ''}`}
            style={{ left: `${startPercent}%` }}
            onMouseDown={handleMouseDown('start')}
            onTouchStart={handleMouseDown('start')}
            role="slider"
            aria-label={t('Startjaar', 'Start year')}
            aria-valuenow={selectedRange[0]}
            aria-valuemin={MIN_YEAR}
            aria-valuemax={MAX_YEAR}
            tabIndex={0}
          >
            <span className="timeline-slider__handle-label">{selectedRange[0]}</span>
          </div>

          {/* End handle */}
          <div
            className={`timeline-slider__handle timeline-slider__handle--end ${isDragging === 'end' ? 'timeline-slider__handle--dragging' : ''}`}
            style={{ left: `${endPercent}%` }}
            onMouseDown={handleMouseDown('end')}
            onTouchStart={handleMouseDown('end')}
            role="slider"
            aria-label={t('Eindjaar', 'End year')}
            aria-valuenow={selectedRange[1]}
            aria-valuemin={MIN_YEAR}
            aria-valuemax={MAX_YEAR}
            tabIndex={0}
          >
            <span className="timeline-slider__handle-label">{selectedRange[1]}</span>
          </div>
        </div>

        {/* Axis labels */}
        <div className="timeline-slider__axis">
          <span>{MIN_YEAR}</span>
          <span>500</span>
          <span>1000</span>
          <span>1500</span>
          <span>1800</span>
          <span>2000</span>
          <span>{MAX_YEAR}</span>
        </div>
      </div>
    </div>
  );
};

// Memoize to prevent unnecessary re-renders when parent updates
export default React.memo(TimelineSlider);
