import { useState, useEffect, useCallback, useMemo } from 'react';
import { trackPageview } from './hooks/usePlausible';
import MapPage from './components/map/MapPage';
import DataSourcesPage from './components/data-sources/DataSourcesPage';
import FAQPage from './components/faq/FAQPage';
import HomePage from './components/home/HomePage';
import Header, { type Page } from './components/ui/Header';
import type { FeatureMeta, FeatureGroup, POICategoriesResponse, POICategoryGroup } from './types';
import { fetchWithRetry, apiUrl } from './lib/api';
import { parseUrlState } from './lib/url-state';
import { INITIAL_VIEW_STATE } from './lib/consts';
import { useTheme } from './hooks/useTheme';

declare global {
  interface Window {
    __og_ready?: boolean;
  }
}

export default function App() {
  const urlState = useMemo(() => parseUrlState(), []);
  const initialViewState = useMemo(() => urlState.viewState || INITIAL_VIEW_STATE, []);

  const isScreenshotMode = useMemo(() => {
    const params = new URLSearchParams(window.location.search);
    return params.get('screenshot') === '1';
  }, []);

  // Core data
  const [features, setFeatures] = useState<FeatureMeta[]>([]);
  const [poiCategoryGroups, setPOICategoryGroups] = useState<POICategoryGroup[]>([]);
  const [initialLoading, setInitialLoading] = useState(true);

  // UI state
  const [pendingInfoFeature, setPendingInfoFeature] = useState<string | null>(null);
  const [activePage, setActivePage] = useState<Page>(() => {
    if (isScreenshotMode) return 'dashboard';
    if (window.history.state?.page) return window.history.state.page;
    const params = new URLSearchParams(window.location.search);
    return params.has('v') || params.has('f') || params.has('poi') || params.has('tab')
      ? 'dashboard'
      : 'home';
  });

  const { theme, toggleTheme } = useTheme();

  // Load features and POI categories on mount
  useEffect(() => {
    const controller = new AbortController();
    let featuresLoaded = false;
    let poisLoaded = false;

    const checkDone = () => {
      if (featuresLoaded && poisLoaded) setInitialLoading(false);
    };

    fetchWithRetry<{ groups: FeatureGroup[] }>(
      apiUrl('features'),
      (json) => {
        const flat: FeatureMeta[] = json.groups.flatMap((g) =>
          g.features.map((f) => ({ ...f, group: g.name }))
        );
        setFeatures(flat);
        featuresLoaded = true;
        checkDone();
      },
      controller.signal
    );

    fetchWithRetry<POICategoriesResponse>(
      apiUrl('poi-categories'),
      (json) => {
        setPOICategoryGroups(json.groups);
        poisLoaded = true;
        checkDone();
      },
      controller.signal
    );

    return () => controller.abort();
  }, []);

  // Screenshot mode ready signal
  useEffect(() => {
    if (isScreenshotMode && !initialLoading && features.length > 0) {
      window.__og_ready = true;
    }
  }, [isScreenshotMode, initialLoading, features]);

  // Navigation
  const navigateTo = useCallback((page: Page, hash?: string, infoFeature?: string) => {
    if (infoFeature) {
      window.history.replaceState({ ...window.history.state, infoFeature }, '');
    }
    const url = hash
      ? `${window.location.pathname}${window.location.search}#${hash}`
      : `${window.location.pathname}${window.location.search}`;
    window.history.pushState({ page }, '', url);
    setActivePage(page);
    trackPageview();
  }, []);

  useEffect(() => {
    if (!window.history.state?.page) {
      window.history.replaceState({ page: activePage }, '');
    }
    const handlePopState = (e: PopStateEvent) => {
      if (e.state?.page) {
        setActivePage(e.state.page);
        if (e.state.infoFeature) {
          setPendingInfoFeature(e.state.infoFeature);
        }
      }
    };
    window.addEventListener('popstate', handlePopState);
    return () => window.removeEventListener('popstate', handlePopState);
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  if (isScreenshotMode) {
    return (
      <MapPage
        features={features}
        poiCategoryGroups={poiCategoryGroups}
        initialFilters={urlState.filters || {}}
        initialViewState={initialViewState}
        initialPOICategories={urlState.poiCategories || new Set()}
        initialTab={urlState.tab || 'pois'}
        initialLoading={initialLoading}
        theme={theme}
        pendingInfoFeature={null}
        onClearPendingInfoFeature={() => {}}
        onNavigateTo={() => {}}
        screenshotMode
      />
    );
  }

  return (
    <div className="h-screen flex flex-col">
      <Header
        activePage={activePage}
        onPageChange={navigateTo}
        theme={theme}
        onToggleTheme={toggleTheme}
      />
      {activePage === 'home' ? (
        <HomePage onOpenDashboard={() => navigateTo('dashboard')} theme={theme} />
      ) : activePage === 'data-sources' ? (
        <DataSourcesPage />
      ) : activePage === 'faq' ? (
        <FAQPage />
      ) : (
        <MapPage
          features={features}
          poiCategoryGroups={poiCategoryGroups}
          initialFilters={urlState.filters || {}}
          initialViewState={initialViewState}
          initialPOICategories={urlState.poiCategories || new Set()}
          initialTab={urlState.tab || 'pois'}
          initialLoading={initialLoading}
          theme={theme}
          pendingInfoFeature={pendingInfoFeature}
          onClearPendingInfoFeature={() => setPendingInfoFeature(null)}
          onNavigateTo={navigateTo}
        />
      )}
    </div>
  );
}
