"use client"

import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import Link from "next/link"
import { Button } from "@/components/ui/button"
import { getOnlyOfficeUrl } from "@/lib/runtime-config"
import { ArrowLeft } from "lucide-react"
import { OnlyOfficeMount } from "@/components/drive/onlyoffice-mount"
import { OfficeEditorChrome } from "@/components/drive/office-editor-chrome"
import { displayFileBaseName } from "@/lib/drive/display-file-name"
import { getGuestEditorIdentity } from "@/lib/drive/guest-editor-identity"
import { resolvePublicShareEditReturnTo, shouldShowPublicShareEditorBack } from "@/lib/drive/public-share-url"
import type { PublicShareRootType } from "@/lib/drive/public-share-url"
import { resolveOnlyOfficeEditorKind } from "@/lib/drive/onlyoffice-formats"
import { useDriveDocumentTitle } from "@/lib/drive/use-drive-document-title"

function fileNameFromPath(filePath: string, fallback?: string): string {
  const base = filePath.split("/").filter(Boolean).pop()
  return base || fallback || filePath
}

export function PublicOfficeEditor({
  token,
  filePath,
  password,
  returnTo,
  mode = "edit",
  fileDisplayName,
  shareRoot,
}: {
  token: string
  filePath: string
  password?: string
  returnTo?: string | null
  mode?: "edit" | "view"
  fileDisplayName?: string
  shareRoot?: PublicShareRootType | null
}) {
  const instanceSeq = useRef(0)
  const guest = useMemo(() => getGuestEditorIdentity(token), [token])
  const [config, setConfig] = useState<Record<string, unknown> | null>(null)
  const [serverUrl, setServerUrl] = useState("")
  const [editorId, setEditorId] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [resolvedMode, setResolvedMode] = useState<"edit" | "view">(mode)

  const fileName = fileDisplayName || fileNameFromPath(filePath)
  const title = displayFileBaseName(fileName)
  const editorKind = resolveOnlyOfficeEditorKind({ name: fileName })
  useDriveDocumentTitle(title, editorKind)

  const backHref = useMemo(
    () => resolvePublicShareEditReturnTo(token, returnTo, filePath),
    [token, returnTo, filePath]
  )
  const showBack = shouldShowPublicShareEditorBack(shareRoot, returnTo, filePath)

  useEffect(() => {
    let cancelled = false
    setConfig(null)
    setServerUrl("")
    setEditorId(null)
    setError(null)
    setResolvedMode(mode)

    void (async () => {
      try {
        const res = await fetch(
          `/api/v1/drive/public/shares/${encodeURIComponent(token)}/office/session`,
          {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
              path: filePath,
              mode,
              password: password ?? "",
              guest_id: guest.guestId,
              guest_name: guest.guestName,
              display_name: fileName,
            }),
          }
        )
        if (!res.ok) throw new Error("session_failed")
        const data = (await res.json()) as {
          config: Record<string, unknown>
          serverUrl: string
          mode?: "edit" | "view"
        }
        if (cancelled) return
        instanceSeq.current += 1
        setConfig(data.config)
        setServerUrl(data.serverUrl || getOnlyOfficeUrl() || "")
        setEditorId(`ultidrive-public-editor-${instanceSeq.current}`)
        if (data.mode === "edit" || data.mode === "view") {
          setResolvedMode(data.mode)
        } else {
          const editorConfig = data.config?.editorConfig as { mode?: string } | undefined
          if (editorConfig?.mode === "edit" || editorConfig?.mode === "view") {
            setResolvedMode(editorConfig.mode)
          }
        }
      } catch {
        if (!cancelled) setError("Impossible de charger l’éditeur.")
      }
    })()

    return () => {
      cancelled = true
    }
  }, [token, filePath, password, mode, fileName])

  const handleEditorError = useCallback((message: string) => {
    setError(message)
  }, [])

  if (error) {
    return (
      <div className="flex h-dvh flex-col items-center justify-center gap-4">
        <p className="text-destructive">{error}</p>
        {showBack ? (
          <Button asChild variant="outline">
            <Link href={backHref}>
              <ArrowLeft className="mr-2 h-4 w-4" />
              Retour
            </Link>
          </Button>
        ) : null}
      </div>
    )
  }

  if (!config || !editorId || !serverUrl) {
    return <p className="p-8 text-center text-muted-foreground">Ouverture du document…</p>
  }

  return (
    <div className="flex h-dvh flex-col">
      <OfficeEditorChrome
        backHref={backHref}
        backLabel="Partage"
        showBack={showBack}
        title={title}
        trailing={
          resolvedMode === "view" ? (
            <span className="rounded-md bg-muted px-2 py-1 text-xs text-muted-foreground">
              Lecture seule
            </span>
          ) : null
        }
      />
      <div className="relative min-h-0 flex-1">
        <OnlyOfficeMount
          editorId={editorId}
          documentServerUrl={serverUrl.replace(/\/$/, "")}
          config={config}
          onError={handleEditorError}
          scriptId="onlyoffice-docs-api-public"
        />
      </div>
    </div>
  )
}
