/**
 * LeafletMapInner Component
 * Internal Leaflet map implementation (client-side only)
 */

'use client';

import { useEffect, useRef } from 'react';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import type { School } from '@/lib/types';
import { schoolUrl } from '@/lib/utils';

// Fix for default marker icons in Next.js
delete (L.Icon.Default.prototype as any)._getIconUrl;
L.Icon.Default.mergeOptions({
  iconRetinaUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png',
  iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png',
  shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png',
});

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

// ---------------------------------------------------------------------------
// Popup helpers (must work in plain JS string templates — no React / CSS Modules)
// ---------------------------------------------------------------------------

function escapeHtml(s: string): string {
  return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}

interface PopupBadge {
  label: string;
  style: string;
}

function buildPopupBadge(school: School): PopupBadge {
  // A report card wins over any carried-forward legacy grade — its presence is
  // signalled by ofsted_rc_date (the list has no full report_card object, and
  // ofsted_framework is the raw event grouping, never "ReportCard").
  if (school.ofsted_rc_date) {
    const rcYear = new Date(school.ofsted_rc_date).getFullYear();
    return { label: `Report Card · ${rcYear}`, style: 'background:var(--phase-secondary-text);color:var(--text-inverse)' };
  }
  const year = school.ofsted_date ? new Date(school.ofsted_date).getFullYear() : null;
  const yearStr = year ? ` · ${year}` : '';
  if (school.ofsted_grade) {
    const labels: Record<number, string> = { 1: 'Outstanding', 2: 'Good', 3: 'Req. Improvement', 4: 'Inadequate' };
    const colours: Record<number, string> = {
      1: 'background:var(--status-above-bg);color:var(--status-above)',
      2: 'background:var(--status-above-bg);color:var(--status-above)',
      3: 'background:var(--status-below-bg);color:var(--status-below)',
      4: 'background:var(--status-below);color:var(--text-inverse)',
    };
    return { label: `${labels[school.ofsted_grade]}${yearStr}`, style: colours[school.ofsted_grade] };
  }
  return { label: 'Not yet inspected', style: 'background:var(--bg-secondary);color:var(--text-muted)' };
}

export default function LeafletMapInner({ schools, center, zoom, referencePoint, onMarkerClick, nationalAvgRwm, laAverages }: LeafletMapInnerProps) {
  const mapRef = useRef<L.Map | null>(null);
  const mapContainerRef = useRef<HTMLDivElement>(null);
  const refMarkerRef = useRef<L.Marker | null>(null);

  useEffect(() => {
    if (!mapContainerRef.current) return;

    // Initialize map
    if (!mapRef.current) {
      mapRef.current = L.map(mapContainerRef.current).setView(center, zoom);

      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
        maxZoom: 19,
      }).addTo(mapRef.current);
    }

    // Clear existing school markers (not the reference pin)
    mapRef.current.eachLayer((layer) => {
      if (layer instanceof L.Marker && layer !== refMarkerRef.current) {
        mapRef.current!.removeLayer(layer);
      }
    });

    // Add reference pin (search location)
    if (refMarkerRef.current) {
      refMarkerRef.current.remove();
      refMarkerRef.current = null;
    }
    if (referencePoint && mapRef.current) {
      const refIcon = L.divIcon({
        html: `<div style="
          width: 20px; height: 20px;
          background: var(--brand);
          border: 3px solid white;
          border-radius: 50%;
          box-shadow: 0 2px 8px rgba(0,0,0,0.35);
        "></div>`,
        iconSize: [20, 20],
        iconAnchor: [10, 10],
        className: '',
      });
      refMarkerRef.current = L.marker(referencePoint, { icon: refIcon, zIndexOffset: 1000 })
        .addTo(mapRef.current)
        .bindPopup('<strong>Search location</strong>');
    }

    // Add markers for schools
    schools.forEach((school) => {
      if (school.latitude && school.longitude && mapRef.current) {
        const marker = L.marker([school.latitude, school.longitude]).addTo(mapRef.current);

        // Create popup content
        const badge = buildPopupBadge(school);
        const isSecondary = school.attainment_8_score != null;

        // Phase label
        const rawPhase = (school.phase ?? '').toLowerCase();
        const phaseLabel =
          rawPhase.includes('secondary') ? 'Secondary' :
          rawPhase === 'all-through' ? 'All-through' :
          rawPhase.includes('primary') ? 'Primary' :
          isSecondary ? 'Secondary' : 'Primary';

        // Distance string
        const distanceStr =
          school.distance != null ? ` · ${school.distance.toFixed(1)} mi` : '';

        // Headline metric
        let metricHtml = '';
        if (isSecondary) {
          const score = school.attainment_8_score!;
          const laAvg = school.local_authority ? (laAverages?.[school.local_authority] ?? null) : null;
          let deltaLine = '';
          if (laAvg != null) {
            const diff = Math.round((score - laAvg) * 10) / 10;
            const sign = diff >= 0 ? '+' : '';
            // Att8 scores range 0–90 in 0.1 increments; ±0.5 is meaningful here
            // vs primary RWM % where ±2 pts is the threshold
            const colour = diff >= 0.5 ? 'var(--status-above)' : diff <= -0.5 ? 'var(--brand)' : 'var(--text-muted)';
            const laName = escapeHtml(school.local_authority ?? 'LA');
            deltaLine = `<div style="font-size:11px;font-weight:600;color:${colour}">${sign}${diff} vs ${laName} avg</div>`;
          }
          metricHtml = `<div style="margin-bottom:4px">
  <span style="font-size:20px;font-weight:700;color:var(--text-primary);font-family:Georgia,serif">${score.toFixed(1)}</span>
  <span style="font-size:11px;color:var(--text-muted);margin-left:4px">Attainment 8</span>
  ${deltaLine}
</div>`;
        } else if (school.rwm_expected_pct != null) {
          const rwm = school.rwm_expected_pct;
          let deltaLine = '';
          if (nationalAvgRwm != null) {
            const diff = Math.round(rwm - nationalAvgRwm);
            const colour = diff >= 2 ? 'var(--status-above)' : diff <= -2 ? 'var(--brand)' : 'var(--text-muted)';
            const text =
              diff >= 2 ? `+${diff} pts vs national` :
              diff <= -2 ? `${diff} pts vs national` :
              '≈ national avg';
            deltaLine = `<div style="font-size:11px;font-weight:600;color:${colour}">${text}</div>`;
          }
          metricHtml = `<div style="margin-bottom:4px">
  <span style="font-size:20px;font-weight:700;color:var(--text-primary);font-family:Georgia,serif">${rwm}%</span>
  <span style="font-size:11px;color:var(--text-muted);margin-left:4px">Reading, Writing &amp; Maths</span>
  ${deltaLine}
</div>`;
        }

        const slug = schoolUrl(school.urn, school.school_name);

        const popupContent = `<div style="font-family:system-ui,sans-serif;min-width:240px;max-width:280px;padding:0">
  <div style="display:flex;justify-content:space-between;align-items:flex-start;gap:8px;margin-bottom:6px">
    <strong style="font-size:13px;color:var(--text-primary);line-height:1.3">${escapeHtml(school.school_name)}</strong>
    <span style="font-size:10px;font-weight:700;padding:2px 6px;border-radius:3px;white-space:nowrap;flex-shrink:0;${badge.style}">${badge.label}</span>
  </div>
  <div style="font-size:11px;color:var(--text-muted);margin-bottom:8px">
    ${phaseLabel}${school.local_authority ? ` · ${escapeHtml(school.local_authority)}` : ''}${distanceStr}
  </div>
  ${metricHtml}
  <a href="${slug}" style="display:block;text-align:center;padding:6px;background:var(--status-above);color:white;border-radius:5px;text-decoration:none;font-size:12px;font-weight:600;margin-top:8px">View Details →</a>
</div>`;

        marker.bindPopup(popupContent);

        if (onMarkerClick) {
          marker.on('click', () => onMarkerClick(school));
        }
      }
    });

    // Update map view
    if (schools.length > 1) {
      const bounds = L.latLngBounds(
        schools
          .filter(s => s.latitude && s.longitude)
          .map(s => [s.latitude!, s.longitude!] as [number, number])
      );
      mapRef.current.fitBounds(bounds, { padding: [50, 50] });
    } else {
      mapRef.current.setView(center, zoom);
    }

    // Cleanup
    return () => {
      // Don't destroy map on every update, just clean markers
    };
  }, [schools, center, zoom, referencePoint, onMarkerClick, nationalAvgRwm, laAverages]);

  // Cleanup map on unmount
  useEffect(() => {
    return () => {
      if (mapRef.current) {
        mapRef.current.remove();
        mapRef.current = null;
      }
    };
  }, []);

  return <div ref={mapContainerRef} style={{ width: '100%', height: '100%' }} />;
}
