"use client"

import { useCallback, useEffect, useMemo, useState } from "react"
import Link from "next/link"
import { useQueryClient } from "@tanstack/react-query"
import { Button } from "@/components/ui/button"
import { ArrowLeft } from "lucide-react"
import { UltidrawDocumentEditor } from "@/components/drive/ultidraw-document"
import {
  DocsEditorLoadingShell,
  useDocsEditorLoadingState,
} from "@/components/drive/richtext/docs-editor-loading-shell"
import { apiClient } from "@/lib/api/client"
import { useDriveFileById, useDriveMutations, useDriveShares } from "@/lib/api/hooks/use-drive-queries"
import { useAuthReady } from "@/lib/api/use-auth-ready"
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 { UltidrawSessionResponse } from "@/lib/drive/ultidraw-types"
import { useChromeIdentity } from "@/lib/hooks/use-chrome-identity"

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

export function UltidrawEditor({ fileId }: { fileId: string }) {
  const queryClient = useQueryClient()
  const identity = useChromeIdentity()
  const { ready } = useAuthReady()
  const setSharePath = useDriveUIStore((s) => s.setSharePath)
  const {
    data: file,
    error: fileError,
    isPending: filePending,
    isFetching: fileFetching,
  } = useDriveFileById(fileId)

  const displayPath = file?.path ?? ""
  const [session, setSession] = useState<UltidrawSessionResponse | null>(null)
  const [sessionError, setSessionError] = useState<string | null>(null)

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

  const [backHref, setBackHref] = useState("/drive")

  useEffect(() => {
    if (!displayPath) return
    setBackHref(
      resolveDriveEditReturnTo(
        null,
        displayPath,
        (folderPath) => driveFolderHref("files", folderPath),
        readDriveEditorReturnTo()
      )
    )
  }, [displayPath])

  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<UltidrawSessionResponse>("/ultidraw/session", {
          path: displayPath,
          mode: "edit",
        })
        if (!cancelled) setSession(res)
      } catch (e) {
        if (!cancelled) {
          setSessionError(e instanceof Error ? e.message : "Impossible d'ouvrir le dessin")
        }
      }
    })()
    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 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,
    }),
    [title, handleRename, rename.isPending, backHref, sharesData?.shares, openShare]
  )

  const resolvingFile = !ready || filePending || fileFetching
  const awaitingSession = Boolean(displayPath) && !session && !sessionError
  const { documentLoading, documentPhase, onDocumentLoadingChange } = useDocsEditorLoadingState(
    session?.roomId ?? displayPath ?? fileId
  )

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

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

  return (
    <DocsEditorLoadingShell
      title={title || undefined}
      resolvingFile={resolvingFile}
      awaitingSession={awaitingSession}
      documentLoading={Boolean(session) && documentLoading}
      documentPhase={documentPhase}
      error={!resolvingFile ? errorView : null}
    >
      {session && file && !error ? (
        <UltidrawDocumentEditor
          session={session}
          mode="edit"
          userName={collabUserName}
          userColor={collabUserColor}
          chrome={chrome}
          deferSplash
          onLoadingChange={onDocumentLoadingChange}
        />
      ) : null}
    </DocsEditorLoadingShell>
  )
}
