"use client"

import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import type { Editor } from "@tiptap/react"
import { Sparkles, X, GripVertical } from "lucide-react"
import { Button } from "@/components/ui/button"
import { AiChatIframe } from "@/components/ai/ai-chat-iframe"
import {
  docsContextFromSnapshot,
  docsSystemPromptExtra,
  snapshotDocsEditor,
} from "@/lib/ai/docs-context"
import {
  applyDocsAction,
  extractDocsApplyFromMarkdown,
  parseDocsApplyPayload,
} from "@/lib/ai/docs-apply"
import type { AiPostMessage } from "@/lib/ai/chat-context"
import { useAiConfig, useAiQuota } from "@/lib/api/hooks/use-ai-queries"
import { AiSpendBar } from "@/components/ai/ai-spend-bar"
import {
  DOCS_AI_PANEL_MIN_WIDTH_PX,
  useDocsAiPanelStore,
} from "@/lib/ai/use-docs-ai-panel"
import { cn } from "@/lib/utils"

export function DocsAiPanel({
  editor,
  documentPath,
  documentTitle,
  sourcePath,
  editable,
}: {
  editor: Editor | null
  documentPath: string
  documentTitle: string
  sourcePath?: string
  editable: boolean
}) {
  const open = useDocsAiPanelStore((s) => s.open)
  const widthPx = useDocsAiPanelStore((s) => s.widthPx)
  const setWidthPx = useDocsAiPanelStore((s) => s.setWidthPx)
  const closePanel = useDocsAiPanelStore((s) => s.closePanel)
  const { data: config } = useAiConfig()
  const { data: quota } = useAiQuota(open && (config?.enabled ?? false))
  const [contextTick, setContextTick] = useState(0)
  const resizeRef = useRef<{ startX: number; startW: number } | null>(null)

  useEffect(() => {
    if (!editor || !open) return
    const bump = () => setContextTick((n) => n + 1)
    editor.on("selectionUpdate", bump)
    editor.on("update", bump)
    return () => {
      editor.off("selectionUpdate", bump)
      editor.off("update", bump)
    }
  }, [editor, open])

  const context = useMemo(() => {
    if (!editor || !open) {
      return {
        app: "docs" as const,
        temporary: true,
        drivePath: documentPath,
        documentTitle,
        sourcePath,
      }
    }
    const snap = snapshotDocsEditor(editor, {
      path: documentPath,
      title: documentTitle,
      sourcePath,
    })
    return docsContextFromSnapshot(snap, true)
  }, [editor, open, documentPath, documentTitle, sourcePath, contextTick])

  const handleApplyFromParent = useCallback(
    (payload: unknown) => {
      if (!editor) return
      const cmd = parseDocsApplyPayload(payload)
      if (cmd) applyDocsAction(editor, cmd)
    },
    [editor]
  )

  useEffect(() => {
    if (!open || !editor) return
    const onMessage = (event: MessageEvent) => {
      if (event.origin !== window.location.origin) return
      const data = event.data as AiPostMessage & {
        type?: string
        payload?: unknown
        text?: string
      }
      if (data?.type === "ULTI_DOCS_APPLY" && data.payload) {
        handleApplyFromParent(data.payload)
      }
      if (data?.type === "ULTI_ASSISTANT_TEXT" && typeof data.text === "string") {
        const cmd = extractDocsApplyFromMarkdown(data.text)
        if (cmd) applyDocsAction(editor, cmd)
      }
    }
    window.addEventListener("message", onMessage)
    return () => window.removeEventListener("message", onMessage)
  }, [open, editor, handleApplyFromParent])

  useEffect(() => {
    if (!open || !editor) return
    ;(window as Window & { __ultiDocsApply?: (p: unknown) => void }).__ultiDocsApply =
      handleApplyFromParent
    return () => {
      delete (window as Window & { __ultiDocsApply?: (p: unknown) => void }).__ultiDocsApply
    }
  }, [open, editor, handleApplyFromParent])

  const onResizePointerDown = (e: React.PointerEvent) => {
    e.preventDefault()
    resizeRef.current = { startX: e.clientX, startW: widthPx }
    const onMove = (ev: PointerEvent) => {
      const st = resizeRef.current
      if (!st) return
      const delta = st.startX - ev.clientX
      setWidthPx(st.startW + delta)
    }
    const onUp = () => {
      resizeRef.current = null
      window.removeEventListener("pointermove", onMove)
      window.removeEventListener("pointerup", onUp)
    }
    window.addEventListener("pointermove", onMove)
    window.addEventListener("pointerup", onUp)
  }

  if (!config?.enabled || !open) return null

  return (
    <div
      className="docs-ai-panel relative flex h-full shrink-0 flex-col border-l border-[#dadce0] bg-white dark:border-border dark:bg-background"
      style={{ width: widthPx }}
      data-docs-ai-panel
    >
      <button
        type="button"
        aria-label="Redimensionner le panneau UltiAI"
        className="absolute left-0 top-0 z-10 flex h-full w-1.5 cursor-col-resize items-center justify-center hover:bg-[#e8eaed] dark:hover:bg-muted"
        onPointerDown={onResizePointerDown}
      >
        <GripVertical className="pointer-events-none h-4 w-4 text-muted-foreground opacity-0 hover:opacity-100" />
      </button>
      <div className="flex items-center justify-between gap-2 border-b px-3 py-2">
        <div className="flex min-w-0 items-center gap-2 text-sm font-medium">
          <Sparkles className="h-4 w-4 shrink-0 text-[#1a73e8]" />
          <span className="truncate">UltiAI</span>
        </div>
        <div className="flex shrink-0 items-center gap-1">
          {quota ? <AiSpendBar quota={quota} compact className="max-w-[140px]" /> : null}
          <Button
            type="button"
            variant="ghost"
            size="icon"
            className="h-7 w-7"
            onClick={closePanel}
            aria-label="Fermer UltiAI"
          >
            <X className="h-4 w-4" />
          </Button>
        </div>
      </div>
      {!editable ? (
        <p className="px-3 py-2 text-xs text-muted-foreground">
          Mode lecture — l&apos;IA peut analyser le document mais pas le modifier.
        </p>
      ) : null}
      <div className="min-h-0 flex-1">
        <AiChatIframe
          publicPath={config.public_path}
          context={{
            ...context,
            systemPromptExtra: docsSystemPromptExtra(context),
          }}
          className={cn("h-full w-full border-0")}
        />
      </div>
    </div>
  )
}

export function DocsAiPanelToggle({
  disabled,
  className,
}: {
  disabled?: boolean
  className?: string
}) {
  const open = useDocsAiPanelStore((s) => s.open)
  const toggle = useDocsAiPanelStore((s) => s.toggle)
  const { data: config } = useAiConfig()

  if (!config?.enabled) return null

  return (
    <Button
      type="button"
      variant="ghost"
      size="icon"
      className={cn(
        "size-9 shrink-0 rounded-full",
        open && "bg-[#e8f0fe] text-[#1a73e8] dark:bg-muted",
        className
      )}
      disabled={disabled}
      onClick={toggle}
      aria-label="UltiAI"
      title="UltiAI"
    >
      <Sparkles className="size-4" />
    </Button>
  )
}
