import { useEffect, useState } from "react";
import { pb } from "@/lib/pocketbase";
import type { Document, RelationshipType } from "@/lib/types";
import { DocumentList } from "@/components/DocumentList";
import { Loader } from "./Loader";
import { DocumentRow } from "./documents/DocumentRow";
import { DocumentForm } from "./documents/DocumentForm";

interface RelationshipListProps {
  root: Document;
  relationshipType: RelationshipType;
}

/**
 * RelationshipList manages a list of documents related to a root document via a relationship type.
 * It handles fetching, creation, and relationship management, and renders a DocumentList.
 */
export function RelationshipList({
  root,
  relationshipType,
}: RelationshipListProps) {
  const [items, setItems] = useState<Document[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // Fetch related documents on mount or when root/relationshipType changes
  useEffect(() => {
    let cancelled = false;
    async function fetchRelated() {
      setLoading(true);
      setError(null);
      try {
        const relationships = await pb
          .collection("relationships")
          .getList(1, 1, {
            filter: `primary = "${root.id}" && type = "${relationshipType}"`,
          });
        const secondaryIds =
          relationships.items.length > 0
            ? relationships.items[0].secondary
            : [];
        let docs: Document[] = [];
        if (Array.isArray(secondaryIds) && secondaryIds.length > 0) {
          docs = (await pb.collection("documents").getFullList({
            filter: secondaryIds
              .map((id: string) => `id = "${id}"`)
              .join(" || "),
          })) as Document[];
        }
        if (!cancelled) setItems(docs);
      } catch (e: any) {
        if (!cancelled)
          setError(e?.message || "Failed to load related documents.");
      } finally {
        if (!cancelled) setLoading(false);
      }
    }
    fetchRelated();
    return () => {
      cancelled = true;
    };
  }, [root.id, relationshipType]);

  // Handles creation of a new document and adds it to the relationship
  const handleCreate = async (doc: Document) => {
    setLoading(true);
    setError(null);
    try {
      // Check for existing relationship
      const existing = await pb.collection("relationships").getFullList({
        filter: `primary = "${root.id}" && type = "${relationshipType}"`,
      });
      if (existing.length > 0) {
        console.debug("Adding to existing relationship");
        await pb.collection("relationships").update(existing[0].id, {
          "+secondary": doc.id,
        });
      } else {
        console.debug("Creating new relationship");
        await pb.collection("relationships").create({
          primary: root.id,
          secondary: [doc.id],
          type: relationshipType,
        });
      }
      setItems((prev) => [...prev, doc]);
    } catch (e: any) {
      setError(e?.message || "Failed to add document to relationship.");
    } finally {
      setLoading(false);
    }
  };

  if (loading) {
    <Loader />;
  }

  return (
    <DocumentList
      title={
        relationshipType.charAt(0).toUpperCase() + relationshipType.slice(1)
      }
      items={items}
      error={error}
      renderRow={(document) => <DocumentRow document={document} />}
      newItemForm={(onSubmit) => (
        <DocumentForm
          campaignId={root.campaign}
          relationshipType={relationshipType}
          onCreate={async (doc: Document) => {
            await handleCreate(doc);
            onSubmit();
          }}
        />
      )}
    />
  );
}
