import { useState, useEffect, useCallback, useRef } from 'react';
import type maplibregl from 'maplibre-gl';
import { MapView } from './MapView';
import { CommandPalette } from './CommandPalette';
import { FilterChips } from './FilterChips';
import { TimelineScrubber } from './TimelineScrubber';
import { ActivityStream } from './ActivityStream';
import { PulseLayer } from './PulseLayer';
import { FlowLayer } from './FlowLayer';
import { MetricSwitcher } from './MetricSwitcher';
import { NationalPanel, UatDetailPanel } from './StatColumn';
import type {
  UatStats,
  UatMetric,
  ChoroplethMetric,
  NationalStats,
  CountyStats,
  FeedItem,
  MapFilters,
  YearFilter,
} from './types';

export function HartaApp() {
  const [choroplethData, setChoroplethData] = useState<UatStats[]>([]);
  const [metricData, setMetricData] = useState<UatMetric[] | undefined>(undefined);
  const [nationalStats, setNationalStats] = useState<NationalStats | null>(null);
  const [countyStats, setCountyStats] = useState<CountyStats[]>([]);
  const [feedItems, setFeedItems] = useState<FeedItem[]>([]);
  const [newPulses, setNewPulses] = useState<FeedItem[]>([]);
  const [selectedUat, setSelectedUat] = useState<string | null>(null);
  const [uatDetail, setUatDetail] = useState<any>(null);
  const [filters, setFilters] = useState<MapFilters>({ year: 'all', metric: 'value' });
  const [loading, setLoading] = useState(true);
  const [paletteOpen, setPaletteOpen] = useState(false);
  const [columnCollapsed, setColumnCollapsed] = useState(false);
  const [flyToSiruta, setFlyToSiruta] = useState<string | null>(null);
  const mapRef = useRef<maplibregl.Map | null>(null);
  const seenFeedIds = useRef<Set<string>>(new Set());

  // Initial + year-change loads (stats, choropleth, feed)
  useEffect(() => {
    let cancelled = false;
    async function load() {
      setLoading(true);
      try {
        const yearPart = filters.year === 'all' ? 'all' : String(filters.year);
        const [statsRes, choroplethRes, feedRes] = await Promise.all([
          fetch('/api/harta/stats'),
          fetch(`/api/harta/choropleth/${yearPart}`),
          fetch('/api/harta/feed/40'),
        ]);
        const stats = await statsRes.json();
        const choropleth = await choroplethRes.json();
        const feed = await feedRes.json();
        if (cancelled) return;

        setNationalStats(stats.national);
        setCountyStats(stats.counties);
        setChoroplethData(choropleth.data || []);
        const items = Array.isArray(feed) ? feed : [];
        setFeedItems(items);
        seenFeedIds.current = new Set(items.map((i: FeedItem) => `${i.type}-${i.id}`));
      } catch (err) {
        console.error('Failed to load:', err);
      } finally {
        if (!cancelled) setLoading(false);
      }
    }
    load();
    return () => { cancelled = true; };
  }, [filters.year]);

  // Metric-change loads (separate cache, no full-page loader)
  useEffect(() => {
    if (filters.metric === 'value') {
      // Value mode reuses choroplethData, no separate fetch needed
      setMetricData(undefined);
      return;
    }
    let cancelled = false;
    fetch(`/api/harta/metric/${filters.metric}`)
      .then((r) => r.json())
      .then((d) => { if (!cancelled) setMetricData(d.data || []); })
      .catch((e) => console.error('Metric fetch failed:', e));
    return () => { cancelled = true; };
  }, [filters.metric]);

  // Polling for new feed items every 30s
  useEffect(() => {
    const id = setInterval(async () => {
      try {
        const res = await fetch('/api/harta/feed/40');
        const data: FeedItem[] = await res.json();
        if (!Array.isArray(data)) return;
        const fresh = data.filter((i) => !seenFeedIds.current.has(`${i.type}-${i.id}`));
        if (fresh.length > 0) {
          fresh.forEach((i) => seenFeedIds.current.add(`${i.type}-${i.id}`));
          setFeedItems((prev) => [...fresh, ...prev].slice(0, 60));
          setNewPulses(fresh);
        }
      } catch { /* ignore */ }
    }, 30_000);
    return () => clearInterval(id);
  }, []);

  // ⌘K opens command palette
  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault();
        setPaletteOpen((p) => !p);
      }
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, []);

  const handleUatSelect = useCallback(async (siruta: string | null) => {
    setSelectedUat(siruta);
    if (!siruta) {
      setUatDetail(null);
      return;
    }
    try {
      const res = await fetch(`/api/harta/uat/${siruta}`);
      const data = await res.json();
      setUatDetail(data);
    } catch (err) {
      console.error('UAT detail failed:', err);
    }
  }, []);

  const handleFilterChange = useCallback((next: Partial<MapFilters>) => {
    setFilters((prev) => ({ ...prev, ...next }));
  }, []);

  const handleYearChange = useCallback((year: YearFilter) => {
    setFilters((prev) => ({ ...prev, year }));
  }, []);

  const handleMetricChange = useCallback((metric: ChoroplethMetric) => {
    setFilters((prev) => ({ ...prev, metric }));
  }, []);

  const handleUatJump = useCallback((siruta: string) => {
    setFlyToSiruta(siruta);
    handleUatSelect(siruta);
  }, [handleUatSelect]);

  return (
    <div className="harta-app">
      {/* Top bar — minimal, floats above map */}
      <header className="harta-topbar">
        <div className="harta-topbar-left">
          <a href="/" className="harta-brand">
            <span>vreau</span><span className="harta-brand-accent">digital</span>
          </a>
          <div className="harta-divider" />
          <div className="harta-page-title">Harta Banilor Publici</div>
        </div>
        <div className="harta-topbar-right">
          <button onClick={() => setPaletteOpen(true)} className="harta-cmdk-trigger">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <circle cx="11" cy="11" r="8" />
              <line x1="21" y1="21" x2="16.65" y2="16.65" />
            </svg>
            <span>caută, filtrează</span>
            <kbd className="harta-kbd-inline">⌘K</kbd>
          </button>
        </div>
      </header>

      {/* Metric switcher */}
      <div className="harta-metric-bar">
        <MetricSwitcher metric={filters.metric} onChange={handleMetricChange} />
      </div>

      {/* Filter chips strip */}
      <div className="harta-chips-bar">
        <FilterChips filters={filters} onChange={handleFilterChange} />
      </div>

      {/* Map area */}
      <div className="harta-map-wrap">
        {loading && <LoadingOverlay />}

        <MapView
          choroplethData={choroplethData}
          metricData={metricData}
          metric={filters.metric}
          onUatSelect={handleUatSelect}
          selectedUat={selectedUat}
          flyToSiruta={flyToSiruta}
          onMapReady={(m) => { mapRef.current = m; }}
        />

        <PulseLayer map={mapRef.current} newItems={newPulses} />

        <FlowLayer map={mapRef.current} selectedUat={selectedUat} />

        {/* Right floating column */}
        <aside className={`harta-rail ${columnCollapsed ? 'is-collapsed' : ''}`}>
          <button
            onClick={() => setColumnCollapsed((c) => !c)}
            className="harta-rail-toggle"
            aria-label={columnCollapsed ? 'Deschide panoul' : 'Restrânge panoul'}
          >
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              {columnCollapsed
                ? <polyline points="15 18 9 12 15 6" />
                : <polyline points="9 18 15 12 9 6" />}
            </svg>
          </button>
          {!columnCollapsed && (
            <div className="harta-rail-inner">
              {selectedUat && uatDetail
                ? <UatDetailPanel detail={uatDetail} onClose={() => handleUatSelect(null)} />
                : <NationalPanel national={nationalStats} counties={countyStats} />}

              <ActivityStream items={feedItems} onItemClick={() => {}} />
            </div>
          )}
        </aside>

        {/* Bottom timeline */}
        <div className="harta-timeline-wrap">
          <TimelineScrubber year={filters.year} onChange={handleYearChange} />
        </div>
      </div>

      <CommandPalette
        open={paletteOpen}
        onClose={() => setPaletteOpen(false)}
        uats={choroplethData}
        year={filters.year}
        onYearChange={handleYearChange}
        onUatJump={handleUatJump}
      />
    </div>
  );
}

function LoadingOverlay() {
  return (
    <div className="harta-loading">
      <div className="harta-loading-card">
        <div className="harta-loading-pulse" />
        <div className="harta-loading-text">Se încarcă harta…</div>
      </div>
    </div>
  );
}
