import { t } from "@lingui/core/macro";
import { useLingui } from "@lingui/react";
import { Trans } from "@lingui/react/macro";
import {
  ArrowsInSimpleIcon,
  ArrowsOutSimpleIcon,
  CodeBlockIcon,
  CodeSimpleIcon,
  ColumnsPlusLeftIcon,
  ColumnsPlusRightIcon,
  HighlighterCircleIcon,
  KeyReturnIcon,
  LinkBreakIcon,
  LinkIcon,
  ListBulletsIcon,
  ListNumbersIcon,
  MinusIcon,
  ParagraphIcon,
  PlusIcon,
  RowsPlusBottomIcon,
  RowsPlusTopIcon,
  TableIcon,
  TextAlignCenterIcon,
  TextAlignJustifyIcon,
  TextAlignLeftIcon,
  TextAlignRightIcon,
  TextBolderIcon,
  TextHFiveIcon,
  TextHFourIcon,
  TextHOneIcon,
  TextHSixIcon,
  TextHThreeIcon,
  TextHTwoIcon,
  TextIndentIcon,
  TextItalicIcon,
  TextOutdentIcon,
  TextStrikethroughIcon,
  TextUnderlineIcon,
  TrashSimpleIcon,
} from "@phosphor-icons/react";
import Color from "@tiptap/extension-color";
import Highlight from "@tiptap/extension-highlight";
import { TableKit } from "@tiptap/extension-table";
import TextAlign from "@tiptap/extension-text-align";
import { TextStyle } from "@tiptap/extension-text-style";
import {
  type Editor,
  EditorContent,
  EditorContext,
  type UseEditorOptions,
  useEditor,
  useEditorState,
} from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import { useMemo, useState } from "react";
import { toast } from "sonner";
import { match } from "ts-pattern";
import z from "zod";

import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogDescription, DialogTitle } from "@/components/ui/dialog";
import {
  DropdownMenu,
  DropdownMenuCheckboxItem,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { PopoverHeader, PopoverTitle, PopoverTrigger } from "@/components/ui/popover";
import { usePrompt } from "@/hooks/use-prompt";
import { isRTL } from "@/utils/locale";
import { sanitizeHtml } from "@/utils/sanitize";
import { cn } from "@/utils/style";

import { Toggle } from "../ui/toggle";
import { ColorPicker } from "./color-picker";
import styles from "./rich-input.module.css";

const defaultTextColor = "rgba(0, 0, 0, 1)";

const extensions = [
  StarterKit.configure({
    heading: {
      levels: [1, 2, 3, 4, 5, 6],
    },
    codeBlock: {
      enableTabIndentation: true,
    },
    link: {
      openOnClick: false,
      enableClickSelection: true,
      defaultProtocol: "https",
      protocols: ["http", "https"],
    },
  }),
  TextStyle,
  Color,
  Highlight.configure({
    HTMLAttributes: {
      class: "rounded-md px-0.5 py-px",
    },
  }),
  TextAlign.configure({ types: ["heading", "paragraph", "listItem"] }),
  TableKit.configure(),
];

type Props = UseEditorOptions & {
  value: string;
  onChange: (value: string) => void;
  style?: React.CSSProperties;
  className?: string;
  editorClassName?: string;
};

export function RichInput({ value, onChange, style, className, editorClassName, ...options }: Props) {
  const { i18n } = useLingui();
  const textDirection = isRTL(i18n.locale) ? "rtl" : undefined;
  const [isFullscreen, setIsFullscreen] = useState(false);

  const editor = useEditor({
    ...options,
    extensions,
    textDirection,
    content: value,
    immediatelyRender: false,
    shouldRerenderOnTransaction: false,
    editorProps: {
      attributes: {
        spellcheck: "false",
        "data-editor": "true",
        "data-fullscreen": isFullscreen ? "true" : "false",
        class: cn(
          "group/editor overflow-y-auto p-3 pb-4",
          "rounded-md rounded-t-none border outline-none focus-visible:border-ring",
          "[td:has(.selectedCell)]:bg-primary",
          "data-[fullscreen=false]:max-h-[400px] data-[fullscreen=false]:min-h-[100px]",
          "data-[fullscreen=true]:max-h-none data-[fullscreen=true]:min-h-full",
          styles.tiptap_content,
          styles.editor_content,
          editorClassName,
        ),
      },
    },
    onUpdate: ({ editor }) => {
      onChange(editor.getHTML());
    },
  });

  const providerValue = useMemo(() => ({ editor }), [editor]);

  if (!editor) return null;

  const editorElement = (
    <div className="relative">
      <EditorToolbar editor={editor} isFullscreen={isFullscreen} />

      <EditorContent editor={editor} />

      <Button
        size="icon"
        variant="secondary"
        className="absolute right-2 bottom-2 size-7"
        title={isFullscreen ? t`Exit Fullscreen` : t`Fullscreen`}
        onClick={() => setIsFullscreen(!isFullscreen)}
      >
        {isFullscreen ? <ArrowsInSimpleIcon className="size-4" /> : <ArrowsOutSimpleIcon className="size-4" />}
      </Button>
    </div>
  );

  if (isFullscreen) {
    return (
      <EditorContext value={providerValue}>
        <div className={cn("rounded-md", className)} style={style}>
          {/* Placeholder to maintain layout */}
          <div className="h-[200px] rounded-md border border-dashed" />
        </div>

        <Dialog open={isFullscreen} onOpenChange={setIsFullscreen}>
          <DialogContent className="flex h-[95svh] max-h-none! w-[95svw] max-w-none! flex-col p-4 sm:max-w-none! 2xl:max-w-none!">
            <div className="sr-only">
              <DialogTitle>
                <Trans comment="Screen reader title for the fullscreen rich-text editor dialog">
                  Fullscreen Editor
                </Trans>
              </DialogTitle>
              <DialogDescription>
                <Trans comment="Screen reader description for the fullscreen rich-text editor dialog">
                  Edit content in fullscreen mode
                </Trans>
              </DialogDescription>
            </div>
            {editorElement}
          </DialogContent>
        </Dialog>
      </EditorContext>
    );
  }

  return (
    <EditorContext value={providerValue}>
      <div className={cn("rounded-md", className)} style={style}>
        {editorElement}
      </div>
    </EditorContext>
  );
}

function EditorToolbar({ editor, isFullscreen }: { editor: Editor; isFullscreen: boolean }) {
  const prompt = usePrompt();

  const state = useEditorState({
    editor,
    selector: (ctx) => {
      return {
        // Bold
        isBold: ctx.editor.isActive("bold") ?? false,
        canBold: ctx.editor.can().chain().toggleBold().run() ?? false,
        toggleBold: () => ctx.editor.chain().focus().toggleBold().run(),

        // Italic
        isItalic: ctx.editor.isActive("italic") ?? false,
        canItalic: ctx.editor.can().chain().toggleItalic().run() ?? false,
        toggleItalic: () => ctx.editor.chain().focus().toggleItalic().run(),

        // Underline
        isUnderline: ctx.editor.isActive("underline") ?? false,
        canUnderline: ctx.editor.can().chain().toggleUnderline().run() ?? false,
        toggleUnderline: () => ctx.editor.chain().focus().toggleUnderline().run(),

        // Strike
        isStrike: ctx.editor.isActive("strike") ?? false,
        canStrike: ctx.editor.can().chain().toggleStrike().run() ?? false,
        toggleStrike: () => ctx.editor.chain().focus().toggleStrike().run(),

        // Highlight
        isHighlight: ctx.editor.isActive("highlight") ?? false,
        canHighlight: ctx.editor.can().chain().toggleHighlight().run() ?? false,
        toggleHighlight: () => ctx.editor.chain().focus().toggleHighlight().run(),

        // Text Color
        textColor: (ctx.editor.getAttributes("textStyle").color as string | undefined) ?? null,
        canTextColor: ctx.editor.can().chain().setColor(defaultTextColor).run() ?? false,
        setTextColor: (color: string) => ctx.editor.chain().focus().setColor(color).run(),
        unsetTextColor: () => ctx.editor.chain().focus().unsetColor().run(),

        // Heading 1
        isHeading1: ctx.editor.isActive("heading", { level: 1 }) ?? false,
        canHeading1: ctx.editor.can().chain().toggleHeading({ level: 1 }).run() ?? false,
        toggleHeading1: () => ctx.editor.chain().focus().toggleHeading({ level: 1 }).run(),

        // Heading 2
        isHeading2: ctx.editor.isActive("heading", { level: 2 }) ?? false,
        canHeading2: ctx.editor.can().chain().toggleHeading({ level: 2 }).run() ?? false,
        toggleHeading2: () => ctx.editor.chain().focus().toggleHeading({ level: 2 }).run(),

        // Heading 3
        isHeading3: ctx.editor.isActive("heading", { level: 3 }) ?? false,
        canHeading3: ctx.editor.can().chain().toggleHeading({ level: 3 }).run() ?? false,
        toggleHeading3: () => ctx.editor.chain().focus().toggleHeading({ level: 3 }).run(),

        // Heading 4
        isHeading4: ctx.editor.isActive("heading", { level: 4 }) ?? false,
        canHeading4: ctx.editor.can().chain().toggleHeading({ level: 4 }).run() ?? false,
        toggleHeading4: () => ctx.editor.chain().focus().toggleHeading({ level: 4 }).run(),

        // Heading 5
        isHeading5: ctx.editor.isActive("heading", { level: 5 }) ?? false,
        canHeading5: ctx.editor.can().chain().toggleHeading({ level: 5 }).run() ?? false,
        toggleHeading5: () => ctx.editor.chain().focus().toggleHeading({ level: 5 }).run(),

        // Heading 6
        isHeading6: ctx.editor.isActive("heading", { level: 6 }) ?? false,
        canHeading6: ctx.editor.can().chain().toggleHeading({ level: 6 }).run() ?? false,
        toggleHeading6: () => ctx.editor.chain().focus().toggleHeading({ level: 6 }).run(),

        // Paragraph
        isParagraph: ctx.editor.isActive("paragraph") ?? false,
        canParagraph: ctx.editor.can().chain().setParagraph().run() ?? false,
        setParagraph: () => ctx.editor.chain().focus().setParagraph().run(),

        // Left Align
        isLeftAlign: ctx.editor.isActive({ textAlign: "left" }) ?? false,
        canLeftAlign: ctx.editor.can().chain().toggleTextAlign("left").run() ?? false,
        toggleLeftAlign: () => ctx.editor.chain().focus().toggleTextAlign("left").run(),

        // Center Align
        isCenterAlign: ctx.editor.isActive({ textAlign: "center" }) ?? false,
        canCenterAlign: ctx.editor.can().chain().toggleTextAlign("center").run() ?? false,
        toggleCenterAlign: () => ctx.editor.chain().focus().toggleTextAlign("center").run(),

        // Right Align
        isRightAlign: ctx.editor.isActive({ textAlign: "right" }) ?? false,
        canRightAlign: ctx.editor.can().chain().toggleTextAlign("right").run() ?? false,
        toggleRightAlign: () => ctx.editor.chain().focus().toggleTextAlign("right").run(),

        // Justify Align
        isJustifyAlign: ctx.editor.isActive({ textAlign: "justify" }) ?? false,
        canJustifyAlign: ctx.editor.can().chain().toggleTextAlign("justify").run() ?? false,
        toggleJustifyAlign: () => ctx.editor.chain().focus().toggleTextAlign("justify").run(),

        // Bullet List
        isBulletList: ctx.editor.isActive("bulletList") ?? false,
        canBulletList: ctx.editor.can().chain().toggleBulletList().run() ?? false,
        toggleBulletList: () => ctx.editor.chain().focus().toggleBulletList().run(),

        // Ordered List
        isOrderedList: ctx.editor.isActive("orderedList") ?? false,
        canOrderedList: ctx.editor.can().chain().toggleOrderedList().run() ?? false,
        toggleOrderedList: () => ctx.editor.chain().focus().toggleOrderedList().run(),

        // Outdent List Item
        canLiftListItem: ctx.editor.can().chain().liftListItem("listItem").run() ?? false,
        liftListItem: () => ctx.editor.chain().focus().liftListItem("listItem").run(),

        // Indent List Item
        canSinkListItem: ctx.editor.can().chain().sinkListItem("listItem").run() ?? false,
        sinkListItem: () => ctx.editor.chain().focus().sinkListItem("listItem").run(),

        // Link
        isLink: ctx.editor.isActive("link") ?? false,
        setLink: async () => {
          const url = await prompt(t`Please enter the URL you want to link to:`, {
            defaultValue: "https://",
          });

          if (!url || url.trim() === "") {
            ctx.editor.chain().focus().unsetLink().run();
            return;
          }

          if (!z.url({ protocol: /^https?$/ }).safeParse(url).success) {
            toast.error(t`The URL you entered is not valid.`, {
              description: t`Valid URLs must start with http:// or https://.`,
            });
            return;
          }

          ctx.editor.chain().focus().setLink({ href: url, target: "_blank", rel: "noopener nofollow" }).run();
        },
        unsetLink: () => ctx.editor.chain().focus().unsetLink().run(),

        // Inline Code
        isInlineCode: ctx.editor.isActive("code") ?? false,
        canInlineCode: ctx.editor.can().chain().toggleCode().run() ?? false,
        toggleInlineCode: () => ctx.editor.chain().focus().toggleCode().run(),

        // Code Block
        isCodeBlock: ctx.editor.isActive("codeBlock") ?? false,
        canCodeBlock: ctx.editor.can().chain().toggleCodeBlock().run() ?? false,
        toggleCodeBlock: () => ctx.editor.chain().focus().toggleCodeBlock().run(),

        // Table
        insertTable: () => ctx.editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run(),
        canInsertTable: ctx.editor.can().chain().insertTable().run() ?? false,
        addColumnBefore: () => ctx.editor.chain().focus().addColumnBefore().run(),
        canAddColumnBefore: ctx.editor.can().chain().addColumnBefore().run() ?? false,
        addColumnAfter: () => ctx.editor.chain().focus().addColumnAfter().run(),
        canAddColumnAfter: ctx.editor.can().chain().addColumnAfter().run() ?? false,
        addRowBefore: () => ctx.editor.chain().focus().addRowBefore().run(),
        canAddRowBefore: ctx.editor.can().chain().addRowBefore().run() ?? false,
        addRowAfter: () => ctx.editor.chain().focus().addRowAfter().run(),
        canAddRowAfter: ctx.editor.can().chain().addRowAfter().run() ?? false,
        deleteColumn: () => ctx.editor.chain().focus().deleteColumn().run(),
        canDeleteColumn: ctx.editor.can().chain().deleteColumn().run() ?? false,
        deleteRow: () => ctx.editor.chain().focus().deleteRow().run(),
        canDeleteRow: ctx.editor.can().chain().deleteRow().run() ?? false,
        deleteTable: () => ctx.editor.chain().focus().deleteTable().run(),
        canDeleteTable: ctx.editor.can().chain().deleteTable().run() ?? false,

        // Hard Break
        setHardBreak: () => ctx.editor.chain().focus().setHardBreak().run(),

        // Horizontal Rule
        setHorizontalRule: () => ctx.editor.chain().focus().setHorizontalRule().run(),
      };
    },
  });

  return (
    <div className="flex flex-wrap items-center gap-y-0.5 rounded-md rounded-b-none border border-b-0">
      <Toggle
        size={isFullscreen ? "lg" : "sm"}
        tabIndex={-1}
        className="rounded-none"
        title={t`Bold`}
        pressed={state.isBold}
        disabled={!state.canBold}
        onPressedChange={state.toggleBold}
      >
        <TextBolderIcon className="size-3.5" />
      </Toggle>

      <Toggle
        size={isFullscreen ? "lg" : "sm"}
        tabIndex={-1}
        className="rounded-none"
        title={t`Italic`}
        pressed={state.isItalic}
        disabled={!state.canItalic}
        onPressedChange={state.toggleItalic}
      >
        <TextItalicIcon className="size-3.5" />
      </Toggle>

      <Toggle
        size={isFullscreen ? "lg" : "sm"}
        tabIndex={-1}
        className="rounded-none"
        title={t`Underline`}
        pressed={state.isUnderline}
        disabled={!state.canUnderline}
        onPressedChange={state.toggleUnderline}
      >
        <TextUnderlineIcon className="size-3.5" />
      </Toggle>

      <Toggle
        size={isFullscreen ? "lg" : "sm"}
        tabIndex={-1}
        className="rounded-none"
        title={t`Strike`}
        pressed={state.isStrike}
        disabled={!state.canStrike}
        onPressedChange={state.toggleStrike}
      >
        <TextStrikethroughIcon className="size-3.5" />
      </Toggle>

      <Toggle
        size={isFullscreen ? "lg" : "sm"}
        tabIndex={-1}
        className="rounded-none"
        title={t`Highlight`}
        pressed={state.isHighlight}
        disabled={!state.canHighlight}
        onPressedChange={state.toggleHighlight}
      >
        <HighlighterCircleIcon className="size-3.5" />
      </Toggle>

      <ColorPicker
        defaultValue={defaultTextColor}
        value={state.textColor ?? undefined}
        onChange={state.setTextColor}
        trigger={
          <PopoverTrigger
            render={
              <Button
                size={isFullscreen ? "lg" : "sm"}
                tabIndex={-1}
                variant="ghost"
                className={cn("rounded-none px-2", state.textColor && "bg-muted text-foreground")}
                title={t`Text Color`}
                disabled={!state.canTextColor}
              >
                <span className="flex flex-col items-center leading-none">
                  <span className="text-xs font-semibold">A</span>
                  <span
                    className="mt-0.5 h-0.5 w-3 rounded-full"
                    style={{ backgroundColor: state.textColor ?? "currentColor" }}
                  />
                </span>
              </Button>
            }
          />
        }
      >
        <PopoverHeader className="flex-row items-start justify-between gap-2">
          <div className="flex items-center gap-2.5">
            <span
              className="grid size-9 place-items-center rounded-lg border border-border bg-muted/60 text-sm font-semibold shadow-xs"
              style={{ color: state.textColor ?? "currentColor" }}
            >
              A
            </span>

            <div className="flex flex-col gap-0.5">
              <PopoverTitle>
                <Trans>Text Color</Trans>
              </PopoverTitle>
              <span className="text-xs text-muted-foreground">
                <Trans comment="Preset or custom shade refer to the color picker">
                  Choose a preset or custom shade.
                </Trans>
              </span>
            </div>
          </div>

          <Button
            size="xs"
            variant="ghost"
            className="shrink-0"
            onClick={state.unsetTextColor}
            disabled={!state.textColor}
          >
            <Trans comment="Clear the text color">Clear</Trans>
          </Button>
        </PopoverHeader>
      </ColorPicker>

      <div className="mx-1 h-5 w-px bg-border" />

      <DropdownMenu>
        <DropdownMenuTrigger
          render={
            <Button size={isFullscreen ? "lg" : "sm"} tabIndex={-1} variant="ghost" className="rounded-none">
              {match(state)
                .with({ isParagraph: true }, () => <ParagraphIcon className="size-3.5" />)
                .with({ isHeading1: true }, () => <TextHOneIcon className="size-3.5" />)
                .with({ isHeading2: true }, () => <TextHTwoIcon className="size-3.5" />)
                .with({ isHeading3: true }, () => <TextHThreeIcon className="size-3.5" />)
                .with({ isHeading4: true }, () => <TextHFourIcon className="size-3.5" />)
                .with({ isHeading5: true }, () => <TextHFiveIcon className="size-3.5" />)
                .with({ isHeading6: true }, () => <TextHSixIcon className="size-3.5" />)
                .otherwise(() => (
                  <ParagraphIcon className="size-3.5" />
                ))}
            </Button>
          }
        />

        <DropdownMenuContent>
          <DropdownMenuCheckboxItem
            disabled={!state.canParagraph}
            checked={state.isParagraph}
            onCheckedChange={state.setParagraph}
          >
            <Trans>Paragraph</Trans>
          </DropdownMenuCheckboxItem>
          <DropdownMenuSeparator />
          <DropdownMenuCheckboxItem
            disabled={!state.canHeading1}
            checked={state.isHeading1}
            onCheckedChange={state.toggleHeading1}
          >
            <Trans>Heading 1</Trans>
          </DropdownMenuCheckboxItem>
          <DropdownMenuCheckboxItem
            disabled={!state.canHeading2}
            checked={state.isHeading2}
            onCheckedChange={state.toggleHeading2}
          >
            <Trans>Heading 2</Trans>
          </DropdownMenuCheckboxItem>
          <DropdownMenuCheckboxItem
            disabled={!state.canHeading3}
            checked={state.isHeading3}
            onCheckedChange={state.toggleHeading3}
          >
            <Trans>Heading 3</Trans>
          </DropdownMenuCheckboxItem>
          <DropdownMenuCheckboxItem
            disabled={!state.canHeading4}
            checked={state.isHeading4}
            onCheckedChange={state.toggleHeading4}
          >
            <Trans>Heading 4</Trans>
          </DropdownMenuCheckboxItem>
          <DropdownMenuCheckboxItem
            disabled={!state.canHeading5}
            checked={state.isHeading5}
            onCheckedChange={state.toggleHeading5}
          >
            <Trans>Heading 5</Trans>
          </DropdownMenuCheckboxItem>
          <DropdownMenuCheckboxItem
            disabled={!state.canHeading6}
            checked={state.isHeading6}
            onCheckedChange={state.toggleHeading6}
          >
            <Trans>Heading 6</Trans>
          </DropdownMenuCheckboxItem>
        </DropdownMenuContent>
      </DropdownMenu>

      <DropdownMenu>
        <DropdownMenuTrigger
          render={
            <Button size={isFullscreen ? "lg" : "sm"} tabIndex={-1} variant="ghost" className="rounded-none">
              {match(state)
                .with({ isLeftAlign: true }, () => <TextAlignLeftIcon className="size-3.5" />)
                .with({ isCenterAlign: true }, () => <TextAlignCenterIcon className="size-3.5" />)
                .with({ isRightAlign: true }, () => <TextAlignRightIcon className="size-3.5" />)
                .with({ isJustifyAlign: true }, () => <TextAlignJustifyIcon className="size-3.5" />)
                .otherwise(() => (
                  <TextAlignLeftIcon className="size-3.5" />
                ))}
            </Button>
          }
        />

        <DropdownMenuContent>
          <DropdownMenuCheckboxItem
            disabled={!state.canLeftAlign}
            checked={state.isLeftAlign}
            onCheckedChange={state.toggleLeftAlign}
          >
            <Trans>Left Align</Trans>
          </DropdownMenuCheckboxItem>
          <DropdownMenuCheckboxItem
            disabled={!state.canCenterAlign}
            checked={state.isCenterAlign}
            onCheckedChange={state.toggleCenterAlign}
          >
            <Trans>Center Align</Trans>
          </DropdownMenuCheckboxItem>
          <DropdownMenuCheckboxItem
            disabled={!state.canRightAlign}
            checked={state.isRightAlign}
            onCheckedChange={state.toggleRightAlign}
          >
            <Trans>Right Align</Trans>
          </DropdownMenuCheckboxItem>
          <DropdownMenuCheckboxItem
            disabled={!state.canJustifyAlign}
            checked={state.isJustifyAlign}
            onCheckedChange={state.toggleJustifyAlign}
          >
            <Trans>Justify Align</Trans>
          </DropdownMenuCheckboxItem>
        </DropdownMenuContent>
      </DropdownMenu>

      <div className="mx-1 h-5 w-px bg-border" />

      <Toggle
        size={isFullscreen ? "lg" : "sm"}
        tabIndex={-1}
        className="rounded-none"
        title={t`Bullet List`}
        pressed={state.isBulletList}
        disabled={!state.canBulletList}
        onPressedChange={state.toggleBulletList}
      >
        <ListBulletsIcon className="size-3.5" />
      </Toggle>

      <Toggle
        size={isFullscreen ? "lg" : "sm"}
        tabIndex={-1}
        className="rounded-none"
        title={t`Ordered List`}
        pressed={state.isOrderedList}
        disabled={!state.canOrderedList}
        onPressedChange={state.toggleOrderedList}
      >
        <ListNumbersIcon className="size-3.5" />
      </Toggle>

      <Button
        size={isFullscreen ? "lg" : "sm"}
        tabIndex={-1}
        variant="ghost"
        className="rounded-none"
        disabled={!state.canLiftListItem}
        onClick={state.liftListItem}
      >
        <TextOutdentIcon className="size-3.5" />
      </Button>

      <Button
        size={isFullscreen ? "lg" : "sm"}
        tabIndex={-1}
        variant="ghost"
        className="rounded-none"
        disabled={!state.canSinkListItem}
        onClick={state.sinkListItem}
      >
        <TextIndentIcon className="size-3.5" />
      </Button>

      <div className="mx-1 h-5 w-px bg-border" />

      {state.isLink ? (
        <Button
          size={isFullscreen ? "lg" : "sm"}
          tabIndex={-1}
          variant="ghost"
          className="rounded-none"
          onClick={state.unsetLink}
        >
          <LinkBreakIcon className="size-3.5" />
        </Button>
      ) : (
        <Button
          size={isFullscreen ? "lg" : "sm"}
          tabIndex={-1}
          variant="ghost"
          className="rounded-none"
          onClick={state.setLink}
        >
          <LinkIcon className="size-3.5" />
        </Button>
      )}

      <Toggle
        size={isFullscreen ? "lg" : "sm"}
        tabIndex={-1}
        className="rounded-none"
        title={t`Inline Code`}
        pressed={state.isInlineCode}
        disabled={!state.canInlineCode}
        onPressedChange={state.toggleInlineCode}
      >
        <CodeSimpleIcon className="size-3.5" />
      </Toggle>

      <Toggle
        size={isFullscreen ? "lg" : "sm"}
        tabIndex={-1}
        className="rounded-none"
        title={t`Code Block`}
        pressed={state.isCodeBlock}
        disabled={!state.canCodeBlock}
        onPressedChange={state.toggleCodeBlock}
      >
        <CodeBlockIcon className="size-3.5" />
      </Toggle>

      <DropdownMenu>
        <DropdownMenuTrigger
          render={
            <Button
              size={isFullscreen ? "lg" : "sm"}
              tabIndex={-1}
              variant="ghost"
              className="rounded-none"
              title={t`Table`}
            >
              <TableIcon className="size-3.5" />
            </Button>
          }
        />

        <DropdownMenuContent>
          <DropdownMenuItem disabled={!state.canInsertTable} onClick={state.insertTable}>
            <PlusIcon />
            <Trans>Insert Table</Trans>
          </DropdownMenuItem>
          <DropdownMenuSeparator />
          <DropdownMenuItem disabled={!state.canAddColumnBefore} onClick={state.addColumnBefore}>
            <ColumnsPlusLeftIcon />
            <Trans>Add Column Before</Trans>
          </DropdownMenuItem>
          <DropdownMenuItem disabled={!state.canAddColumnAfter} onClick={state.addColumnAfter}>
            <ColumnsPlusRightIcon />
            <Trans>Add Column After</Trans>
          </DropdownMenuItem>
          <DropdownMenuSeparator />
          <DropdownMenuItem disabled={!state.canAddRowBefore} onClick={state.addRowBefore}>
            <RowsPlusTopIcon />
            <Trans>Add Row Before</Trans>
          </DropdownMenuItem>
          <DropdownMenuItem disabled={!state.canAddRowAfter} onClick={state.addRowAfter}>
            <RowsPlusBottomIcon />
            <Trans>Add Row After</Trans>
          </DropdownMenuItem>
          <DropdownMenuSeparator />
          <DropdownMenuItem disabled={!state.canDeleteColumn} onClick={state.deleteColumn}>
            <TrashSimpleIcon />
            <Trans>Delete Column</Trans>
          </DropdownMenuItem>
          <DropdownMenuItem disabled={!state.canDeleteRow} onClick={state.deleteRow}>
            <TrashSimpleIcon />
            <Trans>Delete Row</Trans>
          </DropdownMenuItem>
          <DropdownMenuSeparator />
          <DropdownMenuItem variant="destructive" disabled={!state.canDeleteTable} onClick={state.deleteTable}>
            <TrashSimpleIcon />
            <Trans>Delete Table</Trans>
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>

      <Button
        size={isFullscreen ? "lg" : "sm"}
        tabIndex={-1}
        variant="ghost"
        className="rounded-none"
        title={t`New Line`}
        onClick={state.setHardBreak}
      >
        <KeyReturnIcon className="size-3.5" />
      </Button>

      <Button
        size={isFullscreen ? "lg" : "sm"}
        tabIndex={-1}
        variant="ghost"
        className="rounded-none"
        title={t`Separator`}
        onClick={state.setHorizontalRule}
      >
        <MinusIcon className="size-3.5" />
      </Button>
    </div>
  );
}

type TiptapContentProps = React.ComponentProps<"div"> & {
  content: string;
};

export function TiptapContent({ content, className, ...props }: TiptapContentProps) {
  const sanitizedContent = useMemo(() => sanitizeHtml(content), [content]);

  return (
    <div
      dangerouslySetInnerHTML={{ __html: sanitizedContent }}
      className={cn(styles.tiptap_content, className)}
      {...props}
    />
  );
}
