"use client";

import { useCallback, useEffect, useState } from "react";
import { createClient } from "@/lib/supabase/client";
import type { Attachment } from "@/types";

interface UseAttachmentsOptions {
  entityType: Attachment["entity_type"];
  entityId: string | null;
  teamId?: string | null;
  projectId?: string | null;
}

function toAttachmentErrorMessage(error: unknown) {
  const message =
    error instanceof Error ? error.message : "Attachment action failed.";

  if (/bucket/i.test(message) || /storage/i.test(message)) {
    return "Upload failed. The attachments storage bucket is missing or not configured yet.";
  }

  if (/relation .*attachments/i.test(message) || /attachments does not exist/i.test(message)) {
    return "Upload failed. The attachments database table is missing. Run the Phase 1 migrations first.";
  }

  if (/not authenticated/i.test(message)) {
    return "Upload failed. Please sign in again and retry.";
  }

  return message;
}

function sanitizeFileName(name: string) {
  return name.replace(/[^a-zA-Z0-9._-]/g, "-");
}

export function useAttachments({
  entityType,
  entityId,
}: UseAttachmentsOptions) {
  const [attachments, setAttachments] = useState<Attachment[]>([]);
  const [loading, setLoading] = useState(true);
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const supabase = createClient();

  const fetchAttachments = useCallback(async () => {
    if (!entityId) {
      setAttachments([]);
      setLoading(false);
      setError(null);
      return;
    }

    setLoading(true);
    setError(null);

    try {
      const { data, error } = await supabase
        .from("attachments")
        .select("*")
        .eq("entity_type", entityType)
        .eq("entity_id", entityId)
        .order("created_at", { ascending: false });

      if (error) throw error;
      setAttachments((data || []) as Attachment[]);
    } catch (err) {
      setError(toAttachmentErrorMessage(err));
      setAttachments([]);
    } finally {
      setLoading(false);
    }
  }, [entityId, entityType, supabase]);

  useEffect(() => {
    void fetchAttachments();
  }, [fetchAttachments]);

  async function uploadFiles(files: FileList | File[]) {
    if (!entityId) return [];

    const fileList = Array.from(files);
    if (fileList.length === 0) return [];

    setUploading(true);
    setError(null);

    try {
      const uploaded: Attachment[] = [];

      for (const file of fileList) {
        const formData = new FormData();
        formData.append("file", file, sanitizeFileName(file.name));
        formData.append("entityType", entityType);
        formData.append("entityId", entityId);

        const res = await fetch("/api/attachments", {
          method: "POST",
          body: formData,
        });

        const data = await res.json();

        if (!res.ok) {
          throw new Error(
            typeof data?.error === "string"
              ? data.error
              : "Attachment upload failed."
          );
        }

        uploaded.push(data.attachment as Attachment);
      }

      setAttachments((prev) => [...uploaded, ...prev]);
      return uploaded;
    } catch (err) {
      setError(toAttachmentErrorMessage(err));
      return [];
    } finally {
      setUploading(false);
    }
  }

  async function deleteAttachment(attachment: Attachment) {
    setError(null);

    try {
      const res = await fetch("/api/attachments", {
        method: "DELETE",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          attachmentId: attachment.id,
        }),
      });

      const data = await res.json();

      if (!res.ok) {
        throw new Error(
          typeof data?.error === "string"
            ? data.error
            : "Attachment delete failed."
        );
      }

      setAttachments((prev) => prev.filter((item) => item.id !== attachment.id));
    } catch (err) {
      setError(toAttachmentErrorMessage(err));
      throw err;
    }
  }

  return {
    attachments,
    loading,
    uploading,
    error,
    uploadFiles,
    deleteAttachment,
    refetch: fetchAttachments,
  };
}
