import { downloadDriveFile } from "@/lib/api/drive-download"
import type { DriveFileInfo } from "@/lib/api/types"
import {
  openMountFileExternally,
  shouldOpenMountFileExternally,
} from "@/lib/drive/cloud-native-open"
import {
  drivePreviewKind,
  isPreviewNavigable,
  shouldOpenInOnlyOffice,
  shouldOpenInRichTextEditor,
  shouldOpenInUltidrawEditor,
  toPreviewTarget,
} from "@/lib/drive/drive-preview"
import { driveFolderHref } from "@/lib/drive/drive-sidebar-tree"
import { buildDriveEditHref } from "@/lib/drive/drive-url"
import { openRichTextDocument } from "@/lib/drive/open-rich-text-document"
import { openUltidrawDocument } from "@/lib/drive/open-ultidraw-document"
import { stashDriveEditorReturnTo } from "@/lib/drive/drive-editor-return"
import type { DrivePreviewContext } from "@/lib/stores/drive-ui-store"

export interface OpenDriveItemRouter {
  push: (href: string) => void
}

export interface OpenDriveItemOptions {
  router: OpenDriveItemRouter
  openPreview: (
    files: ReturnType<typeof toPreviewTarget>[],
    index: number,
    context?: Partial<DrivePreviewContext>
  ) => void
  view: "files" | "shared"
  /** Items available for in-preview navigation (current folder, search hits, etc.). */
  contextItems?: DriveFileInfo[]
  isTrash?: boolean
  routeRoot?: string
}

/** Open a drive file or folder the same way as the file browser (preview, editor, download). */
export function openDriveItem(file: DriveFileInfo, options: OpenDriveItemOptions) {
  const {
    router,
    openPreview,
    view,
    contextItems = [file],
    isTrash = false,
    routeRoot,
  } = options
  const allowShare = view !== "shared"

  if (file.type === "directory") {
    router.push(driveFolderHref(view, file.path, undefined, routeRoot))
    return
  }

  if (shouldOpenMountFileExternally(file)) {
    void openMountFileExternally(file).then((opened) => {
      if (!opened) {
        window.alert("Impossible d’ouvrir le document dans l’application cloud.")
      }
    })
    return
  }

  if (drivePreviewKind(file)) {
    const ext = file.name.split(".").pop()?.toLowerCase() ?? ""
    const richTextPreview =
      ext === "md" || ext === "markdown" || ext === "txt" || ext === "html" || ext === "htm"
    if (!richTextPreview) {
      const navigable = contextItems
        .filter((item) => isPreviewNavigable(item))
        .map((item) => toPreviewTarget(item))
      const index = navigable.findIndex((item) => item.path === file.path)
      openPreview(navigable, index >= 0 ? index : 0, { allowShare, isTrash })
      return
    }
  }

  if (shouldOpenInUltidrawEditor(file)) {
    void openUltidrawDocument(file, router).catch(() => {
      window.alert("Impossible d’ouvrir le dessin.")
    })
    return
  }

  if (shouldOpenInRichTextEditor(file)) {
    void openRichTextDocument(file, router).catch(() => {
      window.alert("Impossible d’ouvrir le document.")
    })
    return
  }

  if (shouldOpenInOnlyOffice(file)) {
    stashDriveEditorReturnTo()
    const returnTo =
      typeof window !== "undefined"
        ? window.location.pathname + window.location.search
        : undefined
    router.push(buildDriveEditHref(file.path, returnTo))
    return
  }

  void downloadDriveFile(file.path, file.name, file.name).catch(() => {
    window.alert("Impossible d’ouvrir le fichier.")
  })
}
