/**
 * SchoolHeroMap
 * The location map that sits atop the school-detail hero. Shows a static
 * preview (pin + tiles) that blends down into the title; the whole band — or
 * the parent's "View on map" link, via the imperative `open()` handle — expands
 * it to a fullscreen, interactive map.
 */

'use client';

import dynamic from 'next/dynamic';
import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
import styles from './SchoolHeroMap.module.css';

const LeafletHeroMap = dynamic(() => import('./LeafletHeroMapInner'), {
  ssr: false,
  loading: () => <div className={styles.skeleton} aria-hidden="true" />,
});

export interface SchoolHeroMapHandle {
  open: () => void;
}

interface SchoolHeroMapProps {
  lat: number;
  lng: number;
}

export const SchoolHeroMap = forwardRef<SchoolHeroMapHandle, SchoolHeroMapProps>(
  function SchoolHeroMap({ lat, lng }, ref) {
    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;

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

    useImperativeHandle(ref, () => ({ open }), [open]);

    useEffect(() => {
      const onChange = () => setNativeFullscreen(!!document.fullscreenElement);
      document.addEventListener('fullscreenchange', onChange);
      return () => document.removeEventListener('fullscreenchange', onChange);
    }, []);

    // The fallback overlay sits on top of the page rather than replacing it,
    // so lock body scroll while it is up.
    useEffect(() => {
      if (!fallbackFullscreen) return;
      const prev = document.body.style.overflow;
      document.body.style.overflow = 'hidden';
      return () => { document.body.style.overflow = prev; };
    }, [fallbackFullscreen]);

    return (
      <div
        ref={wrapperRef}
        className={styles.wrapper}
        data-fullscreen={isFullscreen || undefined}
        data-fs-fallback={fallbackFullscreen || undefined}
      >
        <LeafletHeroMap lat={lat} lng={lng} interactive={isFullscreen} />

        {isFullscreen ? (
          <button type="button" className={styles.closeBtn} onClick={close} aria-label="Close map">
            <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M18 6 6 18M6 6l12 12" />
            </svg>
          </button>
        ) : (
          <>
            {/* Whole-band click target that opens the full map. */}
            <button type="button" className={styles.openBtn} onClick={open} aria-label="Open full map">
              <span className={styles.openHint}>
                <svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" />
                </svg>
                Open full map
              </span>
            </button>
            {/* Diffuse blend into the hero body below. */}
            <div className={styles.fade} aria-hidden="true" />
          </>
        )}
      </div>
    );
  },
);
