"use client"

import { useRef } from "react"
import type { Editor } from "@tiptap/react"
import { Icon } from "@iconify/react"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuSub,
  DropdownMenuSubContent,
  DropdownMenuSubTrigger,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Button } from "@/components/ui/button"
import { buildInsertGraphicAttrs } from "@/lib/drive/extensions/docs-graphic"
import {
  DOCS_GRAPHIC_PLACEMENT_LABELS,
  DOCS_GRAPHIC_WRAP_LABELS,
  type DocsGraphicFloatSide,
  type DocsGraphicPlacement,
  type DocsGraphicWrap,
  parseGraphicAttrs,
} from "@/lib/drive/docs-graphic-types"

function readSelectedGraphicAttrs(editor: Editor) {
  if (editor.isActive("docsGraphic")) {
    return parseGraphicAttrs(editor.getAttributes("docsGraphic") as Record<string, unknown>)
  }
  if (editor.isActive("docsInlineGraphic")) {
    return parseGraphicAttrs(editor.getAttributes("docsInlineGraphic") as Record<string, unknown>)
  }
  return null
}

export function DocsGraphicInsertMenu({
  editor,
  disabled,
}: {
  editor: Editor | null
  disabled?: boolean
}) {
  const imageInputRef = useRef<HTMLInputElement>(null)

  if (!editor) return null

  const insertImage = (file: File, options?: { wrap?: DocsGraphicWrap; placement?: DocsGraphicPlacement }) => {
    const reader = new FileReader()
    reader.onload = () => {
      const src = reader.result as string
      editor
        .chain()
        .focus()
        .insertDocsGraphic(
          buildInsertGraphicAttrs("image", {
            src,
            wrap: options?.wrap ?? "square",
            placement: options?.placement ?? "block",
            width: 280,
            height: 180,
          })
        )
        .run()
    }
    reader.readAsDataURL(file)
  }

  return (
    <>
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button
            type="button"
            variant="ghost"
            size="icon"
            className="docs-toolbar-btn size-7 shrink-0"
            disabled={disabled}
            aria-label="Insérer un élément graphique"
          >
            <Icon icon="material-symbols:image-outline" className="size-4" />
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="start" className="min-w-56">
          <DropdownMenuItem onClick={() => imageInputRef.current?.click()}>
            Image…
          </DropdownMenuItem>
          <DropdownMenuSub>
            <DropdownMenuSubTrigger>Forme</DropdownMenuSubTrigger>
            <DropdownMenuSubContent>
              {(["rect", "ellipse", "line", "arrow"] as const).map((shapeType) => (
                <DropdownMenuItem
                  key={shapeType}
                  onClick={() =>
                    editor
                      .chain()
                      .focus()
                      .insertDocsGraphic(buildInsertGraphicAttrs("shape", { shapeType }))
                      .run()
                  }
                >
                  {shapeType === "rect"
                    ? "Rectangle"
                    : shapeType === "ellipse"
                      ? "Ellipse"
                      : shapeType === "line"
                        ? "Ligne"
                        : "Flèche"}
                </DropdownMenuItem>
              ))}
            </DropdownMenuSubContent>
          </DropdownMenuSub>
          <DropdownMenuItem
            onClick={() =>
              editor
                .chain()
                .focus()
                .insertDocsGraphic(buildInsertGraphicAttrs("gradient"))
                .run()
            }
          >
            Dégradé
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>
      <input
        ref={imageInputRef}
        type="file"
        accept="image/*"
        className="hidden"
        onChange={(event) => {
          const file = event.target.files?.[0]
          if (file) insertImage(file)
          event.target.value = ""
        }}
      />
    </>
  )
}

export function DocsGraphicLayoutMenu({
  editor,
  disabled,
}: {
  editor: Editor | null
  disabled?: boolean
}) {
  if (!editor) return null
  const attrs = readSelectedGraphicAttrs(editor)
  if (!attrs) return null

  const applyWrap = (wrap: DocsGraphicWrap) => {
    editor.chain().focus().setDocsGraphicWrap(wrap).run()
  }
  const applyPlacement = (placement: DocsGraphicPlacement) => {
    editor.chain().focus().setDocsGraphicPlacement(placement).run()
  }
  const applyFloatSide = (floatSide: DocsGraphicFloatSide) => {
    editor.chain().focus().setDocsGraphicFloatSide(floatSide).run()
  }

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button
          type="button"
          variant="ghost"
          size="icon"
          className="docs-toolbar-btn docs-toolbar-btn--active size-7 shrink-0"
          disabled={disabled}
          aria-label="Disposition de l'élément graphique"
        >
          <Icon icon="material-symbols:layers-outline" className="size-4" />
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="start" className="min-w-64">
        <DropdownMenuSub>
          <DropdownMenuSubTrigger>Habillage texte</DropdownMenuSubTrigger>
          <DropdownMenuSubContent>
            {(Object.keys(DOCS_GRAPHIC_WRAP_LABELS) as DocsGraphicWrap[]).map((wrap) => (
              <DropdownMenuItem key={wrap} onClick={() => applyWrap(wrap)}>
                {DOCS_GRAPHIC_WRAP_LABELS[wrap]}
                {attrs.wrap === wrap ? " ✓" : ""}
              </DropdownMenuItem>
            ))}
          </DropdownMenuSubContent>
        </DropdownMenuSub>
        <DropdownMenuSeparator />
        <DropdownMenuSub>
          <DropdownMenuSubTrigger>Placement</DropdownMenuSubTrigger>
          <DropdownMenuSubContent>
            {(Object.keys(DOCS_GRAPHIC_PLACEMENT_LABELS) as DocsGraphicPlacement[]).map(
              (placement) => (
                <DropdownMenuItem key={placement} onClick={() => applyPlacement(placement)}>
                  {DOCS_GRAPHIC_PLACEMENT_LABELS[placement]}
                  {attrs.placement === placement ? " ✓" : ""}
                </DropdownMenuItem>
              )
            )}
          </DropdownMenuSubContent>
        </DropdownMenuSub>
        <DropdownMenuSeparator />
        <DropdownMenuSub>
          <DropdownMenuSubTrigger>Côté du flottement</DropdownMenuSubTrigger>
          <DropdownMenuSubContent>
            {(["left", "right", "center"] as const).map((side) => (
              <DropdownMenuItem key={side} onClick={() => applyFloatSide(side)}>
                {side === "left" ? "Gauche" : side === "right" ? "Droite" : "Centre"}
                {attrs.floatSide === side ? " ✓" : ""}
              </DropdownMenuItem>
            ))}
          </DropdownMenuSubContent>
        </DropdownMenuSub>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

export function readGraphicToolbarActive(editor: Editor | null): boolean {
  if (!editor) return false
  return editor.isActive("docsGraphic") || editor.isActive("docsInlineGraphic")
}
