/* Orenwell marketing site — interactive geographic 50-state availability map.
   A true US map (AlbersUSA projection, so Alaska & Hawaii sit as clean insets)
   is built at runtime from us-atlas TopoJSON via d3-geo, then painted in
   Orenwell's teal: every state is shaded in the "telehealth available" tone.
   Hovering a state darkens it and shows a tooltip with the state name +
   "Telehealth available." The visitor's state is detected by IP geolocation
   and, when found, persistently highlighted in a darker "your state" teal with
   its own legend chip. If the geographic data can't load, a labeled tile-grid
   fallback renders so the section is never empty. */

const OW_ABBR_NAME = {
  AL: "Alabama", AK: "Alaska", AZ: "Arizona", AR: "Arkansas", CA: "California",
  CO: "Colorado", CT: "Connecticut", DE: "Delaware", DC: "District of Columbia",
  FL: "Florida", GA: "Georgia", HI: "Hawaii", ID: "Idaho", IL: "Illinois",
  IN: "Indiana", IA: "Iowa", KS: "Kansas", KY: "Kentucky", LA: "Louisiana",
  ME: "Maine", MD: "Maryland", MA: "Massachusetts", MI: "Michigan",
  MN: "Minnesota", MS: "Mississippi", MO: "Missouri", MT: "Montana",
  NE: "Nebraska", NV: "Nevada", NH: "New Hampshire", NJ: "New Jersey",
  NM: "New Mexico", NY: "New York", NC: "North Carolina", ND: "North Dakota",
  OH: "Ohio", OK: "Oklahoma", OR: "Oregon", PA: "Pennsylvania",
  RI: "Rhode Island", SC: "South Carolina", SD: "South Dakota",
  TN: "Tennessee", TX: "Texas", UT: "Utah", VT: "Vermont", VA: "Virginia",
  WA: "Washington", WV: "West Virginia", WI: "Wisconsin", WY: "Wyoming",
};
const OW_NAME_SET = new Set(Object.values(OW_ABBR_NAME));

/* Tile-grid cartogram — fallback only, used if the geographic data fails to load */
const OW_TILE_STATES = [
  ["AK", "Alaska", 0, 0], ["ME", "Maine", 0, 10],
  ["WA", "Washington", 1, 1], ["ID", "Idaho", 1, 2], ["MT", "Montana", 1, 3], ["ND", "North Dakota", 1, 4], ["MN", "Minnesota", 1, 5], ["WI", "Wisconsin", 1, 6], ["MI", "Michigan", 1, 7], ["VT", "Vermont", 1, 9], ["NH", "New Hampshire", 1, 10],
  ["OR", "Oregon", 2, 1], ["NV", "Nevada", 2, 2], ["WY", "Wyoming", 2, 3], ["SD", "South Dakota", 2, 4], ["IA", "Iowa", 2, 5], ["IL", "Illinois", 2, 6], ["IN", "Indiana", 2, 7], ["OH", "Ohio", 2, 8], ["NY", "New York", 2, 9], ["MA", "Massachusetts", 2, 10],
  ["CA", "California", 3, 1], ["UT", "Utah", 3, 2], ["CO", "Colorado", 3, 3], ["NE", "Nebraska", 3, 4], ["MO", "Missouri", 3, 5], ["KY", "Kentucky", 3, 6], ["WV", "West Virginia", 3, 7], ["PA", "Pennsylvania", 3, 8], ["NJ", "New Jersey", 3, 9], ["RI", "Rhode Island", 3, 10],
  ["AZ", "Arizona", 4, 2], ["NM", "New Mexico", 4, 3], ["KS", "Kansas", 4, 4], ["AR", "Arkansas", 4, 5], ["TN", "Tennessee", 4, 6], ["VA", "Virginia", 4, 7], ["MD", "Maryland", 4, 8], ["DC", "District of Columbia", 4, 9], ["CT", "Connecticut", 4, 10],
  ["OK", "Oklahoma", 5, 4], ["LA", "Louisiana", 5, 5], ["MS", "Mississippi", 5, 6], ["AL", "Alabama", 5, 7], ["NC", "North Carolina", 5, 8], ["SC", "South Carolina", 5, 9], ["DE", "Delaware", 5, 10],
  ["HI", "Hawaii", 6, 0], ["TX", "Texas", 6, 4], ["GA", "Georgia", 6, 8],
  ["FL", "Florida", 7, 8],
];

const OW_MAP_W = 960;
const OW_MAP_H = 600;

/* Shared legend row — "your state" chip only appears when a state was detected */
function MapLegend({ yourState }) {
  return (
    <div style={{ display: "flex", justifyContent: "center", alignItems: "center", gap: 18, marginTop: 22, flexWrap: "wrap" }}>
      <span style={{ display: "inline-flex", alignItems: "center", gap: 8, fontSize: 13, color: "var(--gray-600)", fontWeight: 500 }}>
        <span style={{ width: 14, height: 14, borderRadius: 4, background: "var(--teal-100)", border: "1px solid var(--teal-200)" }} /> Telehealth available
      </span>
      {yourState && (
        <span style={{ display: "inline-flex", alignItems: "center", gap: 8, fontSize: 13, color: "var(--gray-600)", fontWeight: 500 }}>
          <span style={{ width: 14, height: 14, borderRadius: 4, background: "var(--teal-700)" }} /> Your state, highlighted
        </span>
      )}
    </div>
  );
}

function UsMap() {
  const [paths, setPaths] = React.useState(null);   // [{ name, d }]
  const [failed, setFailed] = React.useState(false);
  const [active, setActive] = React.useState(null); // hovered state name
  const [tip, setTip] = React.useState(null);       // { x, y, name }
  const [yourState, setYourState] = React.useState(null);
  const wrapRef = React.useRef(null);

  /* Build the geographic map once d3 + topojson are available */
  React.useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        if (!window.d3 || !window.topojson) throw new Error("map libs unavailable");
        const res = await fetch("https://cdn.jsdelivr.net/npm/us-atlas@3/states-10m.json");
        if (!res.ok) throw new Error("map data fetch failed");
        const topo = await res.json();
        const fc = window.topojson.feature(topo, topo.objects.states);
        const projection = window.d3.geoAlbersUsa().fitSize([OW_MAP_W, OW_MAP_H], fc);
        const gp = window.d3.geoPath(projection);
        const built = fc.features
          .map((f) => ({ name: f.properties.name, d: gp(f) }))
          .filter((s) => s.d && OW_NAME_SET.has(s.name));
        if (cancelled) return;
        if (built.length < 50) throw new Error("incomplete map");
        setPaths(built);
      } catch (e) {
        if (!cancelled) setFailed(true);
      }
    })();
    return () => { cancelled = true; };
  }, []);

  /* IP-based geolocation → persistently highlight the visitor's state */
  React.useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const res = await fetch("https://ipapi.co/json/");
        if (!res.ok) throw new Error();
        const data = await res.json();
        let name = null;
        if (data && data.region && OW_NAME_SET.has(data.region)) name = data.region;
        else if (data && data.region_code && OW_ABBR_NAME[data.region_code]) name = OW_ABBR_NAME[data.region_code];
        if (name && !cancelled) setYourState(name);
      } catch (e) { /* leave un-highlighted — legend chip stays hidden */ }
    })();
    return () => { cancelled = true; };
  }, []);

  const moveTip = (e, name) => {
    const el = wrapRef.current;
    if (!el) return;
    const r = el.getBoundingClientRect();
    setTip({ x: e.clientX - r.left, y: e.clientY - r.top, name });
  };

  const fillFor = (name) => {
    const isYour = name === yourState;
    const isActive = active === name;
    if (isActive) return isYour ? "var(--teal-800)" : "var(--teal-600)";
    return isYour ? "var(--teal-700)" : "var(--teal-100)";
  };

  /* ---- Hard-failure fallback: labeled tile grid ---- */
  if (failed) {
    const cols = 11, rows = 8, cellW = 100 / cols, cellH = 100 / rows;
    return (
      <div>
        <div style={{ width: "100%", maxWidth: 560, margin: "0 auto" }}>
          <div style={{ position: "relative", width: "100%", paddingBottom: (rows / cols) * 100 + "%" }}>
            {OW_TILE_STATES.map(([abbr, name, r, c]) => {
              const isYour = name === yourState;
              const on = active === abbr;
              return (
                <div key={abbr}
                  onMouseEnter={(e) => { setActive(abbr); moveTip(e, name); }}
                  onMouseMove={(e) => moveTip(e, name)}
                  onMouseLeave={() => { setActive((a) => (a === abbr ? null : a)); setTip(null); }}
                  tabIndex={0} role="img" aria-label={name + " — telehealth available"}
                  style={{ position: "absolute", left: c * cellW + "%", top: r * cellH + "%", width: cellW + "%", height: cellH + "%", cursor: "default", outline: "none" }}>
                  <div style={{ position: "absolute", inset: "8%",
                    background: on ? "var(--teal-600)" : (isYour ? "var(--teal-700)" : "var(--teal-100)"),
                    border: "1px solid " + (on || isYour ? "transparent" : "var(--teal-200)"),
                    borderRadius: "var(--radius-sm)", display: "flex", alignItems: "center", justifyContent: "center",
                    transition: "background .16s var(--ease)" }}>
                    <span style={{ fontFamily: "var(--font-body)", fontSize: "clamp(8px, 1.5vw, 11px)", fontWeight: 700, letterSpacing: ".02em",
                      color: on || isYour ? "#fff" : "var(--teal-700)" }}>{abbr}</span>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
        <MapLegend yourState={yourState} />
      </div>
    );
  }

  /* ---- Loading skeleton (brief, while map data streams) ---- */
  if (!paths) {
    return (
      <div>
        <div style={{ width: "100%", maxWidth: 720, margin: "0 auto" }}>
          <div style={{ position: "relative", width: "100%", paddingBottom: (OW_MAP_H / OW_MAP_W) * 100 + "%",
            borderRadius: "var(--radius-lg)", background: "linear-gradient(100deg, var(--teal-50) 30%, var(--teal-100) 50%, var(--teal-50) 70%)",
            backgroundSize: "200% 100%", animation: "owMapShimmer 1.3s var(--ease) infinite" }}>
            <span style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center",
              fontFamily: "var(--font-body)", fontSize: 13, fontWeight: 600, letterSpacing: ".04em", color: "var(--teal-500)" }}>
              Loading map…
            </span>
          </div>
        </div>
        <style>{"@keyframes owMapShimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}"}</style>
        <MapLegend yourState={yourState} />
      </div>
    );
  }

  /* ---- Geographic map ---- */
  return (
    <div>
      <div ref={wrapRef} style={{ position: "relative", width: "100%", maxWidth: 720, margin: "0 auto" }}>
        <svg viewBox={"0 0 " + OW_MAP_W + " " + OW_MAP_H} width="100%" style={{ display: "block", overflow: "visible" }}
          role="img" aria-label="Map of the United States — telehealth available in all 50 states">
          {paths.map((s) => (
            <path key={s.name} d={s.d} fill={fillFor(s.name)} stroke="#FFFFFF" strokeWidth={0.8} strokeLinejoin="round"
              tabIndex={0} role="img" aria-label={s.name + " — telehealth available"}
              onMouseEnter={(e) => { setActive(s.name); moveTip(e, s.name); }}
              onMouseMove={(e) => moveTip(e, s.name)}
              onMouseLeave={() => { setActive((a) => (a === s.name ? null : a)); setTip(null); }}
              onFocus={() => setActive(s.name)} onBlur={() => setActive((a) => (a === s.name ? null : a))}
              style={{ cursor: "pointer", outline: "none", transition: "fill .16s var(--ease)" }} />
          ))}
        </svg>

        {/* Tooltip — follows the cursor, anchored just above it */}
        {tip && (
          <div aria-hidden="true" style={{ position: "absolute", left: tip.x, top: tip.y,
            transform: "translate(-50%, calc(-100% - 14px))", zIndex: 5, pointerEvents: "none",
            background: "var(--ink-900)", color: "#fff", padding: "7px 11px", borderRadius: "var(--radius-sm)",
            boxShadow: "var(--shadow-lg)", whiteSpace: "nowrap" }}>
            <div style={{ fontSize: 12.5, fontWeight: 700, lineHeight: 1.2 }}>{tip.name}</div>
            <div style={{ display: "flex", alignItems: "center", gap: 5, marginTop: 3, fontSize: 11, color: "var(--teal-200)", fontWeight: 600 }}>
              <span style={{ width: 6, height: 6, borderRadius: "50%", background: "#5FBE8E" }} />Telehealth available
            </div>
            <span style={{ position: "absolute", left: "50%", bottom: -5, transform: "translateX(-50%) rotate(45deg)", width: 10, height: 10, background: "var(--ink-900)" }} />
          </div>
        )}
      </div>
      <MapLegend yourState={yourState} />
    </div>
  );
}

Object.assign(window, { UsMap });
