"use client";
import React, { useEffect, useRef, useState } from "react";
import dynamic from "next/dynamic";
import "@fontsource/jetbrains-mono";
import { marked } from "marked";

const MonacoEditor = dynamic(() => import("@monaco-editor/react"), { ssr: false });

// File/folder types from API
interface FileNode {
  type: "post";
  slug: string;
  title: string;
  date: string;
  tags: string[];
  summary: string;
  content: string;
  createdAt: string;
  pinned: boolean;
}
interface FolderNode {
  type: "folder";
  name: string;
  path: string;
  emoji: string;
  children: (FileNode | FolderNode)[];
}
type Node = FileNode | FolderNode;

// Helper to strip YAML frontmatter
function stripFrontmatter(md: string): string {
  if (!md) return '';
  if (md.startsWith('---')) {
    const end = md.indexOf('---', 3);
    if (end !== -1) return md.slice(end + 3).replace(/^\s+/, '');
  }
  return md;
}

function FileTree({ nodes, onSelect, selectedSlug, level = 0 }: {
  nodes: Node[];
  onSelect: (slug: string) => void;
  selectedSlug: string | null;
  level?: number;
}) {
  const [openFolders, setOpenFolders] = useState<Record<string, boolean>>({});
  return (
    <ul className="pl-2">
      {nodes.map((node) => {
        if (node.type === "folder") {
          const isOpen = openFolders[node.path] ?? true;
          return (
            <li key={node.path} className="mb-1">
              <button
                className="flex items-center gap-1 text-gray-700 hover:bg-gray-100 rounded px-1 py-0.5 w-full"
                style={{ paddingLeft: 8 + level * 12 }}
                onClick={() => setOpenFolders(f => ({ ...f, [node.path]: !isOpen }))}
              >
                <span className="text-lg">{node.emoji || "📁"}</span>
                <span className="font-semibold text-sm">{node.name}</span>
                <span className="ml-auto text-xs">{isOpen ? "▼" : "▶"}</span>
              </button>
              {isOpen && (
                <FileTree nodes={node.children} onSelect={onSelect} selectedSlug={selectedSlug} level={level + 1} />
              )}
            </li>
          );
        } else {
          return (
            <li key={node.slug}>
              <button
                className={`flex items-center gap-2 px-2 py-1 rounded w-full text-left text-sm font-mono ${selectedSlug === node.slug ? "bg-blue-100 text-blue-800 font-bold" : "hover:bg-gray-100 text-gray-800"}`}
                style={{ paddingLeft: 8 + level * 12 }}
                onClick={() => onSelect(node.slug)}
                title={node.title}
              >
                <span className="text-gray-400">📝</span>
                <span className="truncate">{node.title || node.slug}</span>
              </button>
            </li>
          );
        }
      })}
    </ul>
  );
}

export default function EditorPage() {
  // State
  const [tree, setTree] = useState<Node[]>([]);
  const [selectedSlug, setSelectedSlug] = useState<string | null>(null);
  const [fileContent, setFileContent] = useState<string>("");
  const [fileTitle, setFileTitle] = useState<string>("");
  const [vimMode, setVimMode] = useState(false);
  const [previewHtml, setPreviewHtml] = useState<string>("");
  const [split, setSplit] = useState(50); // percent
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [browserOpen, setBrowserOpen] = useState(true);
  const editorRef = useRef<any>(null);
  const monacoVimRef = useRef<any>(null);

  // Fetch file tree
  useEffect(() => {
    fetch("/api/posts")
      .then(r => r.json())
      .then(setTree);
  }, []);

  // Load file content when selected
  useEffect(() => {
    if (!selectedSlug) return;
    setLoading(true);
    fetch(`/api/posts/${encodeURIComponent(selectedSlug)}`)
      .then(r => r.json())
      .then(data => {
        setFileContent(stripFrontmatter(data.raw || data.content || ""));
        setFileTitle(data.title || data.slug || "");
        setLoading(false);
      });
  }, [selectedSlug]);

  // Save file
  async function handleSave() {
    if (!selectedSlug) return;
    setSaving(true);
    await fetch(`/api/posts/${encodeURIComponent(selectedSlug)}`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ markdown: fileContent })
    });
    setSaving(false);
  }

  // Live preview (JS markdown, not Rust)
  useEffect(() => {
    if (!fileContent) { setPreviewHtml(""); return; }
    const html = typeof marked.parse === 'function' ? marked.parse(stripFrontmatter(fileContent)) : '';
    if (typeof html === 'string') setPreviewHtml(html);
    else if (html instanceof Promise) html.then(setPreviewHtml);
    else setPreviewHtml('');
  }, [fileContent]);

  // Monaco Vim integration
  async function handleEditorDidMount(editor: any, monaco: any) {
    editorRef.current = editor;
    if (vimMode) {
      const { initVimMode } = await import("monaco-vim");
      if (monacoVimRef.current) monacoVimRef.current.dispose();
      monacoVimRef.current = initVimMode(editor, document.getElementById("vim-status"));
    }
  }
  useEffect(() => {
    if (!editorRef.current) return;
    let disposed = false;
    async function setupVim() {
      if (monacoVimRef.current) monacoVimRef.current.dispose();
      if (vimMode) {
        const { initVimMode } = await import("monaco-vim");
        if (!disposed) {
          monacoVimRef.current = initVimMode(editorRef.current, document.getElementById("vim-status"));
        }
      }
    }
    setupVim();
    return () => { disposed = true; };
  }, [vimMode]);

  // Split drag logic
  const dragRef = useRef(false);
  function onDrag(e: React.MouseEvent) {
    if (!dragRef.current) return;
    const percent = (e.clientX / window.innerWidth) * 100;
    setSplit(Math.max(20, Math.min(80, percent)));
  }
  function onDragStart() { dragRef.current = true; document.body.style.cursor = "col-resize"; }
  function onDragEnd() { dragRef.current = false; document.body.style.cursor = ""; }
  useEffect(() => {
    function onMove(e: MouseEvent) { onDrag(e as any); }
    function onUp() { onDragEnd(); }
    if (dragRef.current) {
      window.addEventListener("mousemove", onMove);
      window.addEventListener("mouseup", onUp);
      return () => { window.removeEventListener("mousemove", onMove); window.removeEventListener("mouseup", onUp); };
    }
  }, [dragRef.current]);

  // Only render MonacoEditor if the editor pane is visible and has width
  const showEditor = browserOpen ? true : split > 5;

  return (
    <div className="h-screen w-screen bg-white flex flex-col font-mono" style={{ fontFamily: 'JetBrains Mono, monospace', fontWeight: 'bold' }}>
      {/* Header */}
      <div className="flex items-center justify-between px-4 py-2 bg-gray-50 border-b border-gray-200">
        <div className="flex items-center gap-2">
          {/* VS Code SVG Icon (smaller) */}
          <svg
            viewBox="0 0 100 100"
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
            className="w-6 h-6"
            style={{ minWidth: 20, minHeight: 20, width: 24, height: 24 }}
          >
            <mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="100">
              <path fillRule="evenodd" clipRule="evenodd" d="M70.9119 99.3171C72.4869 99.9307 74.2828 99.8914 75.8725 99.1264L96.4608 89.2197C98.6242 88.1787 100 85.9892 100 83.5872V16.4133C100 14.0113 98.6243 11.8218 96.4609 10.7808L75.8725 0.873756C73.7862 -0.130129 71.3446 0.11576 69.5135 1.44695C69.252 1.63711 69.0028 1.84943 68.769 2.08341L29.3551 38.0415L12.1872 25.0096C10.589 23.7965 8.35363 23.8959 6.86933 25.2461L1.36303 30.2549C-0.452552 31.9064 -0.454633 34.7627 1.35853 36.417L16.2471 50.0001L1.35853 63.5832C-0.454633 65.2374 -0.452552 68.0938 1.36303 69.7453L6.86933 74.7541C8.35363 76.1043 10.589 76.2037 12.1872 74.9905L29.3551 61.9587L68.769 97.9167C69.3925 98.5406 70.1246 99.0104 70.9119 99.3171ZM75.0152 27.2989L45.1091 50.0001L75.0152 72.7012V27.2989Z" fill="white"/>
            </mask>
            <g mask="url(#mask0)">
              <path d="M96.4614 10.7962L75.8569 0.875542C73.4719 -0.272773 70.6217 0.211611 68.75 2.08333L1.29858 63.5832C-0.515693 65.2373 -0.513607 68.0937 1.30308 69.7452L6.81272 74.754C8.29793 76.1042 10.5347 76.2036 12.1338 74.9905L93.3609 13.3699C96.086 11.3026 100 13.2462 100 16.6667V16.4275C100 14.0265 98.6246 11.8378 96.4614 10.7962Z" fill="#0065A9"/>
              <g filter="url(#filter0_d)">
                <path d="M96.4614 89.2038L75.8569 99.1245C73.4719 100.273 70.6217 99.7884 68.75 97.9167L1.29858 36.4169C-0.515693 34.7627 -0.513607 31.9063 1.30308 30.2548L6.81272 25.246C8.29793 23.8958 10.5347 23.7964 12.1338 25.0095L93.3609 86.6301C96.086 88.6974 100 86.7538 100 83.3334V83.5726C100 85.9735 98.6246 88.1622 96.4614 89.2038Z" fill="#007ACC"/>
              </g>
              <g filter="url(#filter1_d)">
                <path d="M75.8578 99.1263C73.4721 100.274 70.6219 99.7885 68.75 97.9166C71.0564 100.223 75 98.5895 75 95.3278V4.67213C75 1.41039 71.0564 -0.223106 68.75 2.08329C70.6219 0.211402 73.4721 -0.273666 75.8578 0.873633L96.4587 10.7807C98.6234 11.8217 100 14.0112 100 16.4132V83.5871C100 85.9891 98.6234 88.1786 96.4586 89.2196L75.8578 99.1263Z" fill="#1F9CF0"/>
              </g>
              <g style={{ mixBlendMode: 'overlay' }} opacity="0.25">
                <path fillRule="evenodd" clipRule="evenodd" d="M70.8511 99.3171C72.4261 99.9306 74.2221 99.8913 75.8117 99.1264L96.4 89.2197C98.5634 88.1787 99.9392 85.9892 99.9392 83.5871V16.4133C99.9392 14.0112 98.5635 11.8217 96.4001 10.7807L75.8117 0.873695C73.7255 -0.13019 71.2838 0.115699 69.4527 1.44688C69.1912 1.63705 68.942 1.84937 68.7082 2.08335L29.2943 38.0414L12.1264 25.0096C10.5283 23.7964 8.29285 23.8959 6.80855 25.246L1.30225 30.2548C-0.513334 31.9064 -0.515415 34.7627 1.29775 36.4169L16.1863 50L1.29775 63.5832C-0.515415 65.2374 -0.513334 68.0937 1.30225 69.7452L6.80855 74.754C8.29285 76.1042 10.5283 76.2036 12.1264 74.9905L29.2943 61.9586L68.7082 97.9167C69.3317 98.5405 70.0638 99.0104 70.8511 99.3171ZM74.9544 27.2989L45.0483 50L74.9544 72.7012V27.2989Z" fill="url(#paint0_linear)"/>
              </g>
            </g>
            <defs>
              <filter id="filter0_d" x="-8.39411" y="15.8291" width="116.727" height="92.2456" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
                <feFlood floodOpacity="0" result="BackgroundImageFix"/>
                <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
                <feOffset/>
                <feGaussianBlur stdDeviation="4.16667"/>
                <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
                <feBlend mode="overlay" in2="BackgroundImageFix" result="effect1_dropShadow"/>
                <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
              </filter>
              <filter id="filter1_d" x="60.4167" y="-8.07558" width="47.9167" height="116.151" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
                <feFlood floodOpacity="0" result="BackgroundImageFix"/>
                <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
                <feOffset/>
                <feGaussianBlur stdDeviation="4.16667"/>
                <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
                <feBlend mode="overlay" in2="BackgroundImageFix" result="effect1_dropShadow"/>
                <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
              </filter>
              <linearGradient id="paint0_linear" x1="49.9392" y1="0.257812" x2="49.9392" y2="99.7423" gradientUnits="userSpaceOnUse">
                <stop stopColor="white"/>
                <stop offset="1" stopColor="white" stopOpacity="0"/>
              </linearGradient>
            </defs>
          </svg>
          <span className="text-black text-lg font-semibold">Markdown Editor</span>
        </div>
        <div className="flex gap-2 items-center">
          <button
            onClick={handleSave}
            className={`flex items-center gap-2 px-3 py-1 rounded transition-colors border border-blue-400 bg-blue-500 text-white hover:bg-blue-600 font-mono ${saving ? 'opacity-60 cursor-wait' : ''}`}
            disabled={saving}
          >
            <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a2 2 0 01-2 2H7a2 2 0 01-2-2V7a2 2 0 012-2h4a2 2 0 012 2v1" /></svg>
            <span>Save</span>
          </button>
          <button
            onClick={() => setVimMode((v) => !v)}
            className={`flex items-center gap-2 px-3 py-1 rounded transition-colors border border-gray-300 ${vimMode ? "bg-green-600 text-white" : "bg-white text-gray-700 hover:bg-gray-100"}`}
          >
            {/* Actual Vim SVG Icon */}
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" className="w-5 h-5" fill="currentColor">
              <title>vim</title>
              <path d="M26.445 22.095l0.592-0.649h1.667l0.386 0.519-1.581 5.132h0.616l-0.1 0.261h-2.228l1.405-4.454h-2.518l-1.346 4.238h0.53l-0.091 0.217h-2.006l1.383-4.434h-2.619l-1.327 4.172h0.545l-0.090 0.261h-2.076l1.892-5.573h-0.732l0.114-0.339h2.062l0.649 0.671h1.132l0.614-0.692h1.326l0.611 0.669zM7.99 27.033h-2.141l-0.327-0.187v-21.979h-1.545l-0.125-0.125v-1.47l0.179-0.192h9.211l0.266 0.267v1.385l-0.177 0.216h-1.348v10.857l11.006-10.857h-2.607l-0.219-0.235v-1.453l0.151-0.139h9.36l0.165 0.166v1.337l-12.615 12.937h-0.466c-0.005-0-0.011-0-0.018-0-0.012 0-0.024 0.001-0.036 0.002l0.002-0-0.025 0.004c-0.058 0.012-0.108 0.039-0.149 0.075l0-0-0.429 0.369-0.005 0.004c-0.040 0.037-0.072 0.084-0.090 0.136l-0.001 0.002-0.37 1.037zM17.916 18.028l0.187 0.189-0.336 1.152-0.281 0.282h-1.211l-0.226-0.226 0.389-1.088 0.36-0.309zM13.298 27.42l1.973-5.635h-0.626l0.371-0.38h2.073l-1.953 5.692h0.779l-0.099 0.322zM30.996 15.982h-0.034l-5.396-5.396 5.377-5.516v-2.24l-0.811-0.81h-10.245l-0.825 0.756v1.306l-3.044-3.044v-0.034l-0.019 0.018-0.018-0.018v0.034l-1.612 1.613-0.672-0.673h-10.151l-0.797 0.865v2.356l0.77 0.77h0.9v6.636l-3.382 3.38h-0.034l0.018 0.016-0.018 0.017h0.034l3.382 3.382v8.081l1.133 0.654h2.902l2.321-2.379 5.206 5.206v0.035l0.019-0.017 0.017 0.017v-0.035l3.136-3.135h0.606c0.144-0.001 0.266-0.093 0.312-0.221l0.001-0.002 0.182-0.532c0.011-0.031 0.017-0.067 0.017-0.105 0-0.073-0.024-0.14-0.064-0.195l0.001 0.001 1.827-1.827-0.765 2.452c-0.009 0.029-0.015 0.063-0.015 0.097 0 0.149 0.098 0.275 0.233 0.317l0.002 0.001c0.029 0.009 0.063 0.015 0.097 0.015 0 0 0 0 0 0h2.279c0.136-0.001 0.252-0.084 0.303-0.201l0.001-0.002 0.206-0.492c0.014-0.036 0.022-0.077 0.022-0.121 0-0.048-0.010-0.094-0.028-0.135l0.001 0.002c-0.035-0.082-0.1-0.145-0.18-0.177l-0.002-0.001c-0.036-0.015-0.077-0.024-0.121-0.025h-0.094l1.050-3.304h1.54l-1.27 4.025c-0.009 0.029-0.015 0.063-0.015 0.097 0 0.149 0.098 0.274 0.232 0.317l0.002 0.001c0.029 0.009 0.063 0.015 0.098 0.015 0 0 0.001 0 0.001 0h2.502c0 0 0.001 0 0.001 0 0.14 0 0.26-0.087 0.308-0.21l0.001-0.002 0.205-0.535c0.013-0.034 0.020-0.073 0.020-0.114 0-0.142-0.090-0.264-0.215-0.311l-0.002-0.001c-0.034-0.013-0.073-0.021-0.114-0.021h-0.181l1.413-4.59c0.011-0.031 0.017-0.066 0.017-0.103 0-0.074-0.025-0.143-0.066-0.198l0.001 0.001-0.469-0.63-0.004-0.006c-0.061-0.078-0.156-0.127-0.261-0.127h-1.795c-0.093 0-0.177 0.039-0.237 0.101l-0 0-0.5 0.549h-0.78l-0.052-0.057 5.555-5.555h0.035l-0.017-0.014z"/>
            </svg>
            <span className="hidden sm:inline">Vim Mode</span>
          </button>
        </div>
      </div>
      {/* Split Layout */}
      <div className="flex flex-1 min-h-0" style={{ userSelect: dragRef.current ? "none" : undefined }}>
        {/* Left: File browser + Editor */}
        <div className="flex flex-col" style={{ width: browserOpen ? `${split}%` : '48px', minWidth: browserOpen ? 240 : 48, maxWidth: 900, background: "#fff" }}>
          {/* File Browser Collapsible Toggle */}
          <button
            className="w-full flex items-center gap-2 px-2 py-1 bg-gray-100 border-b border-gray-200 text-gray-700 font-mono hover:bg-gray-200 focus:outline-none"
            onClick={() => setBrowserOpen(o => !o)}
            style={{ fontFamily: 'JetBrains Mono, monospace' }}
          >
            <span className="text-lg">{browserOpen ? '▼' : '▶'}</span>
            <span className="font-bold text-sm">Files</span>
          </button>
          {browserOpen && (
            <div className="h-48 border-b border-gray-200 p-2 overflow-auto bg-gray-50 text-gray-800 font-mono">
              {tree.length === 0 ? (
                <div className="text-xs text-gray-400">No files found.</div>
              ) : (
                <FileTree nodes={tree} onSelect={setSelectedSlug} selectedSlug={selectedSlug} />
              )}
            </div>
          )}
          {/* Monaco Editor */}
          <div className="flex-1 p-0 overflow-auto" style={{ fontFamily: 'JetBrains Mono, monospace', fontWeight: 'bold' }}>
            <div className="h-full">
              {showEditor && (
                <MonacoErrorBoundary>
                  <MonacoEditor
                    height="100%"
                    defaultLanguage="markdown"
                    value={fileContent}
                    theme="light"
                    options={{
                      fontFamily: 'JetBrains Mono',
                      fontWeight: 'bold',
                      fontSize: 15,
                      minimap: { enabled: false },
                      wordWrap: "on",
                      scrollBeyondLastLine: false,
                      smoothScrolling: true,
                      automaticLayout: true,
                      lineNumbers: "on",
                      renderLineHighlight: "all",
                      scrollbar: { vertical: "auto", horizontal: "auto" },
                      tabSize: 2,
                      cursorBlinking: "smooth",
                      cursorStyle: "line",
                      fixedOverflowWidgets: true,
                      readOnly: loading,
                    }}
                    onChange={v => setFileContent(v ?? "")}
                    onMount={handleEditorDidMount}
                  />
                </MonacoErrorBoundary>
              )}
              <div id="vim-status" className="text-xs text-gray-500 px-2 py-1 bg-gray-100 border-t border-gray-200 font-mono" />
            </div>
          </div>
        </div>
        {/* Draggable Splitter */}
        <div
          className="w-2 cursor-col-resize bg-gray-200 hover:bg-gray-300 transition-colors"
          onMouseDown={onDragStart}
        />
        {/* Right: Live Preview */}
        <div className="flex-1 bg-gray-50 p-8 overflow-auto border-l border-gray-200">
          <article className="bg-white rounded-lg shadow-sm border p-6 sm:p-8">
            <header className="mb-8">
              <h1 className="text-3xl sm:text-4xl font-bold text-gray-900 mb-4 leading-tight">
                {fileTitle}
              </h1>
            </header>
            <div 
              className="prose prose-lg max-w-none prose-headings:text-gray-900 prose-p:text-gray-700 prose-a:text-blue-600 prose-a:no-underline hover:prose-a:underline prose-strong:text-gray-900 prose-code:text-gray-800 prose-code:bg-gray-100 prose-code:px-1 prose-code:py-0.5 prose-code:rounded prose-pre:bg-gray-900 prose-pre:text-gray-100"
              style={{ fontFamily: 'inherit', fontWeight: 'normal' }}
              dangerouslySetInnerHTML={{ __html: previewHtml }}
            />
          </article>
        </div>
      </div>
    </div>
  );
}

// ErrorBoundary component for Monaco
class MonacoErrorBoundary extends React.Component<{children: React.ReactNode}, {error: Error | null}> {
  constructor(props: any) {
    super(props);
    this.state = { error: null };
  }
  static getDerivedStateFromError(error: Error) {
    return { error };
  }
  componentDidCatch(error: Error, info: any) {
    // Optionally log error
  }
  render() {
    if (this.state.error) {
      return <div className="text-red-600 p-4">Editor error: {this.state.error.message}</div>;
    }
    return this.props.children;
  }
} 