"use client";

import { formatShortNumber } from "@/lib/format-number";
import { cn } from "@/lib/utils";
import gsap from "gsap";
import { useLayoutEffect, useMemo, useRef } from "react";
import { GlobeIcon } from "./icons";

type Props = {
  countries: { code: string; count: number }[];
  isLoading: boolean;
};

const PALETTE = [
  "#5750F1",
  "#0ABEF9",
  "#22AD5C",
  "#F59460",
  "#F23030",
  "#FCD34D",
  "#8155FF",
];

const RADIUS = 56;
const INNER = 38;
const CIRC = 2 * Math.PI * ((RADIUS + INNER) / 2);
const STROKE = RADIUS - INNER;

function flagEmoji(code: string) {
  if (!code || code.length !== 2) return "";
  const base = 0x1f1e6;
  return String.fromCodePoint(
    base + code.toUpperCase().charCodeAt(0) - 65,
    base + code.toUpperCase().charCodeAt(1) - 65,
  );
}

export function CountryDistribution({ countries, isLoading }: Props) {
  const rootRef = useRef<HTMLDivElement>(null);
  const arcsRef = useRef<SVGGElement>(null);
  const top = countries.slice(0, 6);
  const totalShown = top.reduce((acc, c) => acc + c.count, 0) || 1;

  const segments = useMemo(() => {
    let offset = 0;
    return top.map((c, i) => {
      const length = (c.count / totalShown) * CIRC;
      const seg = {
        code: c.code,
        count: c.count,
        color: PALETTE[i % PALETTE.length],
        dash: `${length} ${CIRC - length}`,
        offset: -offset,
      };
      offset += length;
      return seg;
    });
  }, [top, totalShown]);

  useLayoutEffect(() => {
    const reduced =
      typeof window !== "undefined" &&
      window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const ctx = gsap.context(() => {
      if (reduced) return;
      gsap.from(rootRef.current, {
        opacity: 0,
        y: 24,
        duration: 0.6,
        ease: "power3.out",
        delay: 0.25,
      });

      if (arcsRef.current) {
        const circles =
          arcsRef.current.querySelectorAll<SVGCircleElement>("circle.arc");
        circles.forEach((c) => {
          const finalDash = c.getAttribute("stroke-dasharray") || "0 0";
          gsap.fromTo(
            c,
            { strokeDasharray: `0 ${CIRC}` },
            {
              strokeDasharray: finalDash,
              duration: 1,
              ease: "power2.out",
              delay: 0.45,
            },
          );
        });
      }

      gsap.from("[data-country-row]", {
        x: 20,
        opacity: 0,
        duration: 0.45,
        stagger: 0.06,
        delay: 0.5,
        ease: "power2.out",
      });
    }, rootRef);
    return () => ctx.revert();
  }, [segments.length]);

  return (
    <div
      ref={rootRef}
      className="overflow-hidden rounded-2xl bg-white p-5 shadow-1 ring-1 ring-stroke dark:bg-gray-dark dark:ring-stroke-dark dark:shadow-card md:p-6"
    >
      <div className="mb-4 flex items-center justify-between">
        <div className="flex items-center gap-2">
          <span className="inline-flex size-9 items-center justify-center rounded-lg bg-primary/10 text-primary">
            <GlobeIcon className="size-5" />
          </span>
          <div>
            <h2 className="text-base font-bold text-dark dark:text-white">
              By Country
            </h2>
            <p className="text-xs text-dark-6">Top originating regions</p>
          </div>
        </div>
      </div>

      <div className="flex flex-col items-center gap-5 md:flex-row md:items-start">
        <div className="relative shrink-0">
          <svg width={(RADIUS + STROKE) * 2} height={(RADIUS + STROKE) * 2}>
            <g
              ref={arcsRef}
              transform={`translate(${RADIUS + STROKE} ${RADIUS + STROKE}) rotate(-90)`}
            >
              <circle
                r={(RADIUS + INNER) / 2}
                fill="none"
                stroke="currentColor"
                strokeOpacity="0.08"
                strokeWidth={STROKE}
                className="text-dark-6"
              />
              {segments.map((s, i) => (
                <circle
                  key={s.code}
                  className="arc"
                  r={(RADIUS + INNER) / 2}
                  fill="none"
                  stroke={s.color}
                  strokeWidth={STROKE}
                  strokeDasharray={s.dash}
                  strokeDashoffset={s.offset}
                  strokeLinecap="butt"
                  style={{ filter: `drop-shadow(0 0 6px ${s.color}40)` }}
                />
              ))}
            </g>
          </svg>
          <div className="pointer-events-none absolute inset-0 flex flex-col items-center justify-center">
            <div className="text-[11px] uppercase tracking-wider text-dark-6">
              Total
            </div>
            <div className="text-base font-bold text-dark dark:text-white">
              {isLoading ? "—" : formatShortNumber(totalShown, { plus: true })}
            </div>
          </div>
        </div>

        <ul className="flex-1 space-y-2">
          {(isLoading
            ? Array.from({ length: 5 }).map((_, i) => ({
                code: `--${i}`,
                count: 0,
                color: PALETTE[i],
              }))
            : segments.length
              ? segments
              : []
          ).map((s, i) => {
            const pct = isLoading
              ? 0
              : Math.round((s.count / totalShown) * 100);
            return (
              <li
                key={s.code}
                data-country-row
                className="group flex items-center gap-3 rounded-lg px-2 py-1.5 transition-colors hover:bg-gray-2 dark:hover:bg-dark-2"
              >
                <span
                  className={cn(
                    "size-2.5 shrink-0 rounded-full",
                  )}
                  style={{
                    backgroundColor: s.color,
                    boxShadow: `0 0 0 3px ${s.color}22`,
                  }}
                />
                <span className="text-base leading-none">
                  {flagEmoji(s.code)}
                </span>
                <span className="flex-1 truncate text-sm font-medium text-dark dark:text-white">
                  {s.code.toUpperCase()}
                </span>
                <div className="hidden h-1.5 w-24 overflow-hidden rounded-full bg-gray-2 dark:bg-dark-3 sm:block">
                  <div
                    className="h-full rounded-full transition-all duration-700"
                    style={{
                      width: `${pct}%`,
                      backgroundColor: s.color,
                    }}
                  />
                </div>
                <span className="w-10 text-right text-xs font-semibold tabular-nums text-dark-5 dark:text-dark-6">
                  {isLoading ? "—" : `${pct}%`}
                </span>
              </li>
            );
          })}
          {!isLoading && segments.length === 0 && (
            <li className="text-center text-sm text-dark-6">No data yet.</li>
          )}
        </ul>
      </div>
    </div>
  );
}
