import type { DriveFileInfo } from "@/lib/api/types"
import { blobForPreview } from "@/lib/api/drive-download"

export interface PublicShareView {
  token: string
  name: string
  item_type: "file" | "folder"
  path: string
  permissions: number
  owner_id?: string
  owner_displayname?: string
  files?: DriveFileInfo[]
  file?: DriveFileInfo
}

/** Label for "Partagé par …" — display name, then local part of owner id, then fallback. */
export function publicShareOwnerLabel(data: Pick<PublicShareView, "owner_displayname" | "owner_id">): string {
  const display = data.owner_displayname?.trim()
  if (display) return display
  const id = data.owner_id?.trim()
  if (!id) return "Utilisateur"
  const at = id.indexOf("@")
  return at > 0 ? id.slice(0, at) : id
}

export function publicShareHref(token: string, path = "/"): string {
  const base = `/drive/s/${encodeURIComponent(token)}`
  const trimmed = path.replace(/^\/+|\/+$/g, "")
  if (!trimmed) return base
  return `${base}/${trimmed.split("/").map(encodeURIComponent).join("/")}`
}

export function folderPathFromPublicSegments(segments: string[] | undefined): string {
  if (!segments?.length) return "/"
  return "/" + segments.map((s) => decodeURIComponent(s)).join("/")
}

/** Extract NC or Ultidrive public share token from a share URL. */
export function extractShareTokenFromURL(url: string): string | null {
  const trimmed = url.trim()
  if (!trimmed) return null
  try {
    const parsed = new URL(trimmed, "http://localhost")
    const match =
      parsed.pathname.match(/\/index\.php\/s\/([^/]+)/) ??
      parsed.pathname.match(/\/drive\/s\/([^/]+)/) ??
      parsed.pathname.match(/\/s\/([^/]+)/)
    return match ? decodeURIComponent(match[1]) : null
  } catch {
    return null
  }
}

/** Prefer Ultidrive `/drive/s/{token}` URLs (absolute when origin known). */
export function normalizePublicShareURL(
  url: string,
  token?: string,
  origin?: string
): string {
  const resolvedToken = token?.trim() || extractShareTokenFromURL(url)
  if (!resolvedToken) return url
  const href = publicShareHref(resolvedToken)
  const base = origin ?? (typeof window !== "undefined" ? window.location.origin : "")
  return base ? `${base.replace(/\/$/, "")}${href}` : href
}

export function publicShareDownloadApiPath(
  token: string,
  filePath: string,
  password?: string
): string {
  const parts = filePath
    .replace(/^\/+/, "")
    .split("/")
    .filter(Boolean)
    .map((seg) => encodeURIComponent(seg))
  const base = `/api/v1/drive/public/shares/${encodeURIComponent(token)}/download/${parts.join("/")}`
  if (!password) return base
  return `${base}?password=${encodeURIComponent(password)}`
}

export function publicSharePreviewApiPath(
  token: string,
  file: { path: string; name: string },
  password?: string,
  width = 400,
  height = 300
): string {
  const params = new URLSearchParams({
    path: publicShareDownloadPath(file),
    w: String(width),
    h: String(height),
  })
  if (password) params.set("password", password)
  return `/api/v1/drive/public/shares/${encodeURIComponent(token)}/preview?${params.toString()}`
}

export async function fetchPublicShare(
  token: string,
  path = "/",
  password?: string
): Promise<PublicShareView> {
  const params = new URLSearchParams()
  if (path && path !== "/") params.set("path", path)
  if (password) params.set("password", password)
  const qs = params.toString()
  const res = await fetch(
    `/api/v1/drive/public/shares/${encodeURIComponent(token)}${qs ? `?${qs}` : ""}`
  )
  if (!res.ok) {
    throw new Error(res.status === 403 ? "password_required" : "share_unavailable")
  }
  return (await res.json()) as PublicShareView
}

export function publicShareDownloadPath(file: { path: string; name: string }): string {
  const path = (file.path ?? "").trim() || "/"
  if (path === "/") return "/"
  if (path.endsWith(`/${file.name}`) || path === `/${file.name}`) return path
  return `${path.replace(/\/$/, "")}/${file.name}`.replace(/\/+/g, "/")
}

export async function fetchPublicShareBlob(
  token: string,
  file: { path: string; name: string; mime_type?: string },
  password?: string
): Promise<Blob> {
  const logical = publicShareDownloadPath(file)
  const res = await fetch(publicShareDownloadApiPath(token, logical, password))
  if (!res.ok) {
    throw new Error("download_failed")
  }
  const raw = await res.blob()
  return blobForPreview(raw, file.mime_type ?? "", file.name)
}
