import type { DriveFileInfo } from "@/lib/api/types"
import {
  drivePreviewKind,
  isPreviewNavigable,
  shouldOpenInOnlyOffice,
  shouldOpenInRichTextEditor,
  shouldOpenInUltidrawEditor,
  toPreviewTarget,
} from "@/lib/drive/drive-preview"
import { fetchPublicShareBlob, publicShareDownloadApiPath, publicShareHref } from "@/lib/api/public-share"
import { buildPublicShareEditHref } from "@/lib/drive/public-share-url"
import type { DrivePreviewContext } from "@/lib/stores/drive-ui-store"

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

export interface OpenPublicShareItemOptions {
  token: string
  password?: string
  canEdit: boolean
  router: OpenPublicShareItemRouter
  openPreview: (
    files: ReturnType<typeof toPreviewTarget>[],
    index: number,
    context?: Partial<DrivePreviewContext>
  ) => void
  contextItems?: DriveFileInfo[]
}

export function openPublicShareItem(file: DriveFileInfo, options: OpenPublicShareItemOptions) {
  const { token, password, canEdit, router, openPreview, contextItems = [file] } = options

  if (file.type === "directory") {
    router.push(publicShareHref(token, file.path))
    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: false,
        isTrash: false,
        publicShare: { token, password, canEdit },
      })
      return
    }
  }

  if (shouldOpenInUltidrawEditor(file)) {
    const returnTo =
      typeof window !== "undefined"
        ? window.location.pathname + window.location.search
        : undefined
    const mode = canEdit ? "edit" : "view"
    router.push(
      buildPublicShareEditHref(token, file.path, returnTo, mode, file.name, "ultidraw", "folder")
    )
    return
  }

  if (shouldOpenInRichTextEditor(file)) {
    const returnTo =
      typeof window !== "undefined"
        ? window.location.pathname + window.location.search
        : undefined
    const mode = canEdit ? "edit" : "view"
    router.push(
      buildPublicShareEditHref(token, file.path, returnTo, mode, file.name, "richtext", "folder")
    )
    return
  }

  if (shouldOpenInOnlyOffice(file)) {
    const returnTo =
      typeof window !== "undefined"
        ? window.location.pathname + window.location.search
        : undefined
    const mode = canEdit ? "edit" : "view"
    router.push(buildPublicShareEditHref(token, file.path, returnTo, mode, file.name, "office", "folder"))
    return
  }

  const url = publicShareDownloadApiPath(token, file.path, password)
  const anchor = document.createElement("a")
  anchor.href = url
  anchor.download = file.name
  anchor.rel = "noopener"
  document.body.appendChild(anchor)
  anchor.click()
  anchor.remove()
}

export async function downloadPublicShareFile(
  token: string,
  file: DriveFileInfo,
  password?: string
) {
  const blob = await fetchPublicShareBlob(token, file, password)
  const objectUrl = URL.createObjectURL(blob)
  const anchor = document.createElement("a")
  anchor.href = objectUrl
  anchor.download = file.name
  document.body.appendChild(anchor)
  anchor.click()
  anchor.remove()
  URL.revokeObjectURL(objectUrl)
}
