"use client";
import { useUploadCompanyDocuments } from "@/hooks/queries";
import { fileService, FailedFile } from "@/lib/api";
import {
  MAX_DOCUMENT_FILES,
  validateDocumentFile,
} from "@/utils/shared";
import { ChangeEvent, useState } from "react";

interface IProps {
  /** Present in edit mode (company exists); drives the upload strategy. */
  companyId?: string;
  /** Current document file ids held by the form. */
  value: string[];
  /** Persists the updated document file id list back to the form. */
  onChange: (ids: string[]) => void;
}

/**
 * Owns the multi-file document upload lifecycle for the company form.
 *
 * - Edit mode (companyId set): uploads via `POST /companies/:id/documents`, which
 *   appends + links files server-side and reports per-file failures.
 * - Create mode (no company yet): uploads via `POST /files/upload/batch` and
 *   appends the returned ids to the form so they're sent with the create call.
 */
const useCompanyDocumentsPresenter = ({
  companyId,
  value,
  onChange,
}: IProps) => {
  const [isUploading, setIsUploading] = useState(false);
  const [removingFileId, setRemovingFileId] = useState<string | null>(null);
  const [uploadProgress, setUploadProgress] = useState(0);
  const [failed, setFailed] = useState<FailedFile[]>([]);
  const [errorMessage, setErrorMessage] = useState<string | undefined>();

  const isBusy = isUploading || removingFileId !== null;

  const { mutateAsync: uploadToCompany } = useUploadCompanyDocuments(
    companyId ?? "",
  );

  const validateSelection = (files: File[]): string | null => {
    if (value.length + files.length > MAX_DOCUMENT_FILES) {
      return `You can attach at most ${MAX_DOCUMENT_FILES} documents.`;
    }
    for (const file of files) {
      const error = validateDocumentFile({ file });
      if (error) return `${file.name}: ${error}`;
    }
    return null;
  };

  const uploadFiles = async (files: File[]) => {
    if (companyId) {
      const response = await uploadToCompany(files);
      onChange(response.data.document_file_ids ?? value);
      return response.data.failed ?? [];
    }

    const result = await fileService.uploadBatch({
      files,
      category: "company_document",
      onProgress: setUploadProgress,
    });
    const newIds = (result.uploaded ?? []).map((item) => item.file_id);
    onChange([...value, ...newIds]);
    return result.failed ?? [];
  };

  const onSelectFiles = async (event: ChangeEvent<HTMLInputElement>) => {
    if (isBusy) return;

    const input = event.target;
    const files = input.files ? Array.from(input.files) : [];
    // Reset so selecting the same file again re-triggers change.
    input.value = "";
    if (!files.length) return;

    const validationError = validateSelection(files);
    if (validationError) {
      setErrorMessage(validationError);
      return;
    }

    setErrorMessage(undefined);
    setFailed([]);
    setIsUploading(true);
    setUploadProgress(0);

    try {
      setFailed(await uploadFiles(files));
    } catch (error) {
      console.error("ERROR caught while uploading company documents:", error);
      setErrorMessage("Failed to upload documents. Please try again.");
    } finally {
      setIsUploading(false);
    }
  };

  const onRemove = async (fileId: string) => {
    if (isBusy) return;

    setRemovingFileId(fileId);
    setErrorMessage(undefined);

    try {
      // In create mode the file is an orphan in storage (not linked to any
      // company), so clean it up before dropping it from the form. In edit mode
      // the removal is persisted by the form's update (PUT replaces the full
      // document list).
      if (!companyId) {
        await fileService.deleteFile(fileId);
      }

      onChange(value.filter((id) => id !== fileId));
    } catch (error) {
      console.error("ERROR caught while deleting company document:", error);
      setErrorMessage("Failed to remove document. Please try again.");
    } finally {
      setRemovingFileId(null);
    }
  };

  return {
    isUploading,
    isBusy,
    removingFileId,
    uploadProgress,
    failed,
    errorMessage,
    onSelectFiles,
    onRemove,
  };
};

export default useCompanyDocumentsPresenter;
