import type { CommandPaletteGroup } from "@nuxt/ui"
import { type ComputedRef, computed, type Ref } from "vue"
import type { PatternOpenPayload } from "@/composables/usePatternPlugin"
import type { FormattingHandlers } from "@/lib/formatting"

export interface SuggestionActionItem {
  label: string
  icon?: string
  kbds?: string[]
  description?: string
  disabled?: boolean
  class?: string
  onSelect: () => void
}

export interface MentionItem {
  label: string
  suffix?: string
}

export interface MentionData {
  pages?: MentionItem[]
  blocks?: MentionItem[]
  tags?: MentionItem[]
}

export function buildSlashGroups(
  payload: PatternOpenPayload,
  handlers: FormattingHandlers | null,
  onClose: () => void,
): CommandPaletteGroup[] {
  const { respond, close: closeSession } = payload

  function replace(text: string) {
    respond({ text, mode: "replace" })
    closeSession("completed")
    onClose()
  }

  function run(fn: () => void) {
    respond({ text: "", mode: "replace" })
    closeSession("cancelled")
    fn()
    onClose()
  }

  return [
    {
      id: "headings",
      label: "Headings",
      items: [
        {
          label: "Paragraph",
          icon: "i-lucide-text",
          onSelect: () => replace(""),
        },
        {
          label: "Heading 1",
          icon: "i-lucide-heading-1",
          kbds: ["⌘1"],
          onSelect: () => replace("# "),
        },
        {
          label: "Heading 2",
          icon: "i-lucide-heading-2",
          kbds: ["⌘2"],
          onSelect: () => replace("## "),
        },
        {
          label: "Heading 3",
          icon: "i-lucide-heading-3",
          onSelect: () => replace("### "),
        },
        {
          label: "Heading 4",
          icon: "i-lucide-heading-4",
          onSelect: () => replace("#### "),
        },
        {
          label: "Heading 5",
          icon: "i-lucide-heading-5",
          onSelect: () => replace("##### "),
        },
        {
          label: "Heading 6",
          icon: "i-lucide-heading-6",
          onSelect: () => replace("###### "),
        },
      ],
    },
    {
      id: "formatting",
      label: "Formatting",
      items: [
        {
          label: "Bold",
          icon: "i-lucide-bold",
          kbds: ["⌘B"],
          onSelect: () => {
            if (handlers) run(handlers.toggleBold)
          },
        },
        {
          label: "Italic",
          icon: "i-lucide-italic",
          kbds: ["⌘I"],
          onSelect: () => {
            if (handlers) run(handlers.toggleItalic)
          },
        },
        {
          label: "Code",
          icon: "i-lucide-code",
          kbds: ["⌘`"],
          onSelect: () => {
            if (handlers) run(handlers.toggleCode)
          },
        },
        {
          label: "Strikethrough",
          icon: "i-lucide-strikethrough",
          onSelect: () => {
            if (handlers) run(handlers.toggleStrikethrough)
          },
        },
        {
          label: "Highlight",
          icon: "i-lucide-highlighter",
          onSelect: () => {
            if (handlers) run(handlers.toggleHighlight)
          },
        },
      ],
    },
    {
      id: "blocks",
      label: "Blocks",
      items: [
        {
          label: "Task",
          icon: "i-lucide-list-todo",
          onSelect: () => replace("TODO "),
        },
        {
          label: "Block Math",
          icon: "i-lucide-square-radical",
          onSelect: () => replace("$$\n\n$$"),
        },
      ],
    },
    {
      id: "insert",
      label: "Insert",
      items: [
        {
          label: "Link",
          icon: "i-lucide-link",
          onSelect: () => replace("[link](url)"),
        },
        {
          label: "Inline Math",
          icon: "i-lucide-sigma",
          onSelect: () => replace("$$"),
        },
        {
          label: "Page Reference",
          icon: "i-lucide-book-marked",
          onSelect: () => replace("[[Page Name]]"),
        },
        {
          label: "Block Reference",
          icon: "i-lucide-arrow-up-from-dot",
          onSelect: () => replace("((block-id))"),
        },
        {
          label: "Tag",
          icon: "i-lucide-hash",
          onSelect: () => replace("#tag"),
        },
      ],
    },
  ]
}

const DEMO_PAGES = [
  { label: "Getting Started", suffix: "Page" },
  { label: "Physics Notes", suffix: "Page" },
  { label: "Documentation", suffix: "Page" },
  { label: "Architecture", suffix: "Page" },
  { label: "API Reference", suffix: "Page" },
  { label: "Development Guide", suffix: "Page" },
  { label: "Release Notes", suffix: "Page" },
  { label: "Meeting Notes", suffix: "Page" },
]

const DEMO_BLOCKS = [
  { label: "Fix login bug", suffix: "abc123" },
  { label: "Implement API endpoint", suffix: "def456" },
  { label: "Update documentation", suffix: "ghi789" },
  { label: "Refactor tests", suffix: "jkl012" },
  { label: "Review PR #42", suffix: "mno345" },
]

const DEMO_TAGS: MentionItem[] = [
  { label: "documentation", suffix: "Tag" },
  { label: "development", suffix: "Tag" },
  { label: "bug", suffix: "Tag" },
  { label: "feature", suffix: "Tag" },
  { label: "enhancement", suffix: "Tag" },
  { label: "planning", suffix: "Tag" },
  { label: "urgent", suffix: "Tag" },
]

export function buildMentionGroups(
  payload: PatternOpenPayload,
  onClose: () => void,
  mentionData?: MentionData,
): CommandPaletteGroup[] {
  const { kind, respond, close: closeSession, trigger } = payload

  function select(text: string) {
    const closeDelim =
      kind === "reference" ? "]]" : kind === "embed" ? "))" : ""
    respond({ text: `${trigger}${text}${closeDelim}`, mode: "replace" })
    closeSession("completed")
    onClose()
  }

  if (kind === "reference") {
    const pages = mentionData?.pages?.length ? mentionData.pages : DEMO_PAGES
    return [
      {
        id: "pages",
        label: "",
        items: pages.map((p) => ({
          label: p.label,
          suffix: p.suffix,
          icon: "i-lucide-file-text",
          onSelect: () => select(p.label),
        })),
      },
    ]
  }

  if (kind === "embed") {
    const blocks = mentionData?.blocks?.length
      ? mentionData.blocks
      : DEMO_BLOCKS
    return [
      {
        id: "blocks",
        label: "",
        items: blocks.map((b) => ({
          label: b.label,
          suffix: b.suffix,
          icon: "i-lucide-message-square",
          onSelect: () => select(b.suffix ?? ""),
        })),
      },
    ]
  }

  if (kind === "tag") {
    const tags = mentionData?.tags?.length ? mentionData.tags : DEMO_TAGS
    return [
      {
        id: "tags",
        label: "",
        items: tags.map((t) => ({
          label: t.label,
          suffix: t.suffix,
          icon: "i-lucide-hash",
          onSelect: () => select(t.label),
        })),
      },
    ]
  }

  return []
}

export function useSlashGroups(
  payload: Ref<PatternOpenPayload | null>,
  handlers: Ref<FormattingHandlers | null>,
  onClose: () => void,
): ComputedRef<CommandPaletteGroup[]> {
  return computed(() => {
    if (!payload.value) return []
    return buildSlashGroups(payload.value, handlers.value, onClose)
  })
}

export function useMentionGroups(
  payload: Ref<PatternOpenPayload | null>,
  onClose: () => void,
  mentionData?: Ref<MentionData | null>,
): ComputedRef<CommandPaletteGroup[]> {
  return computed(() => {
    if (!payload.value) return []
    return buildMentionGroups(
      payload.value,
      onClose,
      mentionData?.value ?? undefined,
    )
  })
}
