"use client";

import {
  useEffect,
  useRef,
  useState,
  type FormEvent,
  type MouseEvent,
} from "react";
import { renderToStaticMarkup } from "react-dom/server";
import BlogContent from "./BlogContent";
import { serializeBlogEditor } from "./blog-content-editor-utils";
import {
  BLOG_OPEN_SOURCE_FONTS,
  isBlogOpenSourceFont,
  safeBlogAsset,
  safeBlogHref,
} from "./blog-content-utils";

type EditorTool = "link" | "image" | null;
type TextAlignment = "left" | "center" | "right";

const fontSizes = [12, 14, 16, 18, 20, 24, 28, 32, 36, 42, 48];

export default function BlogRichTextEditor({
  content,
  onChange,
  disabled = false,
  focusRequest = 0,
}: {
  content: string;
  onChange: (content: string) => void;
  disabled?: boolean;
  focusRequest?: number;
}) {
  const textareaRef = useRef<HTMLTextAreaElement>(null);
  const visualEditorRef = useRef<HTMLDivElement>(null);
  const lastVisualEditorRef = useRef<HTMLDivElement | null>(null);
  const selectionRef = useRef({ start: 0, end: 0 });
  const visualSelectionRef = useRef<Range | null>(null);
  const lastVisualContentRef = useRef(content);
  const [initialVisualHtml] = useState(() => ({
    __html: renderToStaticMarkup(<BlogContent content={content} />),
  }));
  const [editorMode, setEditorMode] = useState<"visual" | "code">("visual");
  const [activeTool, setActiveTool] = useState<EditorTool>(null);
  const [url, setUrl] = useState("");
  const [alt, setAlt] = useState("");
  const [toolError, setToolError] = useState("");
  const [fontChoice, setFontChoice] = useState("");
  const [fontSizeChoice, setFontSizeChoice] = useState("");
  const [textColor, setTextColor] = useState("#243746");

  useEffect(() => {
    if (!focusRequest) return;
    const editor = editorMode === "visual" ? visualEditorRef.current : textareaRef.current;
    editor?.focus();
    editor?.scrollIntoView({ block: "center" });
  }, [focusRequest, editorMode]);

  useEffect(() => {
    const editor = visualEditorRef.current;
    if (
      editorMode !== "visual" ||
      !editor ||
      (lastVisualEditorRef.current === editor && lastVisualContentRef.current === content)
    ) {
      return;
    }
    editor.innerHTML = renderToStaticMarkup(<BlogContent content={content} />);
    lastVisualContentRef.current = content;
    lastVisualEditorRef.current = editor;
  }, [content, editorMode]);

  function keepEditorSelection(event: MouseEvent<HTMLButtonElement>) {
    event.preventDefault();
    captureEditorSelection();
  }

  function captureEditorSelection() {
    if (editorMode === "visual") {
      const editor = visualEditorRef.current;
      const selection = window.getSelection();
      if (editor && selection?.rangeCount && editor.contains(selection.anchorNode)) {
        visualSelectionRef.current = selection.getRangeAt(0).cloneRange();
      }
      return;
    }
    const textarea = textareaRef.current;
    if (!textarea) return;
    selectionRef.current = {
      start: textarea.selectionStart,
      end: textarea.selectionEnd,
    };
  }

  function captureSelectionWithoutFocusing() {
    captureEditorSelection();
  }

  function getSelection() {
    const textarea = textareaRef.current;
    if (!textarea) return selectionRef.current;
    if (document.activeElement === textarea) {
      selectionRef.current = {
        start: textarea.selectionStart,
        end: textarea.selectionEnd,
      };
    }
    return selectionRef.current;
  }

  function restoreVisualSelection() {
    const editor = visualEditorRef.current;
    const selection = window.getSelection();
    if (!editor || !selection) return null;
    editor.focus();
    const range = visualSelectionRef.current?.cloneRange();
    if (range && editor.contains(range.commonAncestorContainer)) {
      selection.removeAllRanges();
      selection.addRange(range);
      return range;
    }
    const fallback = document.createRange();
    fallback.selectNodeContents(editor);
    fallback.collapse(false);
    selection.removeAllRanges();
    selection.addRange(fallback);
    return fallback;
  }

  function commitVisualChange() {
    const editor = visualEditorRef.current;
    if (!editor) return;
    const nextContent = serializeBlogEditor(editor);
    if (nextContent.length > 200000) {
      editor.innerHTML = renderToStaticMarkup(
        <BlogContent content={lastVisualContentRef.current} />,
      );
      setToolError("Isi artikel maksimal 200.000 karakter.");
      return;
    }
    setToolError("");
    lastVisualContentRef.current = nextContent;
    onChange(nextContent);
    captureEditorSelection();
  }

  function wrapVisualSelection(tagName: "STRONG" | "EM" | "U" | "S") {
    const range = restoreVisualSelection();
    if (!range) return;
    if (range.collapsed) {
      const placeholder = document.createTextNode("teks");
      range.insertNode(placeholder);
      range.selectNodeContents(placeholder);
    }
    const wrapper = document.createElement(tagName);
    try {
      wrapper.append(range.extractContents());
      range.insertNode(wrapper);
      range.selectNodeContents(wrapper);
      const selection = window.getSelection();
      selection?.removeAllRanges();
      selection?.addRange(range);
      visualSelectionRef.current = range.cloneRange();
      commitVisualChange();
    } catch {
      setToolError("Pilih teks dalam satu bagian sebelum menerapkan format.");
    }
  }

  function applyVisualStyle(name: "font" | "size" | "color", value: string) {
    const range = restoreVisualSelection();
    if (!range) return;
    if (range.collapsed) {
      const placeholder = document.createTextNode("teks");
      range.insertNode(placeholder);
      range.selectNodeContents(placeholder);
    }
    const span = document.createElement("span");
    if (name === "font") span.style.fontFamily = `"${value}", sans-serif`;
    if (name === "size") span.style.fontSize = `${value}px`;
    if (name === "color") span.style.color = value;
    try {
      span.append(range.extractContents());
      range.insertNode(span);
      range.selectNodeContents(span);
      const selection = window.getSelection();
      selection?.removeAllRanges();
      selection?.addRange(range);
      visualSelectionRef.current = range.cloneRange();
      commitVisualChange();
    } catch {
      setToolError("Pilih teks dalam satu bagian sebelum menerapkan format.");
    }
  }

  function insert(markup: string, selectStart = 0, selectLength = 0) {
    if (editorMode === "visual") {
      const range = restoreVisualSelection();
      if (!range) return;
      range.deleteContents();
      if (markup.trim() === "---") {
        const hr = document.createElement("hr");
        range.insertNode(hr);
        range.setStartAfter(hr);
        range.collapse(true);
      } else {
        const fragment = range.createContextualFragment(markup.replace(/\n/g, "<br>"));
        const lastNode = fragment.lastChild;
        range.insertNode(fragment);
        if (lastNode) {
          range.setStartAfter(lastNode);
          range.collapse(true);
        }
      }
      const selection = window.getSelection();
      selection?.removeAllRanges();
      selection?.addRange(range);
      visualSelectionRef.current = range.cloneRange();
      commitVisualChange();
      return;
    }
    const textarea = textareaRef.current;
    const { start, end } = getSelection();
    const nextContent = `${content.slice(0, start)}${markup}${content.slice(end)}`;
    const selectionStart = start + selectStart;
    selectionRef.current = {
      start: selectionStart,
      end: selectionStart + selectLength,
    };
    onChange(nextContent);

    requestAnimationFrame(() => {
      textarea?.focus();
      textarea?.setSelectionRange(selectionStart, selectionStart + selectLength);
    });
  }

  function wrapSelection(prefix: string, suffix = prefix) {
    if (editorMode === "visual") {
      const tagName = prefix === "**" ? "STRONG" : prefix === "*" ? "EM" : prefix === "++" ? "U" : "S";
      wrapVisualSelection(tagName);
      return;
    }
    const { start, end } = getSelection();
    const selected = content.slice(start, end) || "teks";
    insert(`${prefix}${selected}${suffix}`, prefix.length, selected.length);
  }

  function applyInlineStyle(name: "font" | "size" | "color", value: string) {
    if (!value) return;
    if (name === "font" && !isBlogOpenSourceFont(value)) return;
    if (name === "color" && !/^#[\da-f]{6}$/i.test(value)) return;
    if (name === "size" && (!/^\d{1,2}$/.test(value) || Number(value) < 10 || Number(value) > 48)) return;
    if (editorMode === "visual") {
      applyVisualStyle(name, value);
      return;
    }
    const { start, end } = getSelection();
    const selected = content.slice(start, end) || "teks";
    const markup = `<blog-style ${name}="${value}">${selected}</blog-style>`;
    insert(markup, `<blog-style ${name}="${value}">`.length, selected.length);
  }

  function alignBlock(alignment: TextAlignment) {
    if (editorMode === "visual") {
      const range = restoreVisualSelection();
      const editor = visualEditorRef.current;
      if (!range || !editor) return;
      const node = range.startContainer.nodeType === Node.ELEMENT_NODE
        ? range.startContainer as Element
        : range.startContainer.parentElement;
      const block = node?.closest("p,h2,h3,h4,blockquote,li,div");
      if (block && editor.contains(block)) {
        (block as HTMLElement).style.textAlign = alignment;
        commitVisualChange();
      }
      return;
    }
    const { start, end } = getSelection();
    const previousBreak = content.lastIndexOf("\n\n", Math.max(0, start - 1));
    const blockStart = previousBreak < 0 ? 0 : previousBreak + 2;
    const nextBreak = content.indexOf("\n\n", end);
    const blockEnd = nextBreak < 0 ? content.length : nextBreak;
    const selected = content.slice(blockStart, blockEnd);
    const formatted = selected
      .split(/(\n[ \t]*\n)/)
      .map((chunk) => {
        if (!chunk.trim()) return chunk;
        const withoutAlignment = chunk.replace(
          /^:::align=(?:left|center|right)\r?\n/,
          "",
        );
        return `:::align=${alignment}\n${withoutAlignment}`;
      })
      .join("");
    const nextContent = `${content.slice(0, blockStart)}${formatted}${content.slice(blockEnd)}`;
    const nextCaret = blockStart + formatted.length;
    selectionRef.current = { start: nextCaret, end: nextCaret };
    onChange(nextContent);
    requestAnimationFrame(() => {
      textareaRef.current?.focus();
      textareaRef.current?.setSelectionRange(nextCaret, nextCaret);
    });
  }

  function prefixLines(prefix: string) {
    if (editorMode === "visual") {
      restoreVisualSelection();
      const command = prefix.startsWith("##") ? "formatBlock"
        : prefix.startsWith("-") ? "insertUnorderedList"
        : prefix.startsWith("1.") ? "insertOrderedList"
        : "formatBlock";
      document.execCommand(command, false, command === "formatBlock" ? (prefix.startsWith("###") ? "H3" : prefix.startsWith("##") ? "H2" : "BLOCKQUOTE") : undefined);
      commitVisualChange();
      return;
    }
    const { start, end } = getSelection();
    const lineStart = content.lastIndexOf("\n", Math.max(0, start - 1)) + 1;
    const followingBreak = content.indexOf("\n", end);
    const lineEnd = followingBreak < 0 ? content.length : followingBreak;
    const selected = content.slice(lineStart, lineEnd) || "teks";
    const formatted = selected
      .split("\n")
      .map((line) => `${prefix}${line}`)
      .join("\n");
    insert(formatted, formatted.length);
  }

  function showTool(tool: Exclude<EditorTool, null>) {
    setActiveTool((current) => (current === tool ? null : tool));
    setUrl("");
    setAlt("");
    setToolError("");
  }

  function submitTool(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const trimmedUrl = url.trim();
    if (!trimmedUrl) return;
    if (!activeTool) return;
    const safeHref = safeBlogHref(trimmedUrl);
    const safeImage = safeBlogAsset(trimmedUrl);
    if ((activeTool === "image" && !safeImage) || (activeTool === "link" && !safeHref)) {
      setToolError(
        activeTool === "image"
          ? "Gunakan URL HTTPS atau path lokal yang diawali /."
          : "Gunakan URL HTTPS, path lokal, anchor, atau email yang valid.",
      );
      return;
    }
    const textarea = textareaRef.current;
    const { start, end } = getSelection();
    const selected = editorMode === "code" ? content.slice(start, end) : "";

    if (activeTool === "link") {
      if (editorMode === "visual") {
        const range = restoreVisualSelection();
        const editor = visualEditorRef.current;
        if (!range || !editor || !safeHref) return;
        const anchor = document.createElement("a");
        anchor.href = safeHref.href;
        if (range.collapsed) anchor.textContent = "teks tautan";
        else anchor.append(range.extractContents());
        range.insertNode(anchor);
        range.selectNodeContents(anchor);
        const selection = window.getSelection();
        selection?.removeAllRanges();
        selection?.addRange(range);
        visualSelectionRef.current = range.cloneRange();
        commitVisualChange();
        setActiveTool(null);
        setUrl("");
        return;
      }
      const label = selected || "teks tautan";
      const markup = `[${label}](${trimmedUrl})`;
      const urlStart = start + label.length + 3;
      onChange(`${content.slice(0, start)}${markup}${content.slice(end)}`);
      selectionRef.current = { start: urlStart, end: urlStart + trimmedUrl.length };
      requestAnimationFrame(() => {
        textarea?.focus();
        textarea?.setSelectionRange(urlStart, urlStart + trimmedUrl.length);
      });
    } else {
      if (editorMode === "visual") {
        const range = restoreVisualSelection();
        if (!range || !safeImage) return;
        const image = document.createElement("img");
        image.src = safeImage;
        image.alt = alt.trim() || "Deskripsi gambar";
        range.deleteContents();
        range.insertNode(image);
        range.setStartAfter(image);
        range.collapse(true);
        const selection = window.getSelection();
        selection?.removeAllRanges();
        selection?.addRange(range);
        visualSelectionRef.current = range.cloneRange();
        commitVisualChange();
      } else {
        const markup = `![${alt.trim() || "Deskripsi gambar"}](${trimmedUrl})`;
        const insertion = `\n\n${markup}\n\n`;
        insert(insertion, insertion.length);
      }
    }

    setActiveTool(null);
    setUrl("");
    setAlt("");
  }

  return (
    <div className="blog-rich-editor">
      <div className="blog-editor-modes" role="group" aria-label="Mode editor">
        <button
          type="button"
          aria-pressed={editorMode === "visual"}
          onClick={() => setEditorMode("visual")}
        >
          Visual
        </button>
        <button
          type="button"
          aria-pressed={editorMode === "code"}
          onClick={() => setEditorMode("code")}
        >
          Kode
        </button>
      </div>
      <div className="blog-editor-toolbar" role="toolbar" aria-label="Pemformatan artikel">
        <button type="button" title="Tebalkan" aria-label="Tebalkan" onMouseDown={keepEditorSelection} onClick={() => wrapSelection("**")}>
          <strong>B</strong>
        </button>
        <button type="button" title="Miringkan" aria-label="Miringkan" onMouseDown={keepEditorSelection} onClick={() => wrapSelection("*")}>
          <em>I</em>
        </button>
        <button type="button" title="Garis bawah" aria-label="Garis bawah" onMouseDown={keepEditorSelection} onClick={() => wrapSelection("++")}>
          <u>U</u>
        </button>
        <button type="button" title="Coret" aria-label="Coret" onMouseDown={keepEditorSelection} onClick={() => wrapSelection("~~")}>
          <s>S</s>
        </button>
        <span className="blog-toolbar-divider" aria-hidden="true" />
        <label className="blog-toolbar-select-label">
          <span>Font</span>
          <select
            aria-label="Pilih font open-source"
            value={fontChoice}
            onMouseDown={captureSelectionWithoutFocusing}
            onChange={(event) => {
              const font = event.target.value;
              setFontChoice("");
              applyInlineStyle("font", font);
            }}
          >
            <option value="">Pilih font</option>
            {BLOG_OPEN_SOURCE_FONTS.map((font) => (
              <option key={font} value={font}>{font}</option>
            ))}
          </select>
        </label>
        <label className="blog-toolbar-select-label blog-size-label">
          <span>Ukuran</span>
          <select
            aria-label="Pilih ukuran font"
            value={fontSizeChoice}
            onMouseDown={captureSelectionWithoutFocusing}
            onChange={(event) => {
              const size = event.target.value;
              setFontSizeChoice("");
              applyInlineStyle("size", size);
            }}
          >
            <option value="">px</option>
            {fontSizes.map((size) => (
              <option key={size} value={String(size)}>{size}px</option>
            ))}
          </select>
        </label>
        <label className="blog-toolbar-color-label" title="Pilih warna teks">
          <span>Warna</span>
          <input
            aria-label="Pilih warna teks"
            type="color"
            value={textColor}
            onMouseDown={captureSelectionWithoutFocusing}
            onChange={(event) => setTextColor(event.target.value)}
          />
        </label>
        <button
          type="button"
          title="Terapkan warna teks"
          aria-label="Terapkan warna teks"
          onMouseDown={keepEditorSelection}
          onClick={() => applyInlineStyle("color", textColor)}
        >
          A
        </button>
        <span className="blog-toolbar-divider" aria-hidden="true" />
        <div className="blog-toolbar-align" role="group" aria-label="Perataan paragraf">
          <button type="button" title="Rata kiri" aria-label="Rata kiri" onMouseDown={keepEditorSelection} onClick={() => alignBlock("left")}>Kiri</button>
          <button type="button" title="Rata tengah" aria-label="Rata tengah" onMouseDown={keepEditorSelection} onClick={() => alignBlock("center")}>Tengah</button>
          <button type="button" title="Rata kanan" aria-label="Rata kanan" onMouseDown={keepEditorSelection} onClick={() => alignBlock("right")}>Kanan</button>
        </div>
        <span className="blog-toolbar-divider" aria-hidden="true" />
        <button type="button" title="Judul bagian" aria-label="Judul bagian" onMouseDown={keepEditorSelection} onClick={() => prefixLines("## ")}>
          H2
        </button>
        <button type="button" title="Subjudul" aria-label="Subjudul" onMouseDown={keepEditorSelection} onClick={() => prefixLines("### ")}>
          H3
        </button>
        <button type="button" title="Daftar berpoin" aria-label="Daftar berpoin" onMouseDown={keepEditorSelection} onClick={() => prefixLines("- ")}>
          • Daftar
        </button>
        <button type="button" title="Daftar bernomor" aria-label="Daftar bernomor" onMouseDown={keepEditorSelection} onClick={() => prefixLines("1. ")}>
          1. Daftar
        </button>
        <button type="button" title="Kutipan" aria-label="Kutipan" onMouseDown={keepEditorSelection} onClick={() => prefixLines("> ")}>
          Kutipan
        </button>
        <span className="blog-toolbar-divider" aria-hidden="true" />
        <button type="button" title="Tambahkan tautan" aria-label="Tambahkan tautan" onMouseDown={keepEditorSelection} onClick={() => showTool("link")}>
          Tautan
        </button>
        <button type="button" title="Tambahkan gambar" aria-label="Tambahkan gambar" onMouseDown={keepEditorSelection} onClick={() => showTool("image")}>
          Gambar
        </button>
        <button type="button" title="Garis pemisah" aria-label="Garis pemisah" onMouseDown={keepEditorSelection} onClick={() => insert("\n\n---\n\n")}>
          Garis
        </button>
      </div>

      {activeTool && (
        <form className="blog-editor-insert-form" onSubmit={submitTool}>
          <label>
            {activeTool === "link" ? "URL tautan" : "URL gambar"}
            <input
              type="text"
              inputMode="url"
              value={url}
              onChange={(event) => {
                setUrl(event.target.value);
                setToolError("");
              }}
              placeholder={activeTool === "link" ? "https://..." : "/uploads/gambar.jpg atau https://..."}
              required
              autoFocus
            />
          </label>
          {activeTool === "image" && (
            <label>
              Deskripsi gambar
              <input
                value={alt}
                onChange={(event) => setAlt(event.target.value)}
                placeholder="Jelaskan isi gambar"
              />
            </label>
          )}
          <button type="submit" disabled={disabled}>Sisipkan</button>
          <button type="button" className="blog-editor-cancel" onClick={() => setActiveTool(null)}>Batal</button>
          {toolError && <p className="blog-editor-error" role="alert">{toolError}</p>}
        </form>
      )}

      {editorMode === "visual" ? (
        <div
          ref={visualEditorRef}
          className="blog-visual-canvas"
          role="textbox"
          aria-label="Isi artikel visual"
          aria-multiline="true"
          contentEditable={!disabled}
          suppressContentEditableWarning
          spellCheck
          onInput={commitVisualChange}
          onSelect={captureEditorSelection}
          onKeyUp={captureEditorSelection}
          onMouseUp={captureEditorSelection}
          onBlur={captureEditorSelection}
          onPaste={(event) => {
            event.preventDefault();
            const text = event.clipboardData.getData("text/plain");
            document.execCommand("insertText", false, text);
            commitVisualChange();
          }}
          onDrop={(event) => event.preventDefault()}
          dangerouslySetInnerHTML={initialVisualHtml}
        />
      ) : (
        <textarea
          ref={textareaRef}
          aria-label="Kode isi artikel"
          value={content}
          onChange={(event) => {
            selectionRef.current = {
              start: event.target.selectionStart,
              end: event.target.selectionEnd,
            };
            onChange(event.target.value);
          }}
          onSelect={captureEditorSelection}
          onKeyUp={captureEditorSelection}
          onMouseUp={captureEditorSelection}
          maxLength={200000}
          rows={22}
          disabled={disabled}
          placeholder={"Mulai dengan pembuka yang menjelaskan topik artikel.\n\n## Judul bagian\n\nKembangkan satu gagasan dalam setiap paragraf."}
        />
      )}
      {toolError && !activeTool && (
        <p className="blog-editor-error" role="alert">{toolError}</p>
      )}
      <div className="blog-editor-footer">
        <span>
          {editorMode === "visual"
            ? "Format langsung terlihat. Pilih mode Kode untuk mengedit sintaks artikel."
            : "Mode Kode menampilkan format artikel. Font tersedia untuk penggunaan komersial."}
        </span>
        <span>{content.length.toLocaleString("id-ID")} / 200.000</span>
      </div>

      <style jsx>{`
        .blog-rich-editor {
          border: 1px solid #cfd8df;
          border-radius: 12px;
          overflow: hidden;
          background: #fff;
        }
        .blog-editor-modes {
          display: flex;
          gap: 4px;
          padding: 8px 9px 0;
          background: #f8fafb;
        }
        .blog-editor-modes button {
          min-height: 32px;
          padding: 0 13px;
          border: 1px solid transparent;
          border-radius: 7px 7px 0 0;
          background: transparent;
          color: #526176;
          font: inherit;
          font-size: 12px;
          font-weight: 700;
          cursor: pointer;
        }
        .blog-editor-modes button[aria-pressed="true"] {
          border-color: #d6dfe5;
          border-bottom-color: #fff;
          background: #fff;
          color: #087fa1;
        }
        .blog-editor-toolbar {
          display: flex;
          flex-wrap: wrap;
          gap: 5px;
          padding: 9px;
          border-bottom: 1px solid #e2e8ed;
          background: #f8fafb;
        }
        .blog-editor-toolbar button,
        .blog-editor-insert-form button {
          min-height: 34px;
          padding: 0 10px;
          border: 1px solid #d6dfe5;
          border-radius: 7px;
          background: #fff;
          color: #243848;
          font: inherit;
          font-size: 12px;
          font-weight: 700;
          cursor: pointer;
        }
        .blog-editor-toolbar button:hover,
        .blog-editor-insert-form button:hover {
          border-color: #0589ad;
          background: #f0fbff;
        }
        .blog-editor-toolbar select {
          min-height: 34px;
          max-width: 180px;
          padding: 0 8px;
          border: 1px solid #d6dfe5;
          border-radius: 7px;
          background: #fff;
          color: #243848;
          font-size: 12px;
        }
        .blog-toolbar-select-label,
        .blog-toolbar-color-label {
          display: inline-flex;
          align-items: center;
          gap: 5px;
          color: #526176;
          font-size: 11px;
          font-weight: 700;
        }
        .blog-toolbar-select-label select {
          font-weight: 600;
        }
        .blog-toolbar-color-label input {
          width: 34px;
          height: 34px;
          padding: 3px;
          border: 1px solid #d6dfe5;
          border-radius: 7px;
          background: #fff;
          cursor: pointer;
        }
        .blog-toolbar-align {
          display: inline-flex;
          gap: 4px;
        }
        .blog-toolbar-align button {
          min-width: 48px;
          padding: 0 7px;
          font-size: 11px;
        }
        .blog-toolbar-divider {
          width: 1px;
          margin: 3px 4px;
          background: #d6dfe5;
        }
        .blog-editor-insert-form {
          display: flex;
          flex-wrap: wrap;
          align-items: end;
          gap: 10px;
          padding: 12px;
          border-bottom: 1px solid #e2e8ed;
          background: #f5fafb;
        }
        .blog-editor-insert-form label {
          display: grid;
          flex: 1 1 200px;
          gap: 5px;
          color: #34495a;
          font-size: 12px;
          font-weight: 700;
        }
        .blog-editor-insert-form input {
          width: 100%;
          min-height: 38px;
          padding: 0 10px;
          border: 1px solid #cfd8df;
          border-radius: 7px;
          font: inherit;
          font-size: 13px;
          box-sizing: border-box;
        }
        .blog-editor-insert-form .blog-editor-cancel {
          background: transparent;
        }
        .blog-editor-error {
          flex-basis: 100%;
          margin: 0;
          color: #b42318;
          font-size: 12px;
        }
        .blog-rich-editor textarea {
          display: block;
          width: 100%;
          min-height: 420px;
          padding: 18px;
          border: 0;
          outline: none;
          resize: vertical;
          color: #253746;
          font: 14px/1.8 ui-monospace, SFMono-Regular, Consolas, monospace;
          box-sizing: border-box;
        }
        .blog-visual-canvas {
          min-height: 420px;
          padding: 18px;
          outline: none;
          color: #253746;
          font: 16px/1.8 "DM Sans", sans-serif;
          overflow-wrap: anywhere;
        }
        .blog-visual-canvas:focus {
          box-shadow: inset 0 0 0 2px #74cde2;
        }
        .blog-visual-canvas > :first-child {
          margin-top: 0;
        }
        .blog-visual-canvas > :last-child {
          margin-bottom: 0;
        }
        .blog-visual-canvas img {
          max-width: 100%;
          height: auto;
        }
        .blog-rich-editor textarea:focus {
          box-shadow: inset 0 0 0 2px #74cde2;
        }
        .blog-editor-footer {
          display: flex;
          justify-content: space-between;
          gap: 12px;
          padding: 9px 13px;
          border-top: 1px solid #e2e8ed;
          color: #657384;
          font-size: 11px;
        }
        @media (max-width: 560px) {
          .blog-editor-toolbar {
            gap: 6px;
          }
          .blog-editor-toolbar select {
            max-width: 142px;
          }
          .blog-toolbar-select-label,
          .blog-toolbar-color-label {
            flex-wrap: wrap;
          }
          .blog-editor-footer {
            flex-direction: column;
          }
          .blog-rich-editor textarea {
            min-height: 320px;
            padding: 13px;
          }
          .blog-visual-canvas {
            min-height: 320px;
            padding: 13px;
          }
        }
      `}</style>
    </div>
  );
}
