/**
 * SchoolMap Component
 * Client-side Leaflet map wrapper for displaying school locations
 */

'use client';

import dynamic from 'next/dynamic';
import { useRef, useState, useEffect, useCallback } from 'react';
import type { School } from '@/lib/types';
import styles from './SchoolMap.module.css';

// Dynamic import to avoid SSR issues with Leaflet
const LeafletMap = dynamic(() => import('./LeafletMapInner'), {
  ssr: false,
  loading: () => (
    <div className={styles.mapLoading}>
      <div className={styles.spinner}></div>
      <p>Loading map...</p>
    </div>
  ),
});

interface SchoolMapProps {
  schools: School[];
  center?: [number, number];
  zoom?: number;
  referencePoint?: [number, number];
  onMarkerClick?: (school: School) => void;
  nationalAvgRwm?: number | null;
  laAverages?: Record<string, number | null>;
}

export function SchoolMap({ schools, center, zoom = 13, referencePoint, onMarkerClick, nationalAvgRwm, laAverages }: SchoolMapProps) {
  const wrapperRef = useRef<HTMLDivElement>(null);
  const [nativeFullscreen, setNativeFullscreen] = useState(false);
  // iOS Safari has no Element.requestFullscreen — fall back to a fixed-position
  // overlay driven by state instead of the Fullscreen API.
  const [fallbackFullscreen, setFallbackFullscreen] = useState(false);
  const isFullscreen = nativeFullscreen || fallbackFullscreen;

  // Sync state with browser fullscreen events (e.g. Escape key)
  useEffect(() => {
    const onFsChange = () => setNativeFullscreen(!!document.fullscreenElement);
    document.addEventListener('fullscreenchange', onFsChange);
    return () => document.removeEventListener('fullscreenchange', onFsChange);
  }, []);

  // Lock body scroll while the fallback overlay is up.
  useEffect(() => {
    if (!fallbackFullscreen) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { document.body.style.overflow = prev; };
  }, [fallbackFullscreen]);

  // Leaflet re-measures on window resize (trackResize). Native fullscreen fires
  // one; the CSS fallback overlay changes size without a resize event, so nudge
  // Leaflet after the layout settles or the map fills only part of the screen.
  useEffect(() => {
    const id = requestAnimationFrame(() => window.dispatchEvent(new Event('resize')));
    return () => cancelAnimationFrame(id);
  }, [isFullscreen]);

  const toggleFullscreen = useCallback(() => {
    if (document.fullscreenElement) {
      document.exitFullscreen().catch(() => {});
      return;
    }
    if (fallbackFullscreen) {
      setFallbackFullscreen(false);
      return;
    }
    const el = wrapperRef.current;
    if (!el) return;
    if (el.requestFullscreen) {
      el.requestFullscreen().catch(() => setFallbackFullscreen(true));
    } else {
      setFallbackFullscreen(true);
    }
  }, [fallbackFullscreen]);

  // Calculate center if not provided
  const mapCenter: [number, number] = center || (() => {
    if (schools.length === 0) return [51.5074, -0.1278];
    if (schools.length === 1 && schools[0].latitude && schools[0].longitude) {
      return [schools[0].latitude, schools[0].longitude];
    }
    const validSchools = schools.filter(s => s.latitude && s.longitude);
    if (validSchools.length === 0) return [51.5074, -0.1278];
    const avgLat = validSchools.reduce((sum, s) => sum + (s.latitude || 0), 0) / validSchools.length;
    const avgLng = validSchools.reduce((sum, s) => sum + (s.longitude || 0), 0) / validSchools.length;
    return [avgLat, avgLng];
  })();

  return (
    <div ref={wrapperRef} className={`${styles.mapWrapper} ${isFullscreen ? styles.fullscreen : ''} ${fallbackFullscreen ? styles.fsFallback : ''}`}>
      <button
        className={styles.fullscreenBtn}
        onClick={toggleFullscreen}
        title={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}
        aria-label={isFullscreen ? 'Exit fullscreen' : 'View map fullscreen'}
      >
        {isFullscreen ? (
          /* Compress icon */
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" width="18" height="18" strokeLinecap="round" strokeLinejoin="round">
            <path d="M8 3v3a2 2 0 0 1-2 2H3"/><path d="M21 8h-3a2 2 0 0 1-2-2V3"/>
            <path d="M3 16h3a2 2 0 0 1 2 2v3"/><path d="M16 21v-3a2 2 0 0 1 2-2h3"/>
          </svg>
        ) : (
          /* Expand icon */
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" width="18" height="18" strokeLinecap="round" strokeLinejoin="round">
            <path d="M8 3H5a2 2 0 0 0-2 2v3"/><path d="M21 8V5a2 2 0 0 0-2-2h-3"/>
            <path d="M3 16v3a2 2 0 0 0 2 2h3"/><path d="M16 21h3a2 2 0 0 0 2-2v-3"/>
          </svg>
        )}
      </button>
      <LeafletMap
        schools={schools}
        center={mapCenter}
        zoom={zoom}
        referencePoint={referencePoint}
        onMarkerClick={onMarkerClick}
        nationalAvgRwm={nationalAvgRwm}
        laAverages={laAverages}
      />
    </div>
  );
}
