"use client"

import dynamic from "next/dynamic"
import Link from "next/link"
import { useRouter } from "next/navigation"
import { useEffect, useState, type ReactNode } from "react"
import { ChevronRight, Download, FolderOpen, Loader2, Lock } from "lucide-react"
import { DocsLoadingSplash } from "@/components/drive/richtext/docs-loading-splash"
import { toast } from "sonner"
import { PublicShareFolderView } from "@/components/drive/public-share-folder-view"
import { FilePreviewDialog } from "@/components/drive/file-preview-dialog"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import {
  fetchPublicShareBlob,
  publicShareDownloadApiPath,
  publicShareHref,
  publicShareOwnerLabel,
  type PublicShareView,
} from "@/lib/api/public-share"
import type { DriveFileInfo } from "@/lib/api/types"
import { drivePreviewKind, isSvgFile } from "@/lib/drive/drive-preview"
import { SvgPreviewViewer } from "@/components/drive/svg-preview-viewer"
import { PUBLIC_SHARE_INSET_X } from "@/lib/drive/drive-chrome-classes"
import {
  shouldOpenInOnlyOffice,
  shouldOpenInRichTextEditor,
  shouldOpenInUltidrawEditor,
} from "@/lib/drive/drive-preview"
import {
  sharePermCanEdit,
} from "@/lib/drive/drive-share-permissions"
import { buildPublicShareEditHref, persistPublicShareRootType } from "@/lib/drive/public-share-url"
import { suitePublicAsset } from "@/lib/suite/suite-public-asset"
import {
  SUITE_APP_LOGO_LOCKUP_CLASS,
  SUITE_APP_LOGO_MARK_CLASS,
  SUITE_APP_LOGO_TEXT_CLASS,
} from "@/lib/suite/suite-chrome-classes"
import { SuiteThemeShell } from "@/components/suite/suite-theme-shell"
import { cn } from "@/lib/utils"
import { filterHiddenDriveSidecars } from "@/lib/drive/drive-hidden-files"

const PdfPreviewViewer = dynamic(
  () => import("@/components/drive/pdf-preview-viewer").then((m) => m.PdfPreviewViewer),
  { ssr: false }
)

function PublicShareBreadcrumb({
  token,
  rootShareName,
  path,
}: {
  token: string
  rootShareName: string
  path: string
}) {
  const parts = path.replace(/^\/+|\/+$/g, "").split("/").filter(Boolean)
  const crumbs: { label: string; href: string }[] = [
    { label: rootShareName || "Partage", href: publicShareHref(token) },
  ]
  let acc = ""
  for (const part of parts) {
    acc += `/${part}`
    crumbs.push({ label: part, href: publicShareHref(token, acc) })
  }

  return (
    <nav
      className="flex flex-wrap items-center gap-1 text-sm"
      aria-label="Fil d'Ariane"
    >
      {crumbs.map((crumb, i) => (
        <span key={crumb.href} className="flex items-center gap-1">
          {i > 0 ? <ChevronRight className="h-4 w-4 text-muted-foreground" aria-hidden /> : null}
          {i === crumbs.length - 1 ? (
            <span className="font-medium text-[#3c4043] dark:text-[#e8eaed]">{crumb.label}</span>
          ) : (
            <Link href={crumb.href} className="text-[#1967d2] hover:underline dark:text-[#8ab4f8]">
              {crumb.label}
            </Link>
          )}
        </span>
      ))}
    </nav>
  )
}

function usePublicShareRootName(token: string, path: string, currentName: string) {
  const storageKey = `public-share-root:${token}`
  const [rootName, setRootName] = useState(currentName)

  useEffect(() => {
    if (typeof window === "undefined") return
    if (path === "/" && currentName) {
      sessionStorage.setItem(storageKey, currentName)
      setRootName(currentName)
      return
    }
    const stored = sessionStorage.getItem(storageKey)
    if (stored) setRootName(stored)
  }, [token, path, currentName, storageKey])

  return rootName
}

function PublicFilePreview({
  token,
  file,
  password,
}: {
  token: string
  file: DriveFileInfo
  password?: string
}) {
  const [blobUrl, setBlobUrl] = useState<string | null>(null)
  const [textContent, setTextContent] = useState<string | null>(null)
  const [svgMarkup, setSvgMarkup] = useState<string | null>(null)
  const [loading, setLoading] = useState(true)
  const kind = drivePreviewKind(file)
  const isSvg = isSvgFile(file)

  useEffect(() => {
    let cancelled = false
    let objectUrl: string | null = null
    setLoading(true)
    void fetchPublicShareBlob(token, file, password)
      .then(async (blob) => {
        if (cancelled) return
        if (kind === "text") {
          setTextContent(await blob.text())
          setBlobUrl(null)
          setSvgMarkup(null)
        } else if (isSvg) {
          setSvgMarkup(await blob.text())
          setBlobUrl(null)
          setTextContent(null)
        } else {
          objectUrl = URL.createObjectURL(blob)
          setBlobUrl(objectUrl)
          setTextContent(null)
          setSvgMarkup(null)
        }
      })
      .catch(() => toast.error("Aperçu indisponible"))
      .finally(() => {
        if (!cancelled) setLoading(false)
      })
    return () => {
      cancelled = true
      if (objectUrl) URL.revokeObjectURL(objectUrl)
    }
  }, [token, file, password, kind, isSvg])

  if (loading) {
    return (
      <div className="flex h-[min(60vh,520px)] items-center justify-center rounded-2xl border border-border bg-[#f8f9fa] dark:bg-[#35363a]">
        <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
      </div>
    )
  }

  if (isSvg && svgMarkup) {
    return (
      <div className="flex max-h-[min(70vh,640px)] min-h-[240px] items-stretch overflow-hidden rounded-2xl border border-border bg-[#f8f9fa] dark:bg-[#35363a]">
        <SvgPreviewViewer markup={svgMarkup} name={file.name} className="min-h-[240px]" />
      </div>
    )
  }
  if (kind === "image" && blobUrl) {
    return (
      <div className="flex max-h-[min(70vh,640px)] items-center justify-center overflow-hidden rounded-2xl border border-border bg-[#f8f9fa] p-4 dark:bg-[#35363a]">
        {/* eslint-disable-next-line @next/next/no-img-element */}
        <img src={blobUrl} alt={file.name} className="max-h-full max-w-full object-contain" />
      </div>
    )
  }
  if (kind === "video" && blobUrl) {
    return (
      <div className="overflow-hidden rounded-2xl border border-border bg-black">
        <video src={blobUrl} controls className="max-h-[min(70vh,640px)] w-full" />
      </div>
    )
  }
  if (kind === "audio" && blobUrl) {
    return (
      <div className="flex items-center justify-center rounded-2xl border border-border bg-[#f8f9fa] px-8 py-12 dark:bg-[#35363a]">
        <audio src={blobUrl} controls className="w-full max-w-lg" />
      </div>
    )
  }
  if (kind === "pdf" && blobUrl) {
    return (
      <div className="h-[min(70vh,640px)] overflow-hidden rounded-2xl border border-border">
        <PdfPreviewViewer blobUrl={blobUrl} name={file.name} />
      </div>
    )
  }
  if (kind === "text" && textContent != null) {
    return (
      <pre className="max-h-[min(60vh,520px)] overflow-auto rounded-2xl border border-border bg-[#f8f9fa] p-4 text-sm dark:bg-[#35363a]">
        {textContent}
      </pre>
    )
  }

  return (
    <div className="rounded-2xl border border-dashed border-border bg-[#f8f9fa] px-6 py-10 text-center dark:bg-[#35363a]">
      <p className="text-sm text-muted-foreground">Aperçu non disponible pour ce type de fichier.</p>
    </div>
  )
}


export function PublicShareViewPanel({
  token,
  path,
  data,
  password,
}: {
  token: string
  path: string
  data: PublicShareView
  password?: string
}) {
  const router = useRouter()
  const file = data.item_type === "file" ? data.file : null
  const files = data.item_type === "folder" ? filterHiddenDriveSidecars(data.files ?? []) : []
  const rootShareName = usePublicShareRootName(token, path, data.name)
  const sharedByLabel = publicShareOwnerLabel(data)
  const permissions = data.permissions ?? 1
  const canEdit = sharePermCanEdit(permissions)

  useEffect(() => {
    persistPublicShareRootType(token, data.item_type)
  }, [token, data.item_type])

  useEffect(() => {
    if (!file) return
    const isEditorFile =
      shouldOpenInRichTextEditor(file) ||
      shouldOpenInUltidrawEditor(file) ||
      shouldOpenInOnlyOffice(file)
    if (!isEditorFile) return
    const returnTo =
      typeof window !== "undefined"
        ? window.location.pathname + window.location.search
        : undefined
    const editor = shouldOpenInUltidrawEditor(file)
      ? "ultidraw"
      : shouldOpenInRichTextEditor(file)
        ? "richtext"
        : "office"
    router.replace(
      buildPublicShareEditHref(
        token,
        file.path,
        returnTo,
        canEdit ? "edit" : "view",
        file.name,
        editor,
        data.item_type
      )
    )
  }, [canEdit, data.item_type, file, router, token])

  const downloadCurrent = () => {
    if (!file) 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()
  }

  if (
    file &&
    (shouldOpenInRichTextEditor(file) ||
      shouldOpenInUltidrawEditor(file) ||
      shouldOpenInOnlyOffice(file))
  ) {
    return <DocsLoadingSplash phase="opening" title={file.name} />
  }

  return (
    <div
      className={cn(
        "mx-auto flex min-h-0 w-full max-w-5xl flex-1 flex-col pb-4",
        PUBLIC_SHARE_INSET_X,
        "pt-3"
      )}
    >
      <div className="mb-3 flex shrink-0 flex-wrap items-center justify-between gap-3">
        <div className="min-w-0 space-y-1">
          <p className="text-xs text-muted-foreground">
            Partagé par <span className="font-medium text-[#3c4043] dark:text-[#e8eaed]">{sharedByLabel}</span>
          </p>
          {data.item_type === "folder" ? (
            <PublicShareBreadcrumb token={token} rootShareName={rootShareName} path={path} />
          ) : null}
        </div>
        {file ? (
          <Button type="button" variant="outline" size="sm" className="gap-2 shrink-0" onClick={downloadCurrent}>
            <Download className="h-4 w-4" />
            Télécharger
          </Button>
        ) : null}
      </div>

      {data.item_type === "folder" ? (
        <PublicShareFolderView
          token={token}
          folderPath={path}
          files={files}
          permissions={data.permissions ?? 1}
          password={password}
          folderTitle={data.name}
        />
      ) : file ? (
        <PublicFilePreview token={token} file={file} password={password} />
      ) : null}
      <FilePreviewDialog />
    </div>
  )
}

export function PublicShareChrome({ children }: { children: ReactNode }) {
  return (
    <SuiteThemeShell>
      <div className="ultimail-app flex h-dvh flex-col overflow-hidden bg-app-canvas" data-drive-app>
      <header className="flex h-16 shrink-0 items-center border-b border-border bg-mail-surface px-4 sm:px-6">
        <Link href="/drive" className={SUITE_APP_LOGO_LOCKUP_CLASS}>
          <img
            src={suitePublicAsset("/ultidrive-mark.svg")}
            alt=""
            className={SUITE_APP_LOGO_MARK_CLASS}
            draggable={false}
            aria-hidden
          />
          <span className={SUITE_APP_LOGO_TEXT_CLASS}>UltiDrive</span>
        </Link>
        <span className="ml-3 hidden text-sm text-muted-foreground sm:inline">
          <FolderOpen className="mr-1 inline h-4 w-4 align-[-2px]" aria-hidden />
          Lien de partage
        </span>
      </header>
      <main className="flex min-h-0 flex-1 flex-col overflow-hidden">{children}</main>
    </div>
    </SuiteThemeShell>
  )
}
