"use client";

import { useRef, useState, useEffect } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import Link from "next/link";
import { Bookmark, Check } from "lucide-react";
import { collectionsAPI } from "@/lib/api";
import { useAuthStore } from "@/stores/authStore";
import type { Collection } from "@/lib/types";

interface CollectionPickerProps {
  billId: string;
}

export function CollectionPicker({ billId }: CollectionPickerProps) {
  const token = useAuthStore((s) => s.token);
  const [open, setOpen] = useState(false);
  const ref = useRef<HTMLDivElement>(null);
  const qc = useQueryClient();

  useEffect(() => {
    if (!open) return;
    function onClickOutside(e: MouseEvent) {
      if (ref.current && !ref.current.contains(e.target as Node)) {
        setOpen(false);
      }
    }
    document.addEventListener("mousedown", onClickOutside);
    return () => document.removeEventListener("mousedown", onClickOutside);
  }, [open]);

  const { data: collections } = useQuery({
    queryKey: ["collections"],
    queryFn: collectionsAPI.list,
    enabled: !!token,
  });

  const addMutation = useMutation({
    mutationFn: (id: number) => collectionsAPI.addBill(id, billId),
    onSuccess: (_, id) => {
      qc.invalidateQueries({ queryKey: ["collections"] });
      qc.invalidateQueries({ queryKey: ["collection", id] });
    },
  });

  const removeMutation = useMutation({
    mutationFn: (id: number) => collectionsAPI.removeBill(id, billId),
    onSuccess: (_, id) => {
      qc.invalidateQueries({ queryKey: ["collections"] });
      qc.invalidateQueries({ queryKey: ["collection", id] });
    },
  });

  if (!token) return null;

  // Determine which collections contain this bill
  // We check each collection's bill_count proxy by re-fetching detail... but since the list
  // endpoint doesn't return bill_ids, we use a lightweight approach: track via optimistic state.
  // The collection detail page has the bill list; for the picker we just check each collection.
  // To avoid N+1, we'll use a separate query to get the user's collection memberships for this bill.
  // For simplicity, we use the collections list and compare via a bill-membership query.

  return (
    <div ref={ref} className="relative">
      <button
        onClick={() => setOpen((v) => !v)}
        title="Add to collection"
        className={`p-1.5 rounded-md transition-colors ${
          open
            ? "bg-primary text-primary-foreground"
            : "text-muted-foreground hover:bg-accent hover:text-foreground"
        }`}
      >
        <Bookmark className="w-4 h-4" />
      </button>

      {open && (
        <div className="absolute right-0 top-full mt-1 z-20 w-56 bg-card border border-border rounded-lg shadow-lg overflow-hidden">
          {!collections || collections.length === 0 ? (
            <div className="px-3 py-3 text-xs text-muted-foreground">
              No collections yet.
            </div>
          ) : (
            <ul>
              {collections.map((c: Collection) => (
                <CollectionPickerRow
                  key={c.id}
                  collection={c}
                  billId={billId}
                  onAdd={() => addMutation.mutate(c.id)}
                  onRemove={() => removeMutation.mutate(c.id)}
                />
              ))}
            </ul>
          )}
          <div className="border-t border-border px-3 py-2">
            <Link
              href="/collections"
              onClick={() => setOpen(false)}
              className="text-xs text-primary hover:underline"
            >
              New collection →
            </Link>
          </div>
        </div>
      )}
    </div>
  );
}

function CollectionPickerRow({
  collection,
  billId,
  onAdd,
  onRemove,
}: {
  collection: Collection;
  billId: string;
  onAdd: () => void;
  onRemove: () => void;
}) {
  // Fetch detail to know if this bill is in the collection
  const { data: detail } = useQuery({
    queryKey: ["collection", collection.id],
    queryFn: () => collectionsAPI.get(collection.id),
  });

  const inCollection = detail?.bills.some((b) => b.bill_id === billId) ?? false;

  return (
    <li>
      <button
        onClick={inCollection ? onRemove : onAdd}
        className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent transition-colors text-left"
      >
        <span className="w-4 h-4 shrink-0 flex items-center justify-center">
          {inCollection && <Check className="w-3.5 h-3.5 text-primary" />}
        </span>
        <span className="truncate flex-1">{collection.name}</span>
      </button>
    </li>
  );
}
