/* ===== Add / Edit Section + Manage list ===== */

/* ---------- Add / Edit Section ---------- */
function AddSectionView({ nav, route, notify, refresh }) {
  const editing = !!route.editId;
  const existing = editing ? window.sectionById(route.editId) : null;
  const isBuiltinEdit = editing && window.SectionStore.isBuiltin(route.editId) && !window.SectionStore.isCustom(route.editId);
  // built-ins have no `raw` — derive their full source so the form can edit them
  const initialRaw = existing ? (existing.raw || window.buildSectionHTML(existing)) : '';

  const [name, setName] = useState(existing ? existing.name : '');
  const [catId, setCatId] = useState(existing ? existing.category : '');
  const [raw, setRaw] = useState(initialRaw);
  const [fileName, setFileName] = useState(existing && existing.fileName ? existing.fileName : '');
  const [thumb, setThumb] = useState(existing && existing.thumb ? existing.thumb : '');
  const [thumbOver, setThumbOver] = useState(false);
  const [mode, setMode] = useState(editing ? 'paste' : 'upload');
  const [genReact, setGenReact] = useState(existing ? existing.frameworks.includes('react') : true);
  const [pro, setPro] = useState(existing ? !!existing.pro : false);
  const [over, setOver] = useState(false);
  const [touched, setTouched] = useState(false);
  const prevFrameRef = useRef(null);

  const errors = {
    name: !name.trim() ? 'Give your section a name.' : '',
    cat: !catId ? 'Pick a category.' : '',
    raw: !raw.trim() ? 'Upload or paste the section HTML.' : ''
  };
  const valid = !errors.name && !errors.cat && !errors.raw;

  const readFile = (file) => {
    if (!file) return;
    if (!/\.(html?|txt)$/i.test(file.name) && file.type && !/html|text/.test(file.type)) {
      notify('Please choose an .html file', true); return;
    }
    const r = new FileReader();
    r.onload = () => { setRaw(String(r.result)); setFileName(file.name); if (!name.trim()) setName(file.name.replace(/\.[^.]+$/, '').replace(/[-_]/g, ' ').replace(/\b\w/g, c => c.toUpperCase())); };
    r.readAsText(file);
  };

  const onDrop = (e) => { e.preventDefault(); setOver(false); readFile(e.dataTransfer.files[0]); };

  // Read an image file, downscale to a card-sized thumbnail, store as a compact data URL
  const readThumb = (file) => {
    if (!file) return;
    if (!/^image\//.test(file.type) && !/\.(png|jpe?g|webp|gif|avif)$/i.test(file.name)) {
      notify('Please choose an image file (PNG, JPG, WebP…)', true); return;
    }
    const r = new FileReader();
    r.onload = () => {
      const img = new Image();
      img.onload = () => {
        const MAXW = 800;
        const scale = Math.min(1, MAXW / img.width);
        const w = Math.round(img.width * scale), h = Math.round(img.height * scale);
        const c = document.createElement('canvas'); c.width = w; c.height = h;
        c.getContext('2d').drawImage(img, 0, 0, w, h);
        let url;
        try { url = c.toDataURL('image/jpeg', 0.82); } catch (e) { url = String(r.result); }
        setThumb(url);
      };
      img.onerror = () => notify('Could not read that image', true);
      img.src = String(r.result);
    };
    r.readAsDataURL(file);
  };
  const onThumbDrop = (e) => { e.preventDefault(); setThumbOver(false); readThumb(e.dataTransfer.files[0]); };

  const previewSection = raw.trim() ? { id: 'preview-live', name: name || 'Preview', category: catId || 'headers', raw, height: 600 } : null;

  const save = () => {
    setTouched(true);
    if (!valid) { notify('Please complete the highlighted fields', true); return; }
    let height = 600;
    try {
      const doc = prevFrameRef.current && prevFrameRef.current.querySelector('iframe') && prevFrameRef.current.querySelector('iframe').contentDocument;
      if (doc) height = Math.max(doc.body.scrollHeight, 300);
    } catch (e) {}
    const sec = {
      id: editing ? existing.id : window.SectionStore.newId(),
      name: name.trim(),
      category: catId,
      tags: (existing && existing.tags ? existing.tags.filter(function(x){return x!=='custom';}) : []).concat([catId]),
      frameworks: ['html'].concat(genReact ? ['react'] : []),
      popularity: existing ? existing.popularity : 60,
      downloads: existing ? existing.downloads : 0,
      added: editing ? existing.added : new Date().toISOString().slice(0, 10),
      pro: pro,
      custom: isBuiltinEdit ? false : true,
      fileName: fileName || '',
      thumb: thumb || '',
      height: height,
      raw: raw
    };
    if (editing) window.SectionStore.update(sec); else window.SectionStore.add(sec);
    refresh();
    notify(editing ? (isBuiltinEdit ? 'Built-in section updated' : 'Section updated') : 'Section added to ' + window.catById(catId).label);
    nav({ view: 'section', sectionId: sec.id });
  };

  return (
    <div className="content-inner">
      <div className="form-wrap" style={{ margin: '0 auto' }}>
        <button className="btn btn-ghost btn-sm" style={{ marginBottom: 16 }} onClick={() => nav(editing ? { view: 'section', sectionId: existing.id } : { view: 'manage' })}>
          <Icon name="back" size={15} /> {editing ? 'Back to section' : 'My Sections'}
        </button>
        <div style={{ textAlign: 'center', marginBottom: 26 }}>
          <span className="eyebrow">{editing ? 'Edit' : 'Create'}</span>
          <h2 style={{ fontSize: 28, margin: '6px 0 4px', fontFamily: 'var(--font-display)' }}>
            {editing ? 'Edit section' : 'Add new section'}
          </h2>
          <p style={{ color: 'var(--text-2)', margin: '0 auto', maxWidth: '52ch' }}>
            {isBuiltinEdit
              ? 'Edit this section’s name, category or code. Your changes are saved as an override you can restore anytime.'
              : 'Name it, choose a category and drop in your HTML — we\'ll organize it and make it available everywhere.'}
          </p>
        </div>

        <div className="form-card">
          <div className="field">
            <label>Section name <span className="req">*</span></label>
            <input className={'t-input' + (touched && errors.name ? ' err' : '')} value={name}
              onChange={e => setName(e.target.value)} placeholder="e.g. Glass Pricing Table" />
            {touched && errors.name && <p className="field-err">{errors.name}</p>}
          </div>

          <div className="field">
            <label>Category <span className="req">*</span></label>
            <div className="select-wrap">
              <select className={'t-input' + (touched && errors.cat ? ' err' : '')} value={catId}
                onChange={e => setCatId(e.target.value)}>
                <option value="">Select a category…</option>
                {window.CATEGORIES.map(c =>
                  <option key={c.id} value={c.id}>{c.label}</option>)}
              </select>
              <span className="select-chev"><Icon name="arrow" size={16} /></span>
            </div>
            {touched && errors.cat && <p className="field-err">{errors.cat}</p>}
          </div>

          <div className="field">
            <label>Section code <span className="req">*</span></label>
            <div className="src-tabs">
              <button className={mode === 'upload' ? 'active' : ''} onClick={() => setMode('upload')}><Icon name="upload" size={15} /> Upload file</button>
              <button className={mode === 'paste' ? 'active' : ''} onClick={() => setMode('paste')}><Icon name="code" size={15} /> Paste code</button>
            </div>

            {mode === 'upload' && !raw &&
              <div className={'drop' + (over ? ' over' : '')}
                onDragOver={e => { e.preventDefault(); setOver(true); }}
                onDragLeave={() => setOver(false)} onDrop={onDrop}>
                <input type="file" accept=".html,.htm,text/html" onChange={e => readFile(e.target.files[0])} />
                <div className="drop-ico"><Icon name="upload" size={24} /></div>
                <h4>Drop your HTML file here</h4>
                <p>or <b>browse</b> — .html files up to a few MB</p>
              </div>}

            {mode === 'upload' && raw &&
              <div className="file-pill">
                <span className="fp-ico"><Icon name="file" size={19} /></span>
                <div className="fp-meta">
                  <b>{fileName || 'section.html'}</b>
                  <span>{(new Blob([raw]).size / 1024).toFixed(1)} KB · ready</span>
                </div>
                <button className="fp-rm" onClick={() => { setRaw(''); setFileName(''); }} title="Remove"><Icon name="x" size={16} /></button>
              </div>}

            {mode === 'paste' &&
              <textarea className={'t-input' + (touched && errors.raw ? ' err' : '')} value={raw}
                onChange={e => setRaw(e.target.value)}
                placeholder={'<section class="my-section">\n  <h1>Paste your markup here…</h1>\n</section>'} />}

            {touched && errors.raw && <p className="field-err">{errors.raw}</p>}
            <p className="hint">Paste a full HTML document or just the section markup (with a &lt;style&gt; block). We auto-wrap fragments and {genReact ? 'generate a React component too.' : 'export clean HTML.'}</p>
          </div>

          <div className="field">
            <label>Thumbnail image</label>
            {!thumb &&
              <div className={'drop drop-thumb' + (thumbOver ? ' over' : '')}
                onDragOver={e => { e.preventDefault(); setThumbOver(true); }}
                onDragLeave={() => setThumbOver(false)} onDrop={onThumbDrop}>
                <input type="file" accept="image/*" onChange={e => readThumb(e.target.files[0])} />
                <div className="drop-ico"><Icon name="upload" size={24} /></div>
                <h4>Upload a thumbnail</h4>
                <p>or <b>browse</b> — PNG, JPG or WebP, shown on cards everywhere</p>
              </div>}
            {thumb &&
              <div className="thumb-edit">
                <div className="thumb-edit-prev"><img src={thumb} alt="Thumbnail preview" /></div>
                <div className="thumb-edit-meta">
                  <b>Thumbnail ready</b>
                  <span>This image represents the section across cards, the library and My Sections.</span>
                  <div className="thumb-edit-actions">
                    <label className="btn btn-sm">
                      <Icon name="upload" size={14} /> Replace
                      <input type="file" accept="image/*" style={{ display: 'none' }} onChange={e => readThumb(e.target.files[0])} />
                    </label>
                    <button className="btn btn-sm" onClick={() => setThumb('')}><Icon name="x" size={14} /> Remove</button>
                  </div>
                </div>
              </div>}
            <p className="hint">Optional. If you don’t upload one, a live render of your section is used instead.</p>
          </div>

          {previewSection &&
            <div className="field">
              <label>Live preview</label>
              <div className="form-prev">
                <div className="form-prev-bar"><Icon name="eye" size={14} /> {name || 'Untitled section'}{catId ? ' · ' + window.catById(catId).label : ''}
                  <span style={{ flex: 1 }} />
                  <button className="btn btn-sm" style={{ height: 28 }} onClick={() => window.openFullPreview(previewSection)} title="Open full view in new tab">
                    <Icon name="external" size={14} /> Full view
                  </button>
                </div>
                <div className="form-prev-stage" ref={prevFrameRef}>
                  <ScaledFrame key={'p' + raw.length} section={previewSection} mode="fit" logicalWidth={1280} maxScale={1} />
                </div>
              </div>
            </div>}

          <div className="field">
            <label>Options</label>
            <div className="opt-row">
              <div className={'opt-toggle' + (genReact ? ' on' : '')} onClick={() => setGenReact(v => !v)}>
                <span className="opt-box"><Icon name="check" size={13} /></span>
                <div><div className="opt-t">Generate React component</div><div className="opt-d">Adds a .jsx export tab</div></div>
              </div>
              <div className={'opt-toggle' + (pro ? ' on' : '')} onClick={() => setPro(v => !v)}>
                <span className="opt-box"><Icon name="check" size={13} /></span>
                <div><div className="opt-t">Mark as Pro</div><div className="opt-d">Shows a Pro badge</div></div>
              </div>
            </div>
          </div>
        </div>

        <div className="form-actions" style={{ justifyContent: 'center' }}>
          <button className="btn btn-primary" onClick={save} disabled={!valid}
            style={!valid ? { opacity: .55, cursor: 'not-allowed' } : {}}>
            <Icon name="save" size={16} /> {editing ? 'Save changes' : 'Save section'}
          </button>
          <button className="btn" onClick={() => nav(editing ? { view: 'section', sectionId: existing.id } : { view: 'manage' })}>Cancel</button>
        </div>
        {!valid && <p style={{ textAlign: 'center', fontSize: 12.5, color: 'var(--text-3)', margin: '12px 0 0' }}>Name, category and code are required</p>}
      </div>
    </div>
  );
}

/* ---------- Manage list ---------- */
function ManageView({ nav, notify, refresh, version }) {
  const list = window.SectionStore.list();
  const [confirmId, setConfirmId] = useState(null);

  const doCopy = (s) => {
    window.copyToClipboard(window.buildSectionHTML(s)).then(ok => notify(ok ? 'Full HTML copied to clipboard' : 'Copy blocked — open Preview to copy', !ok));
  };
  const doDownload = (s) => {
    const blob = new Blob([window.buildSectionHTML(s)], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a'); a.href = url; a.download = s.id + '.html'; a.click();
    URL.revokeObjectURL(url); notify('Downloaded ' + s.id + '.html');
  };
  const doDelete = (s) => { window.SectionStore.remove(s.id); refresh(); setConfirmId(null); notify('Section deleted'); };
  const modCount = window.SectionStore.modifiedCount();

  return (
    <div className="content-inner">
      <div className="h-row" style={{ marginBottom: 20 }}>
        <div>
          <span className="eyebrow">Manage</span>
          <h2 style={{ fontSize: 28, marginTop: 6 }}>My Sections</h2>
          <p>{list.length} custom {list.length === 1 ? 'template' : 'templates'} · {window.storageLabel()}</p>
        </div>
        <button className="btn btn-primary" onClick={() => nav({ view: 'add' })}><Icon name="plus" size={16} /> Add new section</button>
      </div>

      {modCount > 0 &&
        <div className="set-card" style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '14px 18px', marginBottom: 18 }}>
          <span className="cat-tile-ico" style={{ width: 38, height: 38, borderRadius: 10, background: 'color-mix(in srgb,#f59e0b 14%,var(--surface))', color: '#d97706', flex: 'none' }}><Icon name="edit" size={18} /></span>
          <div style={{ flex: 1 }}>
            <b style={{ fontSize: 14 }}>{modCount} built-in {modCount === 1 ? 'section has' : 'sections have'} been edited or removed</b>
            <div style={{ fontSize: 12.5, color: 'var(--text-3)' }}>Your changes are saved as overrides. You can put everything back to the original library anytime.</div>
          </div>
          <button className="btn btn-sm" onClick={() => { window.SectionStore.restoreAll(); refresh(); notify('All built-in sections restored'); }}>
            <Icon name="back" size={15} /> Restore defaults
          </button>
        </div>}

      {list.length === 0
        ? <div className="empty">
            <Icon name="folder" size={46} />
            <h3>No custom sections yet</h3>
            <p>Add your first section — name it, pick a category and upload the HTML.</p>
            <button className="btn btn-primary" style={{ marginTop: 18 }} onClick={() => nav({ view: 'add' })}>
              <Icon name="plus" size={16} /> Add new section
            </button>
          </div>
        : <div className="mlist">
            {list.map(s => {
              const cat = window.catById(s.category);
              return (
                <div className="mrow" key={s.id}>
                  <div className="mthumb">
                    <ScaledFrame section={s} mode="crop" logicalWidth={1280} />
                  </div>
                  <div className="mmeta">
                    <h3>{s.name} <span className="tag-custom">Custom</span>{s.pro && <span className="badge pro"><Icon name="star" size={11} /> Pro</span>}</h3>
                    <div className="mrow-sub">
                      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}><CatDot cat={cat} /> {cat.label}</span>
                      <span className="dotsep">·</span>
                      <span>{s.frameworks.map(f => f.toUpperCase()).join(' · ')}</span>
                      <span className="dotsep">·</span>
                      <span>Added {window.timeAgo(s.added)}</span>
                    </div>
                  </div>
                  <div className="mactions">
                    {confirmId === s.id
                      ? <div className="confirm-row">
                          <span>Delete?</span>
                          <button className="act-btn danger" onClick={() => doDelete(s)}><Icon name="trash" size={15} /> Yes, delete</button>
                          <button className="act-btn" onClick={() => setConfirmId(null)}>Cancel</button>
                        </div>
                      : <>
                          <button className="act-btn" onClick={() => nav({ view: 'section', sectionId: s.id })}><Icon name="eye" size={15} /> Preview</button>
                          <button className="act-btn icon-only" title="Copy HTML" onClick={() => doCopy(s)}><Icon name="copy" size={15} /></button>
                          <button className="act-btn icon-only" title="Download" onClick={() => doDownload(s)}><Icon name="download" size={15} /></button>
                          <button className="act-btn icon-only" title="Edit" onClick={() => nav({ view: 'add', editId: s.id })}><Icon name="edit" size={15} /></button>
                          <button className="act-btn icon-only danger" title="Delete" onClick={() => setConfirmId(s.id)}><Icon name="trash" size={15} /></button>
                        </>}
                  </div>
                </div>
              );
            })}
          </div>}
    </div>
  );
}

/* ---------- Toast ---------- */
function Toast({ msg, error }) {
  if (!msg) return null;
  return (
    <div className="toast">
      <span className="t-ico" style={error ? { background: '#ef4444' } : {}}><Icon name={error ? 'x' : 'check'} size={14} /></span>
      {msg}
    </div>
  );
}

Object.assign(window, { AddSectionView, ManageView, Toast });
