"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { useEffect, useRef, useState } from "react";
import {
  FetchError,
  apiGet,
  apiPost,
  apiDelete,
  type PublicTemplate,
} from "@/lib/client-api";

export function SearchPopover({
  authenticated,
  favoriteIds,
  onClose,
}: {
  authenticated: boolean;
  favoriteIds: string[];
  onClose: () => void;
}) {
  const [query, setQuery] = useState("");
  const [results, setResults] = useState<PublicTemplate[]>([]);
  const [loading, setLoading] = useState(false);
  const [favSet, setFavSet] = useState<Set<string>>(new Set(favoriteIds));
  const inputRef = useRef<HTMLInputElement>(null);
  const router = useRouter();

  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  useEffect(() => {
    const controller = new AbortController();
    const handle = setTimeout(async () => {
      setLoading(true);
      try {
        const url = `/api/template-search?q=${encodeURIComponent(query.trim())}`;
        const data = await apiGet<{ items: PublicTemplate[] }>(url, {
          signal: controller.signal,
        } as never);
        setResults(data.items ?? []);
      } catch {
        /* ignore abort */
      } finally {
        setLoading(false);
      }
    }, 150);
    return () => {
      clearTimeout(handle);
      controller.abort();
    };
  }, [query]);

  const toggleFavorite = async (templateId: string) => {
    const isFav = favSet.has(templateId);
    if (isFav) {
      setFavSet((s) => {
        const next = new Set(s);
        next.delete(templateId);
        return next;
      });
      try {
        await apiDelete(`/api/favorites/${templateId}`);
      } catch {
        /* ignore */
      }
    } else {
      setFavSet((s) => new Set(s).add(templateId));
      try {
        await apiPost("/api/favorites", { templateId });
      } catch (err) {
        if (err instanceof FetchError) {
          setFavSet((s) => {
            const next = new Set(s);
            next.delete(templateId);
            return next;
          });
        }
      }
    }
  };

  return (
    <div className="p-2">
      <div className="flex items-center gap-2 rounded-xl border border-rose-100 bg-white px-3 py-2">
        <SearchIcon className="h-4 w-4 text-rose-400" />
        <input
          ref={inputRef}
          type="text"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === "Enter") {
              const target = results[0];
              router.push(target ? `/templates#${target.id}` : "/templates");
            }
          }}
          placeholder="Search templates by name, category or description…"
          className="flex-1 bg-transparent text-sm text-foreground placeholder:text-muted focus:outline-none"
        />
        <button
          type="button"
          onClick={onClose}
          aria-label="Close search"
          className="rounded p-1 text-muted hover:bg-rose-50 hover:text-rose-700"
        >
          ✕
        </button>
      </div>
      <div className="mt-2 max-h-80 overflow-y-auto rounded-xl border border-rose-50 bg-white">
        {loading ? (
          <p className="p-4 text-sm text-muted">Searching…</p>
        ) : results.length === 0 ? (
          <p className="p-4 text-sm text-muted">
            {query.trim()
              ? `No templates match “${query.trim()}”.`
              : "Start typing to find a template."}
          </p>
        ) : (
          <ul className="divide-y divide-rose-50">
            {results.map((t) => {
              const fav = favSet.has(t.id);
              return (
                <li
                  key={t.id}
                  className="flex items-center gap-3 px-3 py-2 hover:bg-rose-50/60"
                >
                  <div className="grid h-9 w-9 shrink-0 place-items-center rounded-lg bg-gradient-to-br from-rose-100 to-pink-100 text-sm font-semibold text-rose-700">
                    {t.icon?.[0]?.toUpperCase() ?? t.name.charAt(0)}
                  </div>
                  <div className="min-w-0 flex-1">
                    <p className="truncate text-sm font-semibold text-foreground">
                      {t.name}
                    </p>
                    <p className="truncate text-xs text-muted">
                      {t.category} · {t.modules.filter((m) => m.enabled).length} modules
                    </p>
                  </div>
                  {authenticated ? (
                    <button
                      type="button"
                      onClick={() => toggleFavorite(t.id)}
                      aria-label={fav ? "Remove from favorites" : "Add to favorites"}
                      className={`grid h-8 w-8 place-items-center rounded-full border transition-colors ${
                        fav
                          ? "border-rose-500 bg-rose-500 text-white"
                          : "border-rose-200 bg-white text-rose-500 hover:bg-rose-50"
                      }`}
                    >
                      <HeartIcon className="h-3.5 w-3.5" filled={fav} />
                    </button>
                  ) : null}
                  <Link
                    href="/templates"
                    className="text-xs font-medium text-rose-600 hover:text-rose-700"
                  >
                    View →
                  </Link>
                </li>
              );
            })}
          </ul>
        )}
      </div>
      <p className="mt-2 px-2 text-[11px] text-muted">
        Press <kbd className="rounded border border-rose-100 bg-rose-50 px-1">Enter</kbd> to see all templates.
      </p>
    </div>
  );
}

function SearchIcon(props: React.SVGProps<SVGSVGElement>) {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...props}>
      <circle cx="11" cy="11" r="7" />
      <path d="m21 21-4.3-4.3" />
    </svg>
  );
}

function HeartIcon({
  className,
  filled,
}: {
  className?: string;
  filled?: boolean;
}) {
  return (
    <svg
      viewBox="0 0 24 24"
      fill={filled ? "currentColor" : "none"}
      stroke="currentColor"
      strokeWidth="2"
      className={className}
    >
      <path d="M12 21s-7.5-4.6-9.6-9.4C.7 7.5 3.5 4 7 4c2 0 3.6 1 5 2.6C13.4 5 15 4 17 4c3.5 0 6.3 3.5 4.6 7.6C19.5 16.4 12 21 12 21Z" />
    </svg>
  );
}
