"use client";

import { createPortal } from "react-dom";
import { useCallback, useRef, useState } from "react";
import { trpc } from "~/lib/trpc/client.js";
import { useAnchoredOverlay } from "~/hooks/useAnchoredOverlay.js";

interface SkillTagInputProps {
  value: string[];
  onChange: (skills: string[]) => void;
  placeholder?: string;
  className?: string;
}

export function SkillTagInput({ value, onChange, placeholder = "Add skill…", className }: SkillTagInputProps) {
  const [input, setInput] = useState("");
  const [open, setOpen] = useState(false);
  const [activeIdx, setActiveIdx] = useState(-1);
  const containerRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);
  const closeSuggestions = useCallback(() => {
    setOpen(false);
    setActiveIdx(-1);
  }, []);

  const { data: analytics } = trpc.resource.getSkillsAnalytics.useQuery(undefined, {
    staleTime: 120_000,
  });

  const aggregated: { skill: string }[] = analytics?.aggregated ?? [];
  const suggestions: string[] = aggregated
    .map((a) => a.skill)
    .filter((s) => !value.includes(s) && s.toLowerCase().includes(input.toLowerCase()))
    .slice(0, 8);
  const dropdownOpen = open && suggestions.length > 0;
  const { panelRef, position } = useAnchoredOverlay<HTMLDivElement>({
    open: dropdownOpen,
    onClose: closeSuggestions,
    align: "start",
    matchTriggerWidth: true,
    triggerRef: containerRef,
  });

  function addSkill(skill: string) {
    const trimmed = skill.trim();
    if (trimmed && !value.includes(trimmed)) {
      onChange([...value, trimmed]);
    }
    setInput("");
    setOpen(false);
    setActiveIdx(-1);
    inputRef.current?.focus();
  }

  function removeSkill(skill: string) {
    onChange(value.filter((s) => s !== skill));
  }

  function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
    if (e.key === "Enter") {
      e.preventDefault();
      if (activeIdx >= 0 && suggestions[activeIdx]) {
        addSkill(suggestions[activeIdx]);
      } else if (input.trim()) {
        addSkill(input);
      }
    } else if (e.key === "ArrowDown") {
      e.preventDefault();
      setActiveIdx((i) => Math.min(i + 1, suggestions.length - 1));
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setActiveIdx((i) => Math.max(i - 1, -1));
    } else if (e.key === "Escape") {
      closeSuggestions();
    } else if (e.key === "Backspace" && input === "" && value.length > 0) {
      onChange(value.slice(0, -1));
    }
  }

  return (
    <div ref={containerRef} className={`relative ${className ?? ""}`}>
      {/* Tags + input row */}
      <div
        className="min-h-[42px] flex flex-wrap gap-1.5 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-900 cursor-text focus-within:ring-2 focus-within:ring-brand-500 focus-within:border-transparent"
        onClick={() => inputRef.current?.focus()}
      >
        {value.map((skill) => (
          <span
            key={skill}
            className="inline-flex items-center gap-1 px-2 py-0.5 bg-brand-100 dark:bg-brand-900/40 text-brand-800 dark:text-brand-300 text-xs font-medium rounded-full"
          >
            {skill}
            <button
              type="button"
              onClick={() => removeSkill(skill)}
              className="hover:text-brand-600 dark:hover:text-brand-200 leading-none"
              aria-label={`Remove ${skill}`}
            >
              ×
            </button>
          </span>
        ))}
        <input
          ref={inputRef}
          type="text"
          value={input}
          onChange={(e) => { setInput(e.target.value); setOpen(true); setActiveIdx(-1); }}
          onFocus={() => setOpen(true)}
          onKeyDown={handleKeyDown}
          placeholder={value.length === 0 ? placeholder : ""}
          className="flex-1 min-w-[120px] outline-none bg-transparent text-sm text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500"
        />
      </div>

      {/* Dropdown */}
      {dropdownOpen && typeof document !== "undefined"
        ? createPortal(
            <div
              ref={panelRef}
              className="fixed z-[9998] max-h-48 overflow-y-auto rounded-lg border border-gray-200 bg-white shadow-xl dark:border-gray-700 dark:bg-gray-800"
              style={{
                top: position.top,
                left: position.left,
                width: position.minWidth,
              }}
              onMouseDown={(e) => e.preventDefault()}
            >
              <ul>
                {suggestions.map((skill, idx) => (
                  <li key={skill}>
                    <button
                      type="button"
                      onMouseDown={(e) => { e.preventDefault(); addSkill(skill); }}
                      className={`w-full text-left px-3 py-2 text-sm transition-colors ${
                        idx === activeIdx
                          ? "bg-brand-50 dark:bg-brand-900/30 text-brand-700 dark:text-brand-300"
                          : "text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700"
                      }`}
                    >
                      {skill}
                    </button>
                  </li>
                ))}
              </ul>
            </div>,
            document.body,
          )
        : null}
    </div>
  );
}
