// CorridorMap.jsx, Stylised Vietnam ⇄ Japan map used by the
// "find supplier by location" view. Pure SVG, hairline borders,
// follows JVFood visual language (no gradients, navy + sand).

const CM_VB_W = 1100;
const CM_VB_H = 560;

// Hand-traced country outlines, simplified, not cartographic.
// Use stroke-linejoin: round so the polyline corners read as smooth curves.
const VN_PATH = [
 "M 245 92",
 // east coast top → bottom
 "L 254 120 L 262 152 L 268 188 L 275 224 L 278 262 L 274 298",
 "L 268 332 L 258 364 L 244 392 L 224 418 L 200 442",
 "L 176 462 L 152 482 L 128 500 L 118 514",
 // mekong tip
 "L 122 520 L 140 508 L 158 492",
 // west border bottom → top
 "L 182 472 L 200 444 L 208 408 L 204 372 L 198 338",
 "L 198 302 L 206 268 L 200 232 L 208 196 L 218 158",
 "L 228 126 L 240 100 Z",
].join(" ");

// Japan: 4 separate paths so we can fill them as one country group.
const JP_HOKKAIDO = "M 868 78 C 912 72, 948 96, 952 132 C 956 168, 928 196, 894 200 C 858 204, 826 184, 820 154 C 814 122, 838 82, 868 78 Z";
const JP_HONSHU = [
 "M 765 408",
 "C 742 395, 758 376, 786 370",
 "C 812 364, 838 354, 850 336",
 "C 864 316, 880 308, 895 300",
 "C 914 292, 922 268, 918 240",
 "C 912 212, 894 200, 878 214",
 "C 862 230, 856 256, 850 282",
 "C 842 306, 826 326, 810 342",
 "C 792 360, 770 378, 750 392",
 "C 742 402, 754 412, 765 408 Z",
].join(" ");
const JP_KYUSHU = "M 715 412 C 740 408, 755 426, 750 446 C 744 464, 720 470, 704 462 C 688 454, 682 432, 692 418 C 700 410, 708 410, 715 412 Z";
const JP_SHIKOKU = "M 772 408 C 792 408, 800 418, 790 426 C 778 432, 760 430, 754 422 C 750 414, 762 408, 772 408 Z";

// Trade-lane bezier path between two points (curves north over the East China Sea)
const cmLanePath = (from, to) => {
 const dx = to.x - from.x;
 const cx1 = from.x + dx * 0.30;
 const cy1 = from.y - 120;
 const cx2 = from.x + dx * 0.70;
 const cy2 = to.y - 90;
 return `M ${from.x} ${from.y} C ${cx1} ${cy1}, ${cx2} ${cy2}, ${to.x} ${to.y}`;
};

const CorridorMap = ({
 locations, // DM_LOCATIONS
 lanes, // DM_LANES, list with from/to ids
 countsByCity, // { "Hai Phong": 1, "Tokyo": 2, ... }
 selectedRegion = "all",
 selectedCity = null,
 hoverCity = null,
 highlightedRegion = null, // hover state on region chips
 onCityHover,
 onCityClick,
 onBackgroundClick,
}) => {
 const locById = Object.fromEntries(locations.map(l => [l.id, l]));
 const isCityActive = (loc) => {
 if (selectedCity) return selectedCity === loc.id;
 if (hoverCity) return hoverCity === loc.id;
 if (highlightedRegion && highlightedRegion !== "all") return loc.region === highlightedRegion;
 if (selectedRegion !== "all") return loc.region === selectedRegion;
 return true; // unfiltered: all active
 };
 const isCityDimmed = (loc) => {
 if (selectedCity) return selectedCity !== loc.id;
 if (highlightedRegion && highlightedRegion !== "all") return loc.region !== highlightedRegion;
 if (selectedRegion !== "all") return loc.region !== selectedRegion;
 return false;
 };

 return (
 <div style={{
 position: "relative",
 background: "#fff",
 border: "1px solid var(--color-border)",
 borderRadius: 10,
 overflow: "hidden",
 }}>
 {/* corner labels */}
 <div style={{ position: "absolute", left: 20, top: 16, display: "flex", alignItems: "center", gap: 10, zIndex: 2 }}>
 <Eyebrow style={{ color: "var(--color-fg-muted)" }}>Vietnam ⇄ Japan corridor</Eyebrow>
 </div>
 <div style={{ position: "absolute", right: 20, top: 16, display: "flex", alignItems: "center", gap: 14, fontSize: 11, color: "var(--color-fg-muted)", zIndex: 2 }}>
 <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}><span style={{ width: 8, height: 8, borderRadius: 999, background: "var(--jv-navy-800)", border: "2px solid #fff", boxShadow: "0 0 0 1px var(--color-border)" }}/>Supplier hub</span>
 <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}><span style={{ width: 8, height: 8, borderRadius: 999, background: "var(--jv-accent-600)", border: "2px solid #fff", boxShadow: "0 0 0 1px var(--color-border)" }}/>Selected</span>
 <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}><svg width="22" height="6"><line x1="0" y1="3" x2="22" y2="3" stroke="var(--jv-navy-400)" strokeWidth="1.25" strokeDasharray="3 3"/></svg>Trade lane</span>
 </div>

 {/* compass / scale */}
 <div style={{ position: "absolute", left: 20, bottom: 20, display: "flex", alignItems: "center", gap: 8, fontSize: 11, color: "var(--color-fg-muted)", fontFamily: "var(--font-mono)", zIndex: 2 }}>
 <svg width="14" height="14" viewBox="0 0 14 14" style={{ overflow: "visible" }}>
 <circle cx="7" cy="7" r="6" fill="none" stroke="var(--color-border-strong)" strokeWidth="1"/>
 <polygon points="7,2 9,7 7,6 5,7" fill="var(--jv-navy-800)"/>
 <text x="7" y="1" fontSize="6" textAnchor="middle" fill="var(--color-fg-muted)" fontFamily="var(--font-sans)">N</text>
 </svg>
 <span>≈ 3 600 km</span>
 </div>

 <svg
 viewBox={`0 0 ${CM_VB_W} ${CM_VB_H}`}
 width="100%"
 style={{ display: "block", height: 560 }}
 onClick={onBackgroundClick}
 >
 {/* subtle dot grid water field */}
 <defs>
 <pattern id="cm-dotgrid" x="0" y="0" width="32" height="32" patternUnits="userSpaceOnUse">
 <circle cx="1" cy="1" r="1" fill="var(--jv-ink-100)"/>
 </pattern>
 <pattern id="cm-hatch" x="0" y="0" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
 <line x1="0" y1="0" x2="0" y2="6" stroke="var(--jv-navy-100)" strokeWidth="1"/>
 </pattern>
 </defs>
 <rect x="0" y="0" width={CM_VB_W} height={CM_VB_H} fill="url(#cm-dotgrid)"/>

 {/* latitude markers */}
 {[
 { y: 100, label: "40°N" },
 { y: 220, label: "30°N" },
 { y: 340, label: "20°N" },
 { y: 460, label: "10°N" },
 ].map(m => (
 <g key={m.label}>
 <line x1="40" y1={m.y} x2={CM_VB_W - 40} y2={m.y} stroke="var(--jv-ink-200)" strokeWidth="0.75" strokeDasharray="2 6"/>
 <text x={CM_VB_W - 28} y={m.y + 4} fontSize="10" textAnchor="start" fill="var(--color-fg-muted)" fontFamily="var(--font-mono)">{m.label}</text>
 </g>
 ))}

 {/* country landmasses */}
 <g style={{ pointerEvents: "none" }}>
 <path d={VN_PATH} fill="var(--jv-ink-50)" stroke="var(--color-border-strong)" strokeWidth="1" strokeLinejoin="round"/>
 <path d={JP_HOKKAIDO} fill="var(--jv-ink-50)" stroke="var(--color-border-strong)" strokeWidth="1" strokeLinejoin="round"/>
 <path d={JP_HONSHU} fill="var(--jv-ink-50)" stroke="var(--color-border-strong)" strokeWidth="1" strokeLinejoin="round"/>
 <path d={JP_KYUSHU} fill="var(--jv-ink-50)" stroke="var(--color-border-strong)" strokeWidth="1" strokeLinejoin="round"/>
 <path d={JP_SHIKOKU} fill="var(--jv-ink-50)" stroke="var(--color-border-strong)" strokeWidth="1" strokeLinejoin="round"/>
 </g>

 {/* country name labels */}
 <g style={{ pointerEvents: "none" }}>
 <text x="160" y="232" fontSize="13" fontWeight="600" letterSpacing="0.08em" fill="var(--jv-navy-800)" fontFamily="var(--font-sans)">VIETNAM</text>
 <text x="828" y="262" fontSize="13" fontWeight="600" letterSpacing="0.08em" fill="var(--jv-navy-800)" fontFamily="var(--font-sans)">JAPAN</text>
 </g>

 {/* region tint overlays, soft sand tint over hovered/active region */}
 {(selectedRegion !== "all" || (highlightedRegion && highlightedRegion !== "all")) && (() => {
 const r = highlightedRegion && highlightedRegion !== "all" ? highlightedRegion : selectedRegion;
 // approximate bounding boxes per region (rounded rects behind pins)
 const boxes = {
 "vn-north": { x: 200, y: 78, w: 110, h: 100 },
 "vn-central": { x: 220, y: 240, w: 100, h: 100 },
 "vn-south": { x: 110, y: 420, w: 150, h: 110 },
 "jp-hokkaido": { x: 808, y: 64, w: 156, h: 150 },
 "jp-kanto": { x: 860, y: 270, w: 86, h: 86 },
 "jp-kansai": { x: 766, y: 308, w: 92, h: 70 },
 };
 const b = boxes[r];
 if (!b) return null;
 return (
 <rect x={b.x} y={b.y} width={b.w} height={b.h} rx="10"
 fill="var(--jv-sand-100)" fillOpacity="0.55"
 stroke="var(--jv-sand-300)" strokeWidth="1" strokeDasharray="3 3"
 style={{ pointerEvents: "none" }}/>
 );
 })()}

 {/* trade lanes (dashed bezier) */}
 <g style={{ pointerEvents: "none" }}>
 {lanes.map(ln => {
 const f = locById[ln.from]; const t = locById[ln.to];
 if (!f || !t) return null;
 return (
 <path key={ln.id} d={cmLanePath(f, t)}
 fill="none" stroke="var(--jv-navy-400)" strokeWidth="1.25"
 strokeDasharray="4 4" opacity="0.55"/>
 );
 })}
 </g>

 {/* pins */}
 {locations.map(loc => {
 const active = isCityActive(loc);
 const dimmed = isCityDimmed(loc);
 const selected = selectedCity === loc.id;
 const hover = hoverCity === loc.id;
 const count = countsByCity[loc.city] || 0;
 const r = selected || hover ? 14 : (count > 1 ? 11 : 9);
 const fill = selected ? "var(--jv-accent-600)" : (hover ? "var(--jv-navy-800)" : "var(--jv-navy-800)");
 const opacity = dimmed ? 0.25 : 1;
 return (
 <g key={loc.id}
 transform={`translate(${loc.x} ${loc.y})`}
 style={{ cursor: count > 0 ? "pointer" : "default", opacity, transition: "opacity 120ms" }}
 onMouseEnter={() => count > 0 && onCityHover && onCityHover(loc.id)}
 onMouseLeave={() => onCityHover && onCityHover(null)}
 onClick={(e) => { e.stopPropagation(); count > 0 && onCityClick && onCityClick(loc.id); }}
 >
 {/* halo ring when active */}
 {(selected || hover) && (
 <circle r={r + 8} fill={selected ? "var(--jv-accent-600)" : "var(--jv-navy-800)"} opacity="0.10"/>
 )}
 <circle r={r} fill="#fff" stroke={fill} strokeWidth="2"/>
 <circle r={r - 4} fill={fill}/>
 {count > 1 && (
 <text y={r === 14 ? 1 : 1} fontSize={r >= 12 ? 10 : 9} textAnchor="middle" dominantBaseline="middle"
 fill="#fff" fontWeight="700" fontFamily="var(--font-mono)" style={{ pointerEvents: "none" }}>
 {count}
 </text>
 )}
 {/* city label */}
 <g transform={`translate(${loc.x > 500 ? r + 8 : -(r + 8)} 4)`} style={{ pointerEvents: "none" }}>
 <text fontSize="12" fontWeight="600"
 textAnchor={loc.x > 500 ? "start" : "end"}
 fill={selected ? "var(--jv-accent-700)" : "var(--jv-navy-800)"}
 fontFamily="var(--font-sans)">{loc.city}</text>
 </g>
 </g>
 );
 })}
 </svg>
 </div>
 );
};

Object.assign(window, { CorridorMap });
