import { openOcrTextInNewTab } from '../utils/ocr';
import type {
  EnsureAssetUrl,
  EnsurePreviewData,
  GetDocumentAsset,
  DocumentLike as OcrDocumentLike,
} from '../utils/ocr';

type ResolveApiPath = (path: string) => string;

export type DocumentLike = OcrDocumentLike;

const asyncFalse = async () => false;

const resolveDocumentDownloadHref = (document: DocumentLike | null | undefined, resolveApiPath?: ResolveApiPath | null): string | null => {
  if (!document || !resolveApiPath) {
    return null;
  }
  const downloadPath = (document.current_version as { download_path?: string | null } | null | undefined)?.download_path;
  if (!downloadPath) {
    return null;
  }
  return resolveApiPath(downloadPath);
};

const hasDocumentOcrAsset = (document: DocumentLike | null | undefined, getDocumentAsset?: GetDocumentAsset | null): boolean => {
  if (!document || !getDocumentAsset) {
    return false;
  }
  return Boolean(getDocumentAsset(document, 'ocr-text'));
};

interface CreateDocumentActionStateArgs {
  document: DocumentLike | null;
  resolveApiPath?: ResolveApiPath | null;
  ensurePreviewData: EnsurePreviewData;
  ensureAssetUrl: EnsureAssetUrl;
  getDocumentAsset?: GetDocumentAsset | null;
  notifyApiError?: (error: unknown, message: string) => void;
  ocrErrorMessage?: string;
}

export const createDocumentActionState = ({
  document,
  resolveApiPath,
  ensurePreviewData,
  ensureAssetUrl,
  getDocumentAsset,
  notifyApiError,
  ocrErrorMessage = 'Unable to open OCR text.',
}: CreateDocumentActionStateArgs) => {
  if (!document) {
    return {
      downloadHref: null,
      hasOcr: false,
      openOcr: asyncFalse,
    };
  }

  const downloadHref = resolveDocumentDownloadHref(document, resolveApiPath);
  const hasOcr = hasDocumentOcrAsset(document, getDocumentAsset);

  const openOcr = hasOcr
    ? async () => {
        try {
          const success = await openOcrTextInNewTab({
            document,
            ensurePreviewData,
            getDocumentAsset,
            ensureAssetUrl,
          });
          if (!success) {
            notifyApiError?.(new Error('OCR text URL unavailable.'), ocrErrorMessage);
          }
          return success;
        } catch (error) {
          notifyApiError?.(error, ocrErrorMessage);
          throw error;
        }
      }
    : asyncFalse;

  return {
    downloadHref,
    hasOcr,
    openOcr,
  };
};

export const documentActionsTestExports = {
  resolveDocumentDownloadHref,
  hasDocumentOcrAsset,
};
