"use client"

import { useCallback, useEffect, useMemo, useState } from "react"
import Link from "next/link"
import { Button } from "@/components/ui/button"
import { ArrowLeft } from "lucide-react"
import { RichTextDocumentEditor } from "@/components/drive/richtext-document"
import {
  DocsEditorLoadingShell,
  useDocsEditorLoadingState,
} from "@/components/drive/richtext/docs-editor-loading-shell"
import { displayFileBaseName } from "@/lib/drive/display-file-name"
import { resolvePublicShareEditReturnTo, shouldShowPublicShareEditorBack } from "@/lib/drive/public-share-url"
import type { PublicShareRootType } from "@/lib/drive/public-share-url"
import { useDriveDocumentTitle } from "@/lib/drive/use-drive-document-title"
import { getGuestEditorIdentity } from "@/lib/drive/guest-editor-identity"
import type { RichTextSessionResponse } from "@/lib/drive/richtext-types"
import type { DocPageSetup } from "@/lib/drive/doc-page-setup"
import { fetchPublicShareBlob } from "@/lib/api/public-share"

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

export function PublicRichTextEditor({
  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 guest = useMemo(() => getGuestEditorIdentity(token), [token])
  const [session, setSession] = useState<RichTextSessionResponse | 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)
  useDriveDocumentTitle(title, "docs")

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

  useEffect(() => {
    let cancelled = false
    setSession(null)
    setError(null)
    void (async () => {
      try {
        const res = await fetch(
          `/api/v1/drive/public/shares/${encodeURIComponent(token)}/richtext/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 indisponible")
        const data = (await res.json()) as RichTextSessionResponse
        if (!cancelled) {
          setSession(data)
          setResolvedMode(data.mode === "view" ? "view" : mode)
        }
      } catch (e) {
        if (!cancelled) setError(e instanceof Error ? e.message : "Impossible d'ouvrir le document")
      }
    })()
    return () => {
      cancelled = true
    }
  }, [token, filePath, mode, password, guest.guestId, guest.guestName, fileName])

  const fetchSourceBytes = useCallback(
    async (path: string) => {
      const blob = await fetchPublicShareBlob(
        token,
        { path, name: path.split("/").pop() ?? path },
        password
      )
      return blob.arrayBuffer()
    },
    [token, password]
  )

  const importApi = useCallback(
    async (body: {
      source_path: string
      content: Record<string, unknown>
      pageSetup?: DocPageSetup | null
    }) => {
      const res = await fetch(
        `/api/v1/drive/public/shares/${encodeURIComponent(token)}/richtext/import`,
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ ...body, password: password ?? "", display_name: fileName }),
        }
      )
      if (!res.ok) throw new Error("Import impossible")
    },
    [token, password, fileName]
  )

  const chrome = useMemo(
    () => ({
      title,
      backHref,
      backLabel: "Partage",
      showBack,
      showShare: false,
      showAccount: false,
      trailing:
        resolvedMode === "view" ? (
          <span className="text-xs text-muted-foreground">Lecture seule</span>
        ) : (
          <span
            className="rounded px-2 py-1 text-xs font-semibold text-white"
            style={{ backgroundColor: guest.color }}
          >
            {guest.guestName}
          </span>
        ),
    }),
    [title, backHref, showBack, resolvedMode, guest.color, guest.guestName]
  )

  const { documentLoading, documentPhase, onDocumentLoadingChange } = useDocsEditorLoadingState(
    session?.roomId ?? filePath
  )

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

  return (
    <DocsEditorLoadingShell
      title={title}
      resolvingFile={false}
      awaitingSession={!session}
      documentLoading={Boolean(session) && documentLoading}
      documentPhase={documentPhase}
    >
      {session ? (
        <RichTextDocumentEditor
          session={session}
          mode={resolvedMode}
          userName={guest.guestName}
          userColor={guest.color}
          fetchSourceBytes={fetchSourceBytes}
          importApi={importApi}
          chrome={chrome}
          deferSplash
          onLoadingChange={onDocumentLoadingChange}
        />
      ) : null}
    </DocsEditorLoadingShell>
  )
}
