"use client";

import { useCallback, useEffect, useState } from "react";
import { createClient } from "@/lib/supabase/client";
import { useWorkspaceStore } from "@/stores/workspace-store";
import type { Attachment, Invoice, Note, Project, Task } from "@/types";

export interface DocumentItem extends Attachment {
  entityTitle: string;
  entityHref: string;
  entityLabel: "Project" | "Task" | "Note" | "Invoice";
}

function getEntityHref(attachment: Attachment) {
  if (attachment.entity_type === "project") {
    return `/projects/${attachment.entity_id}`;
  }

  if (attachment.entity_type === "task") {
    return `/tasks?task=${attachment.entity_id}`;
  }

  if (attachment.entity_type === "invoice") {
    return `/invoicing?invoice=${attachment.entity_id}`;
  }

  return `/notes/${attachment.entity_id}`;
}

function getEntityLabel(attachment: Attachment): DocumentItem["entityLabel"] {
  if (attachment.entity_type === "project") return "Project";
  if (attachment.entity_type === "task") return "Task";
  if (attachment.entity_type === "invoice") return "Invoice";
  return "Note";
}

export function useDocuments() {
  const [documents, setDocuments] = useState<DocumentItem[]>([]);
  const [loading, setLoading] = useState(true);
  const supabase = createClient();
  const activeTeamId = useWorkspaceStore((state) => state.activeTeamId);
  const initialized = useWorkspaceStore((state) => state.initialized);

  const fetchDocuments = useCallback(async () => {
    if (!initialized) return;

    setLoading(true);

    let attachmentsQuery = supabase
      .from("attachments")
      .select("*")
      .order("created_at", { ascending: false });

    attachmentsQuery = activeTeamId
      ? attachmentsQuery.eq("team_id", activeTeamId)
      : attachmentsQuery.is("team_id", null);

    const { data: attachmentsData } = await attachmentsQuery;
    const attachments = (attachmentsData || []) as Attachment[];

    if (attachments.length === 0) {
      setDocuments([]);
      setLoading(false);
      return;
    }

    const taskIds = attachments
      .filter((attachment) => attachment.entity_type === "task")
      .map((attachment) => attachment.entity_id);
    const noteIds = attachments
      .filter((attachment) => attachment.entity_type === "note")
      .map((attachment) => attachment.entity_id);
    const projectIds = attachments
      .filter((attachment) => attachment.entity_type === "project")
      .map((attachment) => attachment.entity_id);
    const invoiceIds = attachments
      .filter((attachment) => attachment.entity_type === "invoice")
      .map((attachment) => attachment.entity_id);

    const [tasksRes, notesRes, projectsRes, invoicesRes] = await Promise.all([
      taskIds.length > 0
        ? supabase.from("tasks").select("id, title").in("id", taskIds)
        : Promise.resolve({ data: [] as Array<Pick<Task, "id" | "title">> }),
      noteIds.length > 0
        ? supabase.from("notes").select("id, title").in("id", noteIds)
        : Promise.resolve({ data: [] as Array<Pick<Note, "id" | "title">> }),
      projectIds.length > 0
        ? supabase.from("projects").select("id, name").in("id", projectIds)
        : Promise.resolve({ data: [] as Array<Pick<Project, "id" | "name">> }),
      invoiceIds.length > 0
        ? supabase.from("invoices").select("id, invoice_number, counterparty_name").in("id", invoiceIds)
        : Promise.resolve({
            data: [] as Array<Pick<Invoice, "id" | "invoice_number" | "counterparty_name">>,
          }),
    ]);

    const taskMap = new Map(
      ((tasksRes.data || []) as Array<Pick<Task, "id" | "title">>).map((task) => [
        task.id,
        task.title,
      ])
    );
    const noteMap = new Map(
      ((notesRes.data || []) as Array<Pick<Note, "id" | "title">>).map((note) => [
        note.id,
        note.title,
      ])
    );
    const projectMap = new Map(
      ((projectsRes.data || []) as Array<Pick<Project, "id" | "name">>).map((project) => [
        project.id,
        project.name,
      ])
    );
    const invoiceMap = new Map(
      (
        (invoicesRes.data || []) as Array<
          Pick<Invoice, "id" | "invoice_number" | "counterparty_name">
        >
      ).map((invoice) => [
        invoice.id,
        invoice.counterparty_name
          ? `${invoice.invoice_number} · ${invoice.counterparty_name}`
          : invoice.invoice_number,
      ])
    );

    setDocuments(
      attachments.map((attachment) => {
        const entityTitle =
          attachment.entity_type === "task"
            ? taskMap.get(attachment.entity_id)
            : attachment.entity_type === "note"
            ? noteMap.get(attachment.entity_id)
            : attachment.entity_type === "invoice"
            ? invoiceMap.get(attachment.entity_id)
            : projectMap.get(attachment.entity_id);

        return {
          ...attachment,
          entityTitle: entityTitle || "Workspace item",
          entityHref: getEntityHref(attachment),
          entityLabel: getEntityLabel(attachment),
        };
      })
    );
    setLoading(false);
  }, [activeTeamId, initialized, supabase]);

  useEffect(() => {
    const timer = window.setTimeout(() => {
      void fetchDocuments();
    }, 0);

    return () => window.clearTimeout(timer);
  }, [fetchDocuments]);

  return {
    documents,
    loading,
    refetch: fetchDocuments,
  };
}
