import type { DriveFileInfo } from "@/lib/api/types"
import { isOnlyOfficeFile, isOnlyOfficeExtension, fileExtension as officeFileExtension } from "@/lib/drive/onlyoffice-formats"
import { isRichTextFile, isUltidocPath } from "@/lib/drive/richtext-formats"
import { isExcalidrawFile } from "@/lib/drive/ultidraw-formats"

export type DrivePreviewKind = "image" | "video" | "audio" | "pdf" | "text"

const IMAGE_EXT = new Set([
  "jpg",
  "jpeg",
  "png",
  "gif",
  "webp",
  "svg",
  "bmp",
  "avif",
  "heic",
  "heif",
  "ico",
  "tif",
  "tiff",
  "apng",
  "jfif",
])

const VIDEO_EXT = new Set(["mp4", "webm", "mov", "mkv", "ogv", "m4v", "3gp", "avi"])

const AUDIO_EXT = new Set(["mp3", "wav", "ogg", "flac", "m4a", "aac", "opus", "weba", "aiff", "mid", "midi"])

const TEXT_EXT = new Set([
  "md",
  "markdown",
  "txt",
  "json",
  "yaml",
  "yml",
  "log",
  "ini",
  "conf",
  "cfg",
  "env",
])

function isTextMime(mime: string): boolean {
  if (!mime.startsWith("text/")) return false
  if (mime.includes("html") || mime.includes("calendar")) return false
  return true
}

function fileExt(name: string): string {
  return name.split(".").pop()?.toLowerCase() ?? ""
}

export function isSvgFile(file: { name: string; mime_type?: string }): boolean {
  const mime = (file.mime_type ?? "").toLowerCase()
  return mime === "image/svg+xml" || mime === "application/svg+xml" || fileExt(file.name) === "svg"
}

/** Formats the browser renders from the original file — skip Nextcloud raster preview. */
export function driveClientNativePreview(file: {
  name: string
  mime_type?: string
  type?: string
}): boolean {
  if (file.type === "directory") return false
  const kind = drivePreviewKind(file)
  if (!kind) return false
  if (kind === "video" || kind === "audio" || kind === "pdf" || kind === "text") return true
  if (kind === "image" && isSvgFile(file)) return true
  return false
}

export function isOfficeFormat(file: { name: string; mime_type?: string }): boolean {
  return isOnlyOfficeFile(file)
}

/** Word-processor formats edited in TipTap (when rich-text editor is enabled). */
export function shouldOpenInRichTextEditor(file: {
  name: string
  mime_type?: string
  type?: string
}): boolean {
  if (file.type === "directory") return false
  if (isUltidocPath(file.name)) return true
  if (drivePreviewKind(file) === "text") {
    const ext = officeFileExtension(file.name)
    return ext === "md" || ext === "markdown" || ext === "txt" || ext === "html" || ext === "htm"
  }
  if (drivePreviewKind(file)) return false
  return isRichTextFile(file)
}

/** Excalidraw drawings edited in UltiDraw. */
export function shouldOpenInUltidrawEditor(file: {
  name: string
  mime_type?: string
  type?: string
}): boolean {
  if (file.type === "directory") return false
  return isExcalidrawFile(file)
}

/** Open in OnlyOffice for cell/slide/diagram only (word formats use TipTap). */
export function shouldOpenInOnlyOffice(file: {
  name: string
  mime_type?: string
  type?: string
}): boolean {
  if (file.type === "directory") return false
  if (shouldOpenInUltidrawEditor(file)) return false
  if (shouldOpenInRichTextEditor(file)) return false
  if (drivePreviewKind(file)) return false
  if (!isOfficeFormat(file)) return false
  const ext = officeFileExtension(file.name)
  return isOnlyOfficeExtension(ext) && !isRichTextFile(file)
}

export function drivePreviewKind(file: {
  name: string
  mime_type?: string
}): DrivePreviewKind | null {
  const mime = (file.mime_type ?? "").toLowerCase()
  if (mime.startsWith("image/") || mime === "application/svg+xml") return "image"
  if (mime.startsWith("video/")) return "video"
  if (mime.startsWith("audio/")) return "audio"
  if (mime === "application/pdf") return "pdf"
  if (isTextMime(mime)) return "text"
  if (mime === "application/json" || mime === "application/x-yaml") return "text"

  const ext = fileExt(file.name)
  if (IMAGE_EXT.has(ext)) return "image"
  if (VIDEO_EXT.has(ext)) return "video"
  if (AUDIO_EXT.has(ext)) return "audio"
  if (ext === "pdf") return "pdf"
  if (TEXT_EXT.has(ext)) return "text"
  return null
}

/** Files that can use Nextcloud server-side preview thumbnails. */
export function driveServerThumbnail(file: { name: string; mime_type?: string; type?: string }): boolean {
  if (file.type === "directory") return false
  if (isOfficeFormat(file)) return true
  const kind = drivePreviewKind(file)
  if (kind === "pdf") return true
  if (kind === "image" && !isSvgFile(file)) return true
  return false
}

export function isPreviewNavigable(file: {
  name: string
  mime_type?: string
  type?: string
}): boolean {
  return file.type !== "directory" && drivePreviewKind(file) !== null
}

export function previewTargetToFileInfo(target: {
  path: string
  name: string
  mime_type: string
  is_favorite: boolean
}): DriveFileInfo {
  return {
    path: target.path,
    name: target.name,
    type: "file",
    size: 0,
    mime_type: target.mime_type,
    last_modified: "",
    etag: "",
    is_favorite: target.is_favorite,
  }
}
export function toPreviewTarget(file: {
  path: string
  name: string
  mime_type?: string
  is_favorite?: boolean
}): { path: string; name: string; mime_type: string; is_favorite: boolean } {
  return {
    path: file.path,
    name: file.name,
    mime_type: file.mime_type ?? "",
    is_favorite: file.is_favorite ?? false,
  }
}
