import React, { useEffect, useRef } from 'react';
import { MapContainer, TileLayer, Marker, Polyline, Polygon, Tooltip, useMap } from 'react-leaflet';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import { useTheme } from '../../context/ThemeContext';
import { DISPATCH_REPS, DISPATCH_RECOMMENDATIONS } from '../../data/mockStore';

// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
const PLANO_CENTER = [33.055, -96.752];
const DEFAULT_ZOOM = 12;

const REP_STATUS_COLORS  = { available: '#10B981', en_route: '#3B82F6', busy: '#F59E0B' };
const REP_STATUS_LABELS  = { available: 'Available', en_route: 'En Route', busy: 'Busy' };
const URGENCY_COLORS     = { emergency: '#EF4444', high: '#F59E0B', standard: '#6B7280' };

// Storm polygon — northeast Plano, sweeping toward central
const STORM_POLYGON = [
    [33.105, -96.745], [33.100, -96.695], [33.078, -96.682],
    [33.051, -96.698], [33.042, -96.725], [33.058, -96.750],
    [33.080, -96.758],
];

// ---------------------------------------------------------------------------
// Custom marker factories
// ---------------------------------------------------------------------------
const createRepIcon = (rep, isTopPick) => {
    const color = REP_STATUS_COLORS[rep.status] || '#6B7280';
    const size  = isTopPick ? 42 : 36;
    const ring  = isTopPick
        ? `<div style="position:absolute;inset:-5px;border-radius:50%;border:2px solid ${color};opacity:0.5;animation:repRing 1.6s ease-out infinite;"></div>`
        : '';
    return L.divIcon({
        html: `
            <div style="position:relative;width:${size}px;height:${size}px;">
                ${ring}
                <div style="
                    width:${size}px;height:${size}px;border-radius:50%;
                    background:${color}DD;border:2.5px solid white;
                    display:flex;align-items:center;justify-content:center;
                    font-size:${isTopPick ? 12 : 11}px;font-weight:900;color:white;
                    font-family:system-ui,sans-serif;
                    box-shadow:0 3px 10px ${color}60,0 1px 3px rgba(0,0,0,0.25);
                    transition:transform 0.2s;
                ">${rep.initials}</div>
                <div style="
                    position:absolute;bottom:-3px;right:-3px;
                    width:10px;height:10px;border-radius:50%;
                    background:${color};border:2px solid white;
                "></div>
            </div>`,
        className: '',
        iconSize:   [size, size],
        iconAnchor: [size / 2, size / 2],
    });
};

const createLeadIcon = (lead, isSelected) => {
    const color = URGENCY_COLORS[lead.urgency] || '#6B7280';
    const size  = isSelected ? 22 : 14;
    const pulse = lead.urgency !== 'standard';
    const radar = isSelected
        ? `<div style="position:absolute;inset:-7px;border-radius:50%;border:2px solid ${color};animation:radarPing 1.4s ease-out infinite;"></div>
           <div style="position:absolute;inset:-14px;border-radius:50%;border:1.5px solid ${color};animation:radarPing 1.4s ease-out 0.4s infinite;"></div>`
        : '';

    return L.divIcon({
        html: `
            <div style="position:relative;width:${size}px;height:${size}px;${pulse && !isSelected ? 'animation:dotPulse 1.6s ease-in-out infinite;' : ''}">
                ${radar}
                <div style="
                    width:${size}px;height:${size}px;border-radius:50%;
                    background:${color};border:2px solid white;
                    box-shadow:0 2px 6px ${color}80;
                "></div>
            </div>`,
        className: '',
        iconSize:   [size, size],
        iconAnchor: [size / 2, size / 2],
    });
};

const createTravelChipIcon = (text, color) => {
    const label = `&#x23F1;&nbsp;${text}`;
    return L.divIcon({
        html: `
            <div style="
                background:${color};
                border-radius:999px;
                padding:7px 16px;
                font-size:15px;
                font-weight:900;
                color:#ffffff;
                box-shadow:0 4px 16px rgba(0,0,0,0.45), 0 0 0 3px white, 0 0 0 5px ${color};
                white-space:nowrap;
                font-family:system-ui,sans-serif;
                letter-spacing:0.2px;
                text-shadow:0 1px 3px rgba(0,0,0,0.35);
                pointer-events:none;
            ">${label}</div>`,
        className: '',
        iconAnchor: [56, 20],
    });
};

// ---------------------------------------------------------------------------
// MapController — fits bounds when lead selection changes + fixes tile gaps
// ---------------------------------------------------------------------------
const MapController = ({ selectedLeadId, leadPos, repPos, routePath }) => {
    const map    = useMap();
    const prevId = useRef(null);

    // Invalidate size on mount and on every window resize so Leaflet fills
    // the full flex container — prevents the blank tile area on the right.
    // On mobile the map panel is inside a CollapsePanel that animates
    // height 0→auto over 220ms, so we need to wait past that before calling
    // invalidateSize, otherwise Leaflet initialises at near-zero height.
    useEffect(() => {
        const invalidate = () => map.invalidateSize({ animate: false });
        // 50ms covers desktop (no animation). 320ms covers the 220ms collapse
        // animation with margin so tiles fill correctly on mobile/tablet.
        const t1 = setTimeout(invalidate, 50);
        const t2 = setTimeout(invalidate, 320);
        window.addEventListener('resize', invalidate);
        return () => {
            clearTimeout(t1);
            clearTimeout(t2);
            window.removeEventListener('resize', invalidate);
        };
    }, [map]);

    useEffect(() => {
        if (selectedLeadId === prevId.current) return;
        prevId.current = selectedLeadId;

        if (!leadPos || !repPos) return;

        const positions = [leadPos, repPos, ...(routePath || [])].filter(Boolean);
        if (positions.length < 2) return;

        map.fitBounds(L.latLngBounds(positions), {
            padding:  [72, 72],
            maxZoom:  14,
            animate:  true,
            duration: 0.7,
        });
    }, [selectedLeadId]);   // eslint-disable-line react-hooks/exhaustive-deps

    return null;
};

// ---------------------------------------------------------------------------
// CSS animations — injected as a style block
// ---------------------------------------------------------------------------
const MAP_STYLES = `
    .dispatch-route {
        stroke-dasharray: 5000;
        stroke-dashoffset: 5000;
        animation: drawRoute 1.1s cubic-bezier(0.4,0,0.2,1) forwards;
    }
    @keyframes drawRoute {
        to { stroke-dashoffset: 0; }
    }
    @keyframes radarPing {
        0%   { transform: scale(1); opacity: 0.75; }
        100% { transform: scale(1); opacity: 0; }
        0%   { transform: scale(1); }
        100% { transform: scale(2.4); opacity: 0; }
    }
    @keyframes dotPulse {
        0%, 100% { transform: scale(1);   opacity: 1; }
        50%       { transform: scale(1.3); opacity: 0.7; }
    }
    @keyframes repRing {
        0%   { transform: scale(1); opacity: 0.6; }
        100% { transform: scale(1.8); opacity: 0; }
    }
    .leaflet-container { font-family: system-ui, sans-serif; }
    .dispatch-tooltip {
        background: white;
        border: 1px solid rgba(0,0,0,0.08);
        border-radius: 10px;
        box-shadow: 0 4px 16px rgba(0,0,0,0.12);
        padding: 8px 10px;
        pointer-events: none;
    }
    .dispatch-tooltip::before { display: none; }
    .leaflet-tooltip.dispatch-tooltip { white-space: nowrap; }
`;

// ---------------------------------------------------------------------------
// Main Component
// ---------------------------------------------------------------------------
const DispatchMapPanel = ({ selectedLead, dispatchLeads, reps = DISPATCH_REPS, stormMode, accent, isDesktop, mapHeight }) => {
    const { theme } = useTheme();

    // Top recommendation for the selected lead
    const topRec = selectedLead ? (DISPATCH_RECOMMENDATIONS[selectedLead.id]?.[0] ?? null) : null;
    const topRep = topRec ? reps.find(r => r.id === topRec.repId) : null;

    // Positions for bounds fitting
    const leadPos = selectedLead
        ? [selectedLead.property.lat, selectedLead.property.lng]
        : null;
    const repPos = topRep
        ? [topRep.currentLat, topRep.currentLng]
        : null;

    // Travel time chip — midpoint of route
    const routeMid = topRec?.routePath?.length
        ? topRec.routePath[Math.floor(topRec.routePath.length / 2)]
        : null;

    // Derive estimated drive minutes from top rec factors (driveTime score → minutes)
    const driveMinutes = topRec
        ? Math.round(8 + ((100 - topRec.factors.driveTime) / 100) * 22)
        : null;

    const routeColor = stormMode ? '#F59E0B' : accent;

    // Explicit pixel height on both the wrapper div and MapContainer.
    // Do NOT use h-full / height:100% — the CollapsePanel ancestor has
    // height:auto so the percentage chain resolves to 0. Inline px values
    // bypass the chain entirely and give Leaflet a reliable offsetHeight.
    // mapHeight prop is computed responsively in LynkDispatchPage (300–520px).
    const mapH = isDesktop ? 'calc(72rem + 2.375rem)' : (mapHeight || '300px');

    return (
        <div className="relative overflow-hidden" style={{ height: mapH }}>
            {/* Inject map animations */}
            <style>{MAP_STYLES}</style>

            <MapContainer
                center={PLANO_CENTER}
                zoom={DEFAULT_ZOOM}
                scrollWheelZoom={true}
                zoomControl={false}
                className="w-full"
                style={{ height: mapH, width: '100%' }}
            >
                {/* Tile layer — dark/light aware */}
                <TileLayer
                    key={theme}
                    attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                    className={
                        theme === 'dark'
                            ? 'map-tiles filter invert grayscale contrast-100'
                            : 'map-tiles'
                    }
                />

                {/* Fit bounds on lead selection */}
                <MapController
                    selectedLeadId={selectedLead?.id}
                    leadPos={leadPos}
                    repPos={repPos}
                    routePath={topRec?.routePath}
                />

                {/* Storm polygon */}
                {stormMode && (
                    <Polygon
                        positions={STORM_POLYGON}
                        pathOptions={{
                            color:       '#F59E0B',
                            fillColor:   '#F59E0B',
                            fillOpacity: 0.13,
                            weight:      2,
                            dashArray:   '6 5',
                            opacity:     0.7,
                        }}
                    />
                )}

                {/* Route polyline — animates in with stroke-dashoffset draw */}
                {topRec && (
                    <Polyline
                        key={selectedLead.id}
                        positions={topRec.routePath}
                        pathOptions={{
                            color:     routeColor,
                            weight:    3.5,
                            opacity:   0.85,
                            className: 'dispatch-route',
                            lineCap:   'round',
                            lineJoin:  'round',
                        }}
                    />
                )}

                {/* Lead pins */}
                {dispatchLeads.map(lead => {
                    const urgColor   = URGENCY_COLORS[lead.urgency] || '#6B7280';
                    const notesSnip  = lead.notes
                        ? (lead.notes.length > 55 ? lead.notes.slice(0, 55) + '…' : lead.notes)
                        : null;
                    return (
                        <Marker
                            key={lead.id}
                            position={[lead.property.lat, lead.property.lng]}
                            icon={createLeadIcon(lead, selectedLead?.id === lead.id)}
                        >
                            <Tooltip direction="top" offset={[0, -10]} opacity={1} className="dispatch-tooltip">
                                <div style={{ fontFamily: 'system-ui,sans-serif', minWidth: 150, maxWidth: 220 }}>
                                    <p style={{ fontSize: 11, fontWeight: 700, color: '#18181b', marginBottom: 2 }}>
                                        {lead.customer.name}
                                    </p>
                                    <p style={{ fontSize: 10, fontWeight: 700, color: urgColor, marginBottom: 2 }}>
                                        {lead.urgency.toUpperCase()}
                                    </p>
                                    <p style={{ fontSize: 10, color: '#71717a', marginBottom: notesSnip ? 4 : 0 }}>
                                        {lead.property.address}
                                    </p>
                                    {notesSnip && (
                                        <p style={{ fontSize: 9, color: '#a1a1aa', fontStyle: 'italic', lineHeight: 1.4, borderTop: '1px solid #f0f0f0', paddingTop: 4 }}>
                                            {notesSnip}
                                        </p>
                                    )}
                                </div>
                            </Tooltip>
                        </Marker>
                    );
                })}

                {/* Rep markers */}
                {reps.map(rep => {
                    const repColor = REP_STATUS_COLORS[rep.status] || '#6B7280';
                    return (
                        <Marker
                            key={rep.id}
                            position={[rep.currentLat, rep.currentLng]}
                            icon={createRepIcon(rep, topRep?.id === rep.id)}
                        >
                            <Tooltip direction="top" offset={[0, -10]} opacity={1} className="dispatch-tooltip">
                                <div style={{ fontFamily: 'system-ui,sans-serif', minWidth: 140 }}>
                                    <p style={{ fontSize: 11, fontWeight: 800, color: repColor, marginBottom: 3 }}>
                                        {rep.name}
                                    </p>
                                    <p style={{ fontSize: 10, color: '#71717a', marginBottom: 1 }}>
                                        {REP_STATUS_LABELS[rep.status]} · {rep.todayAppointments}/{rep.maxDaily} slots
                                    </p>
                                    <p style={{ fontSize: 10, color: '#71717a' }}>
                                        ★ {rep.rating} · {rep.closeRate}% close
                                    </p>
                                </div>
                            </Tooltip>
                        </Marker>
                    );
                })}

                {/* Travel time chip at route midpoint */}
                {topRec && routeMid && driveMinutes && (
                    <Marker
                        key={`chip-${selectedLead.id}`}
                        position={routeMid}
                        icon={createTravelChipIcon(`~${driveMinutes} min`, routeColor)}
                    />
                )}
            </MapContainer>

            {/* ── Legend overlay — bottom-left ── */}
            <div className="absolute bottom-3 left-3 z-[1000] flex flex-col gap-1.5 pointer-events-none">
                {/* Rep status legend */}
                <div className="rounded-xl border bg-white/90 dark:bg-zinc-900/85 backdrop-blur-md border-zinc-200/80 dark:border-white/[0.08] px-2.5 py-2 shadow-lg">
                    <p className="text-[9px] font-black uppercase tracking-widest text-zinc-400 dark:text-zinc-500 mb-1.5">Reps</p>
                    <div className="space-y-1">
                        {Object.entries(REP_STATUS_COLORS).map(([status, color]) => (
                            <div key={status} className="flex items-center gap-1.5">
                                <div className="w-2.5 h-2.5 rounded-full shrink-0" style={{ backgroundColor: color }} />
                                <span className="text-[10px] font-medium text-zinc-600 dark:text-zinc-300 capitalize">
                                    {REP_STATUS_LABELS[status]}
                                </span>
                                <span className="text-[10px] text-zinc-400 ml-1">
                                    {DISPATCH_REPS.filter(r => r.status === status).length}
                                </span>
                            </div>
                        ))}
                    </div>
                </div>

                {/* Lead urgency legend */}
                <div className="rounded-xl border bg-white/90 dark:bg-zinc-900/85 backdrop-blur-md border-zinc-200/80 dark:border-white/[0.08] px-2.5 py-2 shadow-lg">
                    <p className="text-[9px] font-black uppercase tracking-widest text-zinc-400 dark:text-zinc-500 mb-1.5">Leads</p>
                    <div className="space-y-1">
                        {Object.entries(URGENCY_COLORS).map(([urgency, color]) => (
                            <div key={urgency} className="flex items-center gap-1.5">
                                <div className="w-2.5 h-2.5 rounded-full shrink-0" style={{ backgroundColor: color }} />
                                <span className="text-[10px] font-medium text-zinc-600 dark:text-zinc-300 capitalize">
                                    {urgency}
                                </span>
                                <span className="text-[10px] text-zinc-400 ml-1">
                                    {dispatchLeads.filter(l => l.urgency === urgency).length}
                                </span>
                            </div>
                        ))}
                    </div>
                </div>
            </div>

            {/* Storm mode overlay label */}
            {stormMode && (
                <div className="absolute top-3 left-1/2 -translate-x-1/2 z-[1000] pointer-events-none">
                    <div className="flex items-center gap-1.5 px-3 py-1 rounded-full bg-amber-500/90 backdrop-blur-sm shadow-lg">
                        <span className="w-1.5 h-1.5 rounded-full bg-white animate-pulse" />
                        <span className="text-[10px] font-black uppercase tracking-widest text-white">
                            Storm Zone Active
                        </span>
                    </div>
                </div>
            )}

            {/* Selected lead info chip — top right */}
            {selectedLead && topRep && (
                <div className="absolute top-3 right-3 z-[1000] pointer-events-none">
                    <div
                        className="rounded-xl border px-3 py-2 bg-white/92 dark:bg-zinc-900/85 backdrop-blur-md shadow-lg border-zinc-200/80 dark:border-white/[0.08]"
                        style={{ borderLeftWidth: 3, borderLeftColor: routeColor }}
                    >
                        <p className="text-[9px] font-black uppercase tracking-widest mb-0.5" style={{ color: routeColor }}>
                            Route Active
                        </p>
                        <p className="text-[11px] font-bold text-zinc-900 dark:text-white">{topRep.name}</p>
                        <p className="text-[10px] text-zinc-400 mt-0.5 truncate max-w-[140px]">
                            → {selectedLead.property.address}
                        </p>
                    </div>
                </div>
            )}
        </div>
    );
};

export default DispatchMapPanel;
