"use client"

import { useCallback, useEffect, useMemo, useState } from "react"
import { useRouter } from "next/navigation"
import Link from "next/link"
import { apiClient } from "@/lib/api/client"
import { Button } from "@/components/ui/button"
import { ArrowLeft, Loader2 } from "lucide-react"
import { OfficeEditorChrome } from "@/components/drive/office-editor-chrome"
import { RichTextDocumentEditor } from "@/components/drive/richtext-document"
import { useDriveMutations, useDriveShares } from "@/lib/api/hooks/use-drive-queries"
import { displayFileBaseName } from "@/lib/drive/display-file-name"
import { resolveRenameName } from "@/lib/drive/drive-default-name"
import { driveFolderHref } from "@/lib/drive/drive-sidebar-tree"
import { buildDriveEditHref, resolveDriveEditReturnTo } from "@/lib/drive/drive-url"
import { useDriveDocumentTitle } from "@/lib/drive/use-drive-document-title"
import { useDriveUIStore } from "@/lib/stores/drive-ui-store"
import { colorForGuestId } from "@/lib/drive/guest-editor-identity"
import type { RichTextSaveStatus, RichTextSessionResponse } from "@/lib/drive/richtext-types"
import { useChromeIdentity } from "@/lib/hooks/use-chrome-identity"
import { cn } from "@/lib/utils"

function fileNameFromPath(filePath: string): string {
  return filePath.split("/").filter(Boolean).pop() ?? filePath
}

function renameTargetPath(filePath: string, newName: string): string {
  const parent = filePath.replace(/\/[^/]+$/, "") || "/"
  const base = parent === "/" ? "" : parent
  return `${base}/${newName}`.replace(/\/+/g, "/") || `/${newName}`
}

function saveStatusLabel(status: RichTextSaveStatus): string {
  switch (status) {
    case "saving":
      return "Enregistrement…"
    case "saved":
      return "Enregistré"
    case "error":
      return "Erreur d'enregistrement"
    default:
      return ""
  }
}

export function RichTextEditor({
  filePath,
  returnTo,
}: {
  filePath: string
  returnTo?: string | null
}) {
  const router = useRouter()
  const identity = useChromeIdentity()
  const setSharePath = useDriveUIStore((s) => s.setSharePath)
  const [session, setSession] = useState<RichTextSessionResponse | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [saveStatus, setSaveStatus] = useState<RichTextSaveStatus>("idle")
  const [displayPath, setDisplayPath] = useState(filePath)

  useEffect(() => {
    setDisplayPath(filePath)
  }, [filePath])

  const fileName = fileNameFromPath(displayPath)
  const title = displayFileBaseName(fileName)
  useDriveDocumentTitle(title)

  const backHref = useMemo(
    () =>
      resolveDriveEditReturnTo(returnTo, displayPath, (folderPath) =>
        driveFolderHref("files", folderPath)
      ),
    [returnTo, displayPath]
  )

  const { data: sharesData } = useDriveShares(displayPath, Boolean(displayPath))
  const { rename } = useDriveMutations()

  useEffect(() => {
    let cancelled = false
    setSession(null)
    setError(null)
    void (async () => {
      try {
        const res = await apiClient.post<RichTextSessionResponse>("/richtext/session", {
          path: displayPath,
          mode: "edit",
        })
        if (!cancelled) setSession(res)
      } catch (e) {
        if (!cancelled) setError(e instanceof Error ? e.message : "Impossible d'ouvrir le document")
      }
    })()
    return () => {
      cancelled = true
    }
  }, [displayPath])

  const handleRename = useCallback(
    async (input: string) => {
      const newName = resolveRenameName({ name: fileName, type: "file" }, input)
      if (displayFileBaseName(fileName) === input.trim()) return
      await rename.mutateAsync({ path: displayPath, new_name: newName })
      const nextPath = renameTargetPath(displayPath, newName)
      setDisplayPath(nextPath)
      router.replace(buildDriveEditHref(nextPath, returnTo ?? undefined, "richtext"))
    },
    [displayPath, fileName, rename, returnTo, router]
  )

  const openShare = useCallback(() => {
    setSharePath(displayPath)
  }, [displayPath, setSharePath])

  const statusText = saveStatusLabel(saveStatus)
  const collabUserName = identity?.name?.trim() || identity?.email || "Utilisateur"
  const collabUserColor = colorForGuestId(identity?.email ?? collabUserName)

  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>
        <Button variant="outline" asChild>
          <Link href={backHref}>
            <ArrowLeft className="mr-2 h-4 w-4" />
            Retour
          </Link>
        </Button>
      </div>
    )
  }

  return (
    <div className="flex h-full min-h-0 flex-col bg-background">
      <OfficeEditorChrome
        backHref={backHref}
        backLabel="Drive"
        title={title}
        onRename={handleRename}
        renameDisabled={rename.isPending}
        shares={sharesData?.shares ?? []}
        onShareClick={openShare}
        showShare
        showAccount
        trailing={
          statusText ? (
            <span
              className={cn(
                "text-xs text-muted-foreground",
                saveStatus === "error" && "text-destructive"
              )}
            >
              {statusText}
            </span>
          ) : null
        }
      />
      <div className="min-h-0 flex-1">
        {!session ? (
          <div className="flex h-full items-center justify-center">
            <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
          </div>
        ) : (
          <RichTextDocumentEditor
            session={session}
            mode="edit"
            userName={collabUserName}
            userColor={collabUserColor}
            onSaveStatus={setSaveStatus}
          />
        )}
      </div>
    </div>
  )
}
