"use client";

import { useMemo, useState } from "react";
import type { MouseEvent } from "react";
import { useRouter } from "next/navigation";
import { ComposableMap, Geographies, Geography } from "react-simple-maps";
import world from "world-atlas/countries-110m.json";
import type { Market } from "@/lib/types";
import { numericIdToMarket } from "@/lib/mock-data/markets-metadata";
import { marketLabel } from "@/lib/labels";
import { sentimentToScore } from "@/lib/utils";

type MarketDatum = {
  code: Market;
  mentions: number;
  sentiment: number;
};

type TooltipState = {
  x: number;
  y: number;
  datum: MarketDatum;
} | null;

export function WorldChoropleth({
  data,
  height = 430,
  compact = false
}: {
  data: MarketDatum[];
  height?: number;
  compact?: boolean;
}) {
  const router = useRouter();
  const [tooltip, setTooltip] = useState<TooltipState>(null);
  const max = Math.max(...data.map((item) => item.mentions), 1);
  const byCode = useMemo(() => new Map(data.map((item) => [item.code, item])), [data]);

  function fillFor(datum?: MarketDatum) {
    if (!datum) return "#E8DFC8";
    const intensity = datum.mentions / max;
    if (intensity > 0.75) return "#4A0E1F";
    if (intensity > 0.5) return "#7A2838";
    if (intensity > 0.25) return "#B08D57";
    return "#D4B98C";
  }

  return (
    <div className="relative rounded-md border border-gold/25 bg-ivory-warm p-4">
      <ComposableMap projectionConfig={{ scale: compact ? 132 : 145 }} height={height} className="h-auto w-full">
        <Geographies geography={world}>
          {({ geographies }) =>
            geographies.map((geo) => {
              const code = numericIdToMarket[String(geo.id)];
              const datum = code ? byCode.get(code) : undefined;
              return (
                <Geography
                  key={geo.rsmKey}
                  geography={geo}
                  fill={fillFor(datum)}
                  stroke="#F7F2E8"
                  strokeWidth={0.55}
                  style={{
                    default: { outline: "none" },
                    hover: { outline: "none", fill: datum ? "#2B0810" : "#D4B98C", cursor: datum ? "pointer" : "default" },
                    pressed: { outline: "none" }
                  }}
                  onMouseMove={(event: MouseEvent<SVGPathElement>) => {
                    if (!datum) return;
                    setTooltip({ x: event.clientX, y: event.clientY, datum });
                  }}
                  onMouseLeave={() => setTooltip(null)}
                  onClick={() => {
                    if (code) router.push(`/markets/${code}`);
                  }}
                />
              );
            })
          }
        </Geographies>
      </ComposableMap>
      {tooltip ? (
        <div
          className="pointer-events-none fixed z-50 min-w-48 rounded-md border border-gold/40 bg-ivory p-3 text-sm shadow-vellum"
          style={{ left: tooltip.x + 14, top: tooltip.y + 14 }}
        >
          <p className="font-serif text-lg font-semibold text-bordeaux-deep">{marketLabel(tooltip.datum.code)}</p>
          <p className="mt-1 font-mono text-xs text-smoke">{tooltip.datum.mentions} mentions</p>
          <p className="mt-1 font-mono text-xs text-smoke">Sentiment {sentimentToScore(tooltip.datum.sentiment)}/100</p>
        </div>
      ) : null}
    </div>
  );
}
