// components.jsx — UI atoms and panels for the markdown editor

// ── Icon set ────────────────────────────────────────────────────────────────
const Icon = ({ name, size = 16, ...rest }) => {
  const paths = {
    'edit':       <><path d="M14 2.5L17.5 6 7 16.5H3.5V13L14 2.5Z" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinejoin="round"/></>,
    'eye':        <><path d="M2 10s2.5-5 8-5 8 5 8 5-2.5 5-8 5-8-5-8-5Z" stroke="currentColor" strokeWidth="1.5" fill="none"/><circle cx="10" cy="10" r="2.5" stroke="currentColor" strokeWidth="1.5" fill="none"/></>,
    'split':      <><rect x="2.5" y="3.5" width="15" height="13" rx="1.5" stroke="currentColor" strokeWidth="1.5" fill="none"/><line x1="10" y1="3.5" x2="10" y2="16.5" stroke="currentColor" strokeWidth="1.5"/></>,
    'sidebar':    <><rect x="2.5" y="3.5" width="15" height="13" rx="1.5" stroke="currentColor" strokeWidth="1.5" fill="none"/><line x1="7.5" y1="3.5" x2="7.5" y2="16.5" stroke="currentColor" strokeWidth="1.5"/></>,
    'sun':        <><circle cx="10" cy="10" r="3.5" stroke="currentColor" strokeWidth="1.5" fill="none"/><path d="M10 2v2M10 16v2M2 10h2M16 10h2M4.2 4.2l1.4 1.4M14.4 14.4l1.4 1.4M4.2 15.8l1.4-1.4M14.4 5.6l1.4-1.4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></>,
    'moon':       <><path d="M16 11.2A6.5 6.5 0 0 1 8.8 4 6.5 6.5 0 1 0 16 11.2Z" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinejoin="round"/></>,
    'maximize':   <><path d="M3.5 7V3.5H7M13 3.5h3.5V7M16.5 13v3.5H13M7 16.5H3.5V13" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round"/></>,
    'globe':      <><circle cx="10" cy="10" r="7" stroke="currentColor" strokeWidth="1.5" fill="none"/><path d="M3 10h14M10 3a10 10 0 0 1 0 14M10 3a10 10 0 0 0 0 14" stroke="currentColor" strokeWidth="1.5" fill="none"/></>,
    'download':   <><path d="M10 3v10m0 0l-3.5-3.5M10 13l3.5-3.5M3.5 16h13" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></>,
    'file':       <><path d="M5 2.5h6L15 6.5v11H5v-15Z" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinejoin="round"/><path d="M11 2.5v4h4" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinejoin="round"/></>,
    'list':       <><path d="M3 5h14M3 10h14M3 15h14" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></>,
    'plus':       <><path d="M10 4v12M4 10h12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></>,
    'search':     <><circle cx="9" cy="9" r="5" stroke="currentColor" strokeWidth="1.5" fill="none"/><path d="M13 13l4 4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></>,
    'more':       <><circle cx="5" cy="10" r="1.3" fill="currentColor"/><circle cx="10" cy="10" r="1.3" fill="currentColor"/><circle cx="15" cy="10" r="1.3" fill="currentColor"/></>,
    'pdf':        <><path d="M5 2.5h6L15 6.5v11H5v-15Z" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinejoin="round"/><path d="M11 2.5v4h4" stroke="currentColor" strokeWidth="1.5" fill="none"/><text x="6.5" y="14.5" fontSize="4.6" fontWeight="700" fill="currentColor" fontFamily="ui-sans-serif">PDF</text></>,
    'html':       <><path d="M3 5l3 5-3 5M17 5l-3 5 3 5M11.5 4l-3 12" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></>,
    'check':      <><path d="M4 10.5l4 4 8-9" stroke="currentColor" strokeWidth="1.8" fill="none" strokeLinecap="round" strokeLinejoin="round"/></>,
    'x':          <><path d="M5 5l10 10M15 5L5 15" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></>,
    'tweaks':     <><path d="M4 6h8M16 6h0M4 14h2M10 14h6M12 4v4M6 12v4" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round"/></>,
    'save':       <><path d="M3.5 3.5h10L17 7v9.5h-13v-13Z" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinejoin="round"/><path d="M6 3.5v4.5h7v-4.5M6.5 16.5v-5h6v5" stroke="currentColor" strokeWidth="1.5" fill="none"/></>,
    'trash':      <><path d="M4 6h12M8 6V4h4v2M5.5 6l1 11h7l1-11" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></>,
    'rename':     <><path d="M3 16.5h14M5 13.5l8.5-8.5 2 2L7 15.5H5v-2Z" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinejoin="round"/></>,
    'duplicate':  <><rect x="6.5" y="6.5" width="9" height="10" rx="1.5" stroke="currentColor" strokeWidth="1.5" fill="none"/><path d="M4 13.5V4.5h9" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round"/></>,
    'chev-down':  <><path d="M5 8l5 5 5-5" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></>,
    'circle':     <><circle cx="10" cy="10" r="6" stroke="currentColor" strokeWidth="1.5" fill="none"/></>,
    'pen':        <><path d="M3 17h4l9-9-4-4-9 9v4Z" stroke="currentColor" strokeWidth="1.5" fill="none" strokeLinejoin="round"/><path d="M11 5l4 4" stroke="currentColor" strokeWidth="1.5"/></>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" {...rest}>
      {paths[name] || null}
    </svg>
  );
};

// ── Brand mark ──────────────────────────────────────────────────────────────
const BrandMark = () => (
  <div className="brand-mark" aria-hidden>I</div>
);

// ── Segmented mode toggle ───────────────────────────────────────────────────
function ModeToggle({ value, onChange, t }) {
  const ref = React.useRef(null);
  const [thumb, setThumb] = React.useState({ left: 2, width: 0 });
  const opts = [
    { value: 'edit',    label: t.mode_edit,    icon: 'edit' },
    { value: 'split',   label: t.mode_split,   icon: 'split' },
    { value: 'preview', label: t.mode_preview, icon: 'eye' },
  ];
  React.useLayoutEffect(() => {
    const el = ref.current;
    if (!el) return;
    const idx = opts.findIndex(o => o.value === value);
    const btn = el.querySelectorAll('button')[idx];
    if (btn) setThumb({ left: btn.offsetLeft, width: btn.offsetWidth });
  }, [value]);
  return (
    <div className="seg" ref={ref}>
      <div className="seg-thumb" style={{ left: thumb.left, width: thumb.width }} />
      {opts.map(o => (
        <button key={o.value} className={value === o.value ? 'active' : ''} onClick={() => onChange(o.value)}>
          <Icon name={o.icon} />{o.label}
        </button>
      ))}
    </div>
  );
}

// ── Dropdown menu ───────────────────────────────────────────────────────────
function Menu({ anchor, items, onClose, align = 'right' }) {
  const ref = React.useRef(null);
  const [pos, setPos] = React.useState(null);
  React.useLayoutEffect(() => {
    if (!anchor || !ref.current) return;
    const r = anchor.getBoundingClientRect();
    const mw = ref.current.offsetWidth;
    setPos({
      top: r.bottom + 6,
      left: align === 'right' ? r.right - mw : r.left,
    });
  }, [anchor]);
  React.useEffect(() => {
    const onDoc = (e) => {
      if (ref.current && !ref.current.contains(e.target) && anchor && !anchor.contains(e.target)) {
        onClose();
      }
    };
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('mousedown', onDoc);
    document.addEventListener('keydown', onKey);
    return () => {
      document.removeEventListener('mousedown', onDoc);
      document.removeEventListener('keydown', onKey);
    };
  }, [anchor, onClose]);
  return (
    <div ref={ref} className="menu" style={{ top: pos?.top ?? -9999, left: pos?.left ?? -9999 }}>
      {items.map((it, i) => {
        if (it.divider) return <div key={i} className="menu-divider" />;
        if (it.section) return <div key={i} className="menu-section">{it.section}</div>;
        return (
          <div key={i} className="menu-item" onClick={() => { it.onClick && it.onClick(); onClose(); }}>
            {it.icon && <Icon name={it.icon} size={14} className="menu-icon" />}
            <span style={{ flex: 1 }}>{it.label}</span>
            {it.shortcut && <span className="menu-shortcut">{it.shortcut}</span>}
            {it.checked && <Icon name="check" size={13} className="menu-icon" />}
          </div>
        );
      })}
    </div>
  );
}

// ── Sidebar ─────────────────────────────────────────────────────────────────
function Sidebar({ docs, activeId, onSelect, onCreate, onRename, onDelete, onDuplicate, headings, activeHeading, onJumpHeading, t }) {
  const [tab, setTab] = React.useState('files');
  const [q, setQ] = React.useState('');
  const [renaming, setRenaming] = React.useState(null);
  const [renameVal, setRenameVal] = React.useState('');
  const [menuAnchor, setMenuAnchor] = React.useState(null);
  const [menuDoc, setMenuDoc] = React.useState(null);

  const filtered = docs.filter(d => !q || d.name.toLowerCase().includes(q.toLowerCase()) || d.content.toLowerCase().includes(q.toLowerCase()));

  const startRename = (doc) => { setRenaming(doc.id); setRenameVal(doc.name); };
  const finishRename = () => {
    if (renaming && renameVal.trim()) onRename(renaming, renameVal.trim());
    setRenaming(null);
  };

  return (
    <aside className="sidebar">
      <div className="sidebar-tabs">
        <button className={`sidebar-tab ${tab === 'files' ? 'active' : ''}`} onClick={() => setTab('files')}>
          <Icon name="file" />{t.tab_files}
        </button>
        <button className={`sidebar-tab ${tab === 'outline' ? 'active' : ''}`} onClick={() => setTab('outline')}>
          <Icon name="list" />{t.tab_outline}
        </button>
      </div>

      {tab === 'files' && (
        <>
          <div className="file-search">
            <Icon name="search" />
            <input placeholder={t.search_placeholder} value={q} onChange={e => setQ(e.target.value)} />
          </div>
          <div className="sidebar-content">
            <div className="file-section-label">
              <span>{t.documents}</span>
              <button className="icon-btn" onClick={onCreate} title={t.new_doc}><Icon name="plus" /></button>
            </div>
            {filtered.map(doc => (
              <div key={doc.id}
                   className={`file-item ${doc.id === activeId ? 'active' : ''} ${doc.dirty ? 'dirty' : ''}`}
                   onClick={() => onSelect(doc.id)}
                   onDoubleClick={() => startRename(doc)}>
                <Icon name="file" className="file-item-icon" />
                {renaming === doc.id ? (
                  <input
                    autoFocus
                    value={renameVal}
                    onChange={e => setRenameVal(e.target.value)}
                    onBlur={finishRename}
                    onKeyDown={e => {
                      if (e.key === 'Enter') finishRename();
                      else if (e.key === 'Escape') setRenaming(null);
                    }}
                    style={{ flex: 1, border: 0, outline: 0, background: 'transparent', font: 'inherit', color: 'inherit' }}
                  />
                ) : (
                  <span className="file-item-name">{doc.name.replace(/\.md$/, '')}</span>
                )}
                <button className="icon-btn" style={{ width: 22, height: 22 }}
                        onClick={(e) => { e.stopPropagation(); setMenuAnchor(e.currentTarget); setMenuDoc(doc); }}>
                  <Icon name="more" size={13} />
                </button>
              </div>
            ))}
            {filtered.length === 0 && (
              <div style={{ padding: '24px 12px', fontSize: 12, color: 'var(--fg-3)', textAlign: 'center' }}>
                {q ? t.no_matches : t.no_docs}
              </div>
            )}
          </div>
        </>
      )}

      {tab === 'outline' && (
        <div className="sidebar-content">
          {headings.length === 0 && (
            <div style={{ padding: '24px 12px', fontSize: 12, color: 'var(--fg-3)', textAlign: 'center' }}>
              {t.no_headings}
            </div>
          )}
          {headings.map((h, i) => (
            <div key={i}
                 className={`toc-item lvl-${h.level} ${h.id === activeHeading ? 'active' : ''}`}
                 onClick={() => onJumpHeading(h)}
                 title={h.text}>
              {h.text}
            </div>
          ))}
        </div>
      )}

      {menuAnchor && menuDoc && (
        <Menu anchor={menuAnchor} onClose={() => { setMenuAnchor(null); setMenuDoc(null); }}
              items={[
                { label: t.menu_rename, icon: 'rename', onClick: () => startRename(menuDoc) },
                { label: t.menu_duplicate, icon: 'duplicate', onClick: () => onDuplicate(menuDoc.id) },
                { divider: true },
                { label: t.menu_delete, icon: 'trash', onClick: () => onDelete(menuDoc.id) },
              ]} />
      )}
    </aside>
  );
}

// ── Status bar ──────────────────────────────────────────────────────────────
function StatusBar({ stats, saveState, lastSaved, mode, onMode, onFocus, t, lang }) {
  return (
    <div className="statusbar">
      <span className="sb-item">
        <span className={`sb-dot ${saveState === 'saving' ? 'saving' : ''}`} />
        {saveState === 'saving' ? t.saving : t.saved}
        {lastSaved && saveState === 'saved' && <span style={{ color: 'var(--fg-4)' }}>· {lastSaved}</span>}
      </span>
      <span className="sb-item">{t.words}: <strong style={{ color: 'var(--fg-2)' }}>{stats.words.toLocaleString(lang === 'zh' ? 'zh-CN' : 'en-US')}</strong></span>
      <span className="sb-item">{t.chars}: <strong style={{ color: 'var(--fg-2)' }}>{stats.chars.toLocaleString(lang === 'zh' ? 'zh-CN' : 'en-US')}</strong></span>
      <span className="sb-item">{t.reading_time}: <strong style={{ color: 'var(--fg-2)' }}>{stats.reading} {t.min}</strong></span>
      <span className="sb-spacer" />
      <button className="sb-btn" onClick={onFocus}>
        <Icon name="maximize" size={11} />{t.focus_mode}
      </button>
    </div>
  );
}

// ── PDF preview modal ───────────────────────────────────────────────────────
function PdfPreviewModal({ html, title, onClose, onPrint, t }) {
  // Auto-paginate by measuring content. For demo we show one long page that
  // visually mimics A4 and let the print dialog handle real pagination.
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal-header">
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <Icon name="pdf" size={16} />
            <div>
              <div className="modal-title">{t.pdf_title}</div>
              <div style={{ fontSize: 11, color: 'var(--fg-3)', marginTop: 2 }}>
                {title} · A4 · {t.pdf_subtitle}
              </div>
            </div>
          </div>
          <button className="icon-btn" onClick={onClose}><Icon name="x" /></button>
        </div>
        <div className="modal-body">
          <div className="pdf-page">
            <div className="prose" style={{ padding: 0, maxWidth: 'none' }} dangerouslySetInnerHTML={{ __html: html }} />
            <div className="pdf-page-num">— 1 —</div>
          </div>
        </div>
        <div className="modal-footer">
          <div style={{ fontSize: 11, color: 'var(--fg-3)' }}>{t.pdf_hint}</div>
          <div style={{ display: 'flex', gap: 8 }}>
            <button className="text-btn" onClick={onClose}>{t.cancel}</button>
            <button className="text-btn primary" onClick={onPrint}>
              <Icon name="download" />{t.pdf_download}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Onboarding empty state ──────────────────────────────────────────────────
function EmptyDoc({ onCreate, t }) {
  return (
    <div className="empty">
      <div>
        <h3 style={{ fontSize: 22 }}>{t.empty_title}</h3>
        <p>{t.empty_body}</p>
        <button className="text-btn primary" style={{ marginTop: 18 }} onClick={onCreate}>
          <Icon name="plus" />{t.new_doc}
        </button>
      </div>
    </div>
  );
}

Object.assign(window, {
  Icon, BrandMark, ModeToggle, Menu, Sidebar, StatusBar, PdfPreviewModal, EmptyDoc,
});
