import { createFileRoute } from "@tanstack/react-router";
import { pb } from "@/lib/pocketbase";
import { AutoSaveTextarea } from "@/components/AutoSaveTextarea";
import { useState } from "react";
import { RelationshipType, type Secret } from "@/lib/types";
import { DocumentList } from "@/components/DocumentList";

export const Route = createFileRoute("/_authenticated/document/$documentId")({
  loader: async ({ params }) => {
    const doc = await pb.collection("documents").getOne(params.documentId);
    // Fetch the unique relationship where this document is the primary and type is "plannedSecrets"
    const relationships = await pb.collection("relationships").getList(1, 1, {
      filter: `primary = "${params.documentId}" && type = "${RelationshipType.Secrets}"`,
    });
    // Get all related secret document IDs from the secondary field
    const secretIds =
      relationships.items.length > 0 ? relationships.items[0].secondary : [];
    // Fetch all related secret documents
    let secrets: any[] = [];
    if (Array.isArray(secretIds) && secretIds.length > 0) {
      secrets = await pb.collection("documents").getFullList({
        filter: secretIds.map((id) => `id = "${id}"`).join(" || "),
      });
    }
    return { document: doc, secrets };
  },
  component: RouteComponent,
});

function RouteComponent() {
  const { document: session, secrets } = Route.useLoaderData();
  const strongStart = session?.data?.session?.strongStart || "";
  const [newSecret, setNewSecret] = useState("");
  const [adding, setAdding] = useState(false);
  const [secretList, setSecretList] = useState<Secret[]>(secrets);
  const [error, setError] = useState<string | null>(null);

  async function handleSaveStrongStart(newValue: string) {
    await pb.collection("documents").update(session.id, {
      data: {
        ...session.data,
        session: {
          ...session.data.session,
          strongStart: newValue,
        },
      },
    });
  }

  async function handleAddSecret() {
    if (!newSecret.trim()) return;
    setAdding(true);
    setError(null);
    try {
      // 1. Create the secret document
      const secretDoc = await pb.collection("documents").create({
        campaign: session.campaign, // assuming campaign is an id or object
        data: {
          secret: {
            text: newSecret,
            discoveredOn: null,
          },
        },
      });
      // 2. Check for existing relationship
      const existing = await pb.collection("relationships").getFullList({
        filter: `primary = "${session.id}" && type = "${RelationshipType.Secrets}"`,
      });
      if (existing.length > 0) {
        // Update existing relationship to add new secret to secondary array
        await pb.collection("relationships").update(existing[0].id, {
          "+secondary": secretDoc.id,
        });
      } else {
        // Create new relationship
        await pb.collection("relationships").create({
          primary: session.id,
          secondary: [secretDoc.id],
          type: RelationshipType.Secrets,
        });
      }
      setSecretList([...secretList, secretDoc]);
      setNewSecret("");
    } catch (e: any) {
      setError(e?.message || "Failed to add secret.");
    } finally {
      setAdding(false);
    }
  }

  async function handleToggleDiscovered(secret: Secret, checked: boolean) {
    // 1. Update the discovered field in the secret document
    const updatedSecret: Secret = await pb
      .collection("documents")
      .update(secret.id, {
        data: {
          ...secret.data,
          secret: {
            text: secret.data.secret.text,
            discovered: checked,
          },
        },
      });
    // 2. Remove any existing discoveredIn relationship
    const rels = await pb.collection("relationships").getList(1, 1, {
      filter: `primary = "${secret.id}" && type = "discoveredIn"`,
    });
    if (rels.items.length > 0) {
      await pb.collection("relationships").delete(rels.items[0].id);
    }
    // 3. If marking as discovered, add a new discoveredIn relationship
    if (checked) {
      await pb.collection("relationships").create({
        primary: secret.id,
        secondary: [session.id],
        type: "discoveredIn",
      });
    }
    // 4. Update local state
    setSecretList(
      secretList.map((s: any) => (s.id === secret.id ? updatedSecret : s)),
    );
  }

  return (
    <div className="max-w-xl mx-auto py-8">
      <h2 className="text-2xl font-bold mb-4 text-slate-100">
        Session Strong Start
      </h2>
      <AutoSaveTextarea
        value={strongStart}
        onSave={handleSaveStrongStart}
        placeholder="Enter a strong start for this session..."
        aria-label="Strong Start"
      />
      {secretList && (
        <DocumentList
          title="Secrets and Clues"
          items={secretList}
          newItemForm={(onSubmit) => (
            <form
              className="flex items-center gap-2 mt-4"
              onSubmit={(e) => {
                e.preventDefault();
                handleAddSecret();
                onSubmit();
              }}
            >
              <input
                type="text"
                className="flex-1 px-3 py-2 rounded bg-slate-800 text-slate-100 border border-slate-700 focus:outline-none focus:ring-2 focus:ring-violet-500"
                placeholder="Add a new secret..."
                value={newSecret}
                onChange={(e) => setNewSecret(e.target.value)}
                disabled={adding}
              />
              {error && (
                <div className="text-red-400 mt-2 text-sm">{error}</div>
              )}
              <button
                type="submit"
                className="px-4 py-2 rounded bg-emerald-600 hover:bg-emerald-700 text-white font-semibold transition-colors disabled:opacity-60"
                disabled={adding || !newSecret.trim()}
              >
                {adding ? "Adding..." : "Add Secret"}
              </button>
            </form>
          )}
          renderRow={(secret) => (
            <li
              key={secret.id}
              className="bg-slate-800 rounded p-4 text-slate-100 flex items-center gap-3"
            >
              <input
                type="checkbox"
                checked={!!secret.data?.secret?.discovered}
                onChange={(e) =>
                  handleToggleDiscovered(secret, e.target.checked)
                }
                className="accent-emerald-500 w-5 h-5"
                aria-label="Discovered"
              />
              <span>
                {secret.data?.secret?.text || (
                  <span className="italic text-slate-400">
                    (No secret text)
                  </span>
                )}
              </span>
            </li>
          )}
        />
      )}
    </div>
  );
}
