"use client"

import { useCallback, useEffect, useMemo, useState } from "react"
import Link from "next/link"
import { useQueryClient } from "@tanstack/react-query"
import { apiClient } from "@/lib/api/client"
import { Button } from "@/components/ui/button"
import { ArrowLeft, Loader2 } from "lucide-react"
import { RichTextDocumentEditor } from "@/components/drive/richtext-document"
import { useDriveFileById, useDriveMutations, useDriveShares } from "@/lib/api/hooks/use-drive-queries"
import { displayFileBaseName } from "@/lib/drive/display-file-name"
import { readDriveEditorReturnTo } from "@/lib/drive/drive-editor-return"
import { resolveRenameName } from "@/lib/drive/drive-default-name"
import { driveFolderHref } from "@/lib/drive/drive-sidebar-tree"
import { 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 { RichTextSessionResponse } from "@/lib/drive/richtext-types"
import type { DriveFileInfo } from "@/lib/api/types"
import { useChromeIdentity } from "@/lib/hooks/use-chrome-identity"

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}`
}

export function RichTextEditor({ fileId }: { fileId: string }) {
  const queryClient = useQueryClient()
  const identity = useChromeIdentity()
  const setSharePath = useDriveUIStore((s) => s.setSharePath)
  const { data: file, error: fileError, isLoading: fileLoading } = useDriveFileById(fileId)
  const displayPath = file?.path ?? ""
  const [session, setSession] = useState<RichTextSessionResponse | null>(null)
  const [sessionError, setSessionError] = useState<string | null>(null)
  const [renameSignal, setRenameSignal] = useState(0)

  const fileName = file?.name ?? fileNameFromPath(displayPath)
  const title = displayFileBaseName(fileName)
  useDriveDocumentTitle(title)

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

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

  const refreshFile = useCallback(async () => {
    await queryClient.invalidateQueries({ queryKey: ["drive", "file", fileId] })
  }, [fileId, queryClient])

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

  const handleRename = useCallback(
    async (input: string) => {
      if (!displayPath) return
      const newName = resolveRenameName({ name: fileName, type: "file" }, input)
      if (displayFileBaseName(fileName) === input.trim()) return
      await rename.mutateAsync({ path: displayPath, new_name: newName })
      await refreshFile()
    },
    [displayPath, fileName, refreshFile, rename]
  )

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

  const moveFile = useMemo((): DriveFileInfo | undefined => {
    if (!file || !displayPath) return undefined
    return {
      ...file,
      path: displayPath,
      name: fileName,
      type: "file",
    }
  }, [displayPath, file, fileName])

  const handleFileMoved = useCallback(
    async (_newPath: string) => {
      await refreshFile()
    },
    [refreshFile]
  )

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

  const chrome = useMemo(
    () => ({
      title,
      onRename: handleRename,
      renameDisabled: rename.isPending,
      backHref,
      backLabel: "Drive",
      showBack: true,
      shares: sharesData?.shares ?? [],
      onShareClick: openShare,
      showShare: true,
      showAccount: true,
      moveFile,
      onFileMoved: handleFileMoved,
      file: moveFile,
      onRenameRequest: () => setRenameSignal((value) => value + 1),
      renameSignal,
    }),
    [
      title,
      handleRename,
      rename.isPending,
      backHref,
      sharesData?.shares,
      openShare,
      moveFile,
      handleFileMoved,
      renameSignal,
    ]
  )

  const error =
    fileError instanceof Error
      ? fileError.message
      : sessionError

  if (fileLoading) {
    return (
      <div className="flex h-dvh items-center justify-center">
        <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
      </div>
    )
  }

  if (error || !file) {
    return (
      <div className="flex h-full flex-col items-center justify-center gap-4 p-8">
        <p className="text-sm text-muted-foreground">
          {error ?? "Document introuvable"}
        </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-dvh min-h-0 flex-col">
      {!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}
          chrome={chrome}
        />
      )}
    </div>
  )
}
