"use client";

import { useRef, useState } from "react";
import Link from "next/link";
import { BookOpen } from "lucide-react";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { cn } from "@/lib/utils";
import { glossaryHref, trackGlossaryOpened, useGlossary } from "./glossary-client";
import { useLearningPrefs } from "./learning-prefs";

const OPEN_DELAY_MS = 250;
const CLOSE_DELAY_MS = 200;

// Glossary keys are snake_case; a label like "L/C" or "Ex-factory" also finds its entry by the term itself.
function findEntry(byKey, entries, k, label) {
  if (k && byKey.has(k)) return byKey.get(k);
  const wanted = String(k || label || "").toLowerCase().replace(/[^a-z0-9]+/g, "");
  if (!wanted) return null;
  return entries.find((entry) => String(entry.term).toLowerCase().replace(/[^a-z0-9]+/g, "") === wanted
    || String(entry.key).toLowerCase().replace(/[^a-z0-9]+/g, "") === wanted) || null;
}

/**
 * A trade word with a plain-language explainer: dotted underline, popover on hover (mouse) or tap/Enter.
 * `<Term k="tna">TNA</Term>`. Shows the Bangla line when the user turned on Bangla hints. Renders the plain
 * children when the glossary has no such term, so a label never breaks. Safe inside labels and tab triggers:
 * it does not steal the click from them.
 */
export function Term({ k, children, className }) {
  const { entries, byKey } = useGlossary();
  const { bnHints } = useLearningPrefs();
  const [open, setOpen] = useState(false);
  const timer = useRef(null);
  const entry = findEntry(byKey, entries, k, typeof children === "string" ? children : "");

  if (!entry) return <>{children}</>;

  const change = (next) => {
    clearTimeout(timer.current);
    setOpen(next);
    if (next) trackGlossaryOpened(entry.key);
  };
  const hoverOpen = (event) => {
    if (event.pointerType !== "mouse") return;
    clearTimeout(timer.current);
    timer.current = setTimeout(() => change(true), OPEN_DELAY_MS);
  };
  const hoverClose = (event) => {
    if (event.pointerType !== "mouse") return;
    clearTimeout(timer.current);
    timer.current = setTimeout(() => setOpen(false), CLOSE_DELAY_MS);
  };
  // Inside a tab trigger or a label the explainer must not also switch the tab or focus the field.
  const stop = (event) => event.stopPropagation();

  return <Popover open={open} onOpenChange={change}>
    <PopoverTrigger asChild>
      <span
        role="button"
        tabIndex={0}
        aria-label={`${typeof children === "string" ? children : entry.term}: what does it mean?`}
        className={cn("cursor-help underline decoration-muted-foreground/60 decoration-dotted underline-offset-4 hover:decoration-foreground focus-visible:rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50", className)}
        onPointerEnter={hoverOpen}
        onPointerLeave={hoverClose}
        onClick={(event) => { stop(event); event.preventDefault(); change(!open); }}
        onPointerDown={stop}
        onMouseDown={stop}
        onFocus={stop}
        onKeyDown={(event) => {
          if (event.key !== "Enter" && event.key !== " ") return;
          event.preventDefault();
          stop(event);
          change(!open);
        }}
      >{children}</span>
    </PopoverTrigger>
    <PopoverContent
      side="top"
      align="start"
      collisionPadding={12}
      className="grid w-72 gap-1.5 text-sm"
      onPointerEnter={(event) => { if (event.pointerType === "mouse") clearTimeout(timer.current); }}
      onPointerLeave={hoverClose}
      onClick={stop}
      onOpenAutoFocus={(event) => event.preventDefault()}
    >
      <p className="font-semibold text-foreground">{entry.term}</p>
      <p className="text-muted-foreground">{entry.meaning}</p>
      {bnHints && entry.bn && <p lang="bn" className="text-foreground/80">{entry.bn}</p>}
      <Link href={glossaryHref(entry.key)} className="mt-1 inline-flex items-center gap-1.5 text-xs font-medium text-foreground underline-offset-4 hover:underline" onClick={() => setOpen(false)}>
        <BookOpen className="size-3.5" aria-hidden="true" /> Open glossary
      </Link>
    </PopoverContent>
  </Popover>;
}
