// ─────────────────────────────────────────────────────────────────────
// videos-edit.jsx
// ─────────────────────────────────────────────────────────────────────
// Adds three things to the Videos surface area:
//
//   1. <GlobalVideoDrawer/>   — listens for `astro-open-video` and shows
//      an editable side drawer with all video metadata fields.
//   2. <GlobalAddVideoModal/> — listens for `astro-add-video` and shows
//      a 3-step new-video flow (recording link → details → confirm).
//   3. window.RS.upsertVideo(payload) helper that persists edits / inserts
//      back into window.RS.videos for the current session.
//
// Convention parity with the codebase:
//   • Backdrop overlay + right-side drawer w/ close button
//   • Global event listener pattern (see globals.jsx)
//   • All edits are session-only; we don't fake-write to disk
//   • Existing rich data is preserved via spread, even fields we don't surface
//
// Wired up:
//   • VideosView card click       → astro-open-video {id}
//   • "New video" button          → astro-add-video
//   • Recording detail panel      → "Linked videos" block (videos-on-recording.jsx)
// ─────────────────────────────────────────────────────────────────────

(function () {
  const { useState, useEffect, useMemo } = React;

  // ── Persistence helper ─────────────────────────────────────────────
  // Mutates window.RS.videos in place and broadcasts a change event so
  // VideosView (and anything else listening) re-renders.
  function upsertVideo(next) {
    if (!window.RS) window.RS = {};
    if (!Array.isArray(window.RS.videos)) window.RS.videos = [];
    const arr = window.RS.videos;
    const idx = arr.findIndex((v) => v['Video ID'] === next['Video ID']);
    if (idx >= 0) arr[idx] = { ...arr[idx], ...next };
    else arr.unshift(next);
    window.dispatchEvent(new CustomEvent('astro-videos-changed', { detail: { id: next['Video ID'] } }));
    window.dispatchEvent(new CustomEvent('astro-toast', { detail: { msg: idx >= 0 ? `Video ${next['Video ID']} updated` : `Video ${next['Video ID']} created`, tone: 'ok' } }));
    return arr[idx >= 0 ? idx : 0];
  }
  if (!window.RS) window.RS = {};
  window.RS.upsertVideo = upsertVideo;

  // ── Generate next free RVID ────────────────────────────────────────
  function nextVideoId() {
    const arr = (window.RS && window.RS.videos) || [];
    let max = 10000;
    for (const v of arr) {
      const m = (v['Video ID'] || '').match(/^RVID(\d+)$/);
      if (m) max = Math.max(max, parseInt(m[1], 10));
    }
    return 'RVID' + (max + 1);
  }

  // ── YouTube ID extractor (mirrors VideosView) ──────────────────────
  function ytId(url) {
    if (!url) return null;
    const m1 = url.match(/youtu\.be\/([\w-]+)/);
    const m2 = url.match(/[?&]v=([\w-]+)/);
    return m1 ? m1[1] : (m2 ? m2[1] : null);
  }
  function ytThumb(url) {
    const id = ytId(url);
    return id ? `https://i.ytimg.com/vi/${id}/hqdefault.jpg` : null;
  }

  // ── Field — small reusable labelled input ──────────────────────────
  function Field({ label, value, onChange, mono = false, placeholder = '', hint = '', type = 'text', readOnly = false }) {
    return (
      <label style={{ display: 'block', marginBottom: 14 }}>
        <div className="ff-mono upper" style={{ fontSize: 9, letterSpacing: '.12em', color: 'var(--ink-3)', fontWeight: 600, marginBottom: 5 }}>{label}</div>
        <input
          type={type}
          value={value || ''}
          onChange={(e) => onChange(e.target.value)}
          placeholder={placeholder}
          readOnly={readOnly}
          className={mono ? 'ff-mono' : ''}
          style={{
            width: '100%', padding: '8px 10px',
            border: '1px solid var(--rule)',
            background: readOnly ? 'var(--bg-2)' : 'var(--bg)',
            color: 'var(--ink)', fontSize: mono ? 12 : 13,
            outline: 'none',
          }}
          onFocus={(e) => e.target.style.borderColor = 'var(--ink)'}
          onBlur={(e) => e.target.style.borderColor = 'var(--rule)'}
        />
        {hint && (<div className="ff-mono" style={{ fontSize: 10, color: 'var(--ink-4)', marginTop: 4 }}>{hint}</div>)}
      </label>
    );
  }

  // ── Toggle for Yes/No fields ───────────────────────────────────────
  function YesNo({ label, value, onChange }) {
    const yes = (value || '').toLowerCase().startsWith('y');
    return (
      <div style={{ marginBottom: 14 }}>
        <div className="ff-mono upper" style={{ fontSize: 9, letterSpacing: '.12em', color: 'var(--ink-3)', fontWeight: 600, marginBottom: 5 }}>{label}</div>
        <div style={{ display: 'flex', gap: 0 }}>
          {['Yes', 'No'].map((opt) => {
            const active = (opt === 'Yes') === yes;
            return (
              <button key={opt} onClick={() => onChange(opt)} className="ff-mono upper"
                style={{
                  padding: '8px 14px', fontSize: 11, letterSpacing: '.08em', fontWeight: 600,
                  background: active ? 'var(--ink)' : 'transparent',
                  color: active ? 'var(--bg)' : 'var(--ink-2)',
                  border: '1px solid var(--rule)',
                  cursor: 'pointer',
                }}>{opt}</button>
            );
          })}
        </div>
      </div>
    );
  }

  // ── Recording typeahead — small inline picker over RECORDINGS ──────
  function RecordingPicker({ value, onChange }) {
    const [q, setQ] = useState(value || '');
    const [open, setOpen] = useState(false);
    useEffect(() => { setQ(value || ''); }, [value]);
    const hits = useMemo(() => {
      const all = (window.RECORDINGS || []);
      const qq = (q || '').trim().toLowerCase();
      if (!qq) return all.slice(0, 8);
      return all.filter((r) => (r.title || '').toLowerCase().includes(qq) || (r.isrc || '').toLowerCase().includes(qq)).slice(0, 8);
    }, [q]);
    return (
      <div style={{ marginBottom: 14, position: 'relative' }}>
        <div className="ff-mono upper" style={{ fontSize: 9, letterSpacing: '.12em', color: 'var(--ink-3)', fontWeight: 600, marginBottom: 5 }}>LINKED RECORDING</div>
        <input
          value={q}
          onChange={(e) => { setQ(e.target.value); setOpen(true); onChange(e.target.value); }}
          onFocus={() => setOpen(true)}
          onBlur={() => setTimeout(() => setOpen(false), 200)}
          placeholder="Search recording title or ISRC..."
          style={{ width: '100%', padding: '8px 10px', border: '1px solid var(--rule)', background: 'var(--bg)', color: 'var(--ink)', fontSize: 13, outline: 'none' }}
        />
        {open && hits.length > 0 && (
          <div style={{
            position: 'absolute', left: 0, right: 0, top: '100%', zIndex: 10,
            background: 'var(--bg)', border: '1px solid var(--ink)',
            boxShadow: '4px 4px 0 rgba(0,0,0,.18)', maxHeight: 280, overflowY: 'auto',
          }}>
            {hits.map((r) => (
              <button key={r.id} onMouseDown={(e) => { e.preventDefault(); onChange(r.title); setQ(r.title); setOpen(false); }}
                style={{ display: 'block', width: '100%', textAlign: 'left', padding: '8px 12px', background: 'transparent', border: 0, cursor: 'pointer', borderBottom: '1px solid var(--rule-soft)' }}
                onMouseEnter={(e) => e.currentTarget.style.background = 'var(--bg-2)'}
                onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
                <div style={{ fontSize: 13, fontWeight: 500 }}>{r.title}</div>
                <div className="ff-mono" style={{ fontSize: 10, color: 'var(--ink-3)' }}>{r.isrc || '—'} · {r.artist || '—'}</div>
              </button>
            ))}
          </div>
        )}
      </div>
    );
  }

  // ── Backdrop + drawer shell ────────────────────────────────────────
  function DrawerShell({ children, onClose, width = 'min(560px,92vw)' }) {
    return (
      <>
        <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.34)', zIndex: 60 }} />
        <aside style={{
          position: 'fixed', top: 0, right: 0, bottom: 0, width,
          background: 'var(--bg)', borderLeft: '1px solid var(--rule)',
          zIndex: 61, overflowY: 'auto', boxShadow: '-20px 0 40px rgba(0,0,0,.18)',
        }}>{children}</aside>
      </>
    );
  }

  // ─────────────────────────────────────────────────────────────────
  // VIDEO DETAIL DRAWER
  // ─────────────────────────────────────────────────────────────────
  function VideoDrawer({ video, onClose }) {
    // Local working copy — only persisted on Save.
    const [draft, setDraft] = useState({ ...video });
    useEffect(() => { setDraft({ ...video }); }, [video]);
    const setF = (k) => (v) => setDraft((d) => ({ ...d, [k]: v }));
    const dirty = useMemo(() => {
      return Object.keys(draft).some((k) => (draft[k] || '') !== (video[k] || ''));
    }, [draft, video]);

    const save = () => {
      upsertVideo(draft);
      onClose();
    };

    const thumb = ytThumb(draft['YouTube Link']);
    const claimed = !!draft['Content ID Claimants'];

    return (
      <DrawerShell onClose={onClose}>
        {/* Hero */}
        <div style={{ position: 'relative', padding: 0 }}>
          <div style={{
            aspectRatio: '16 / 9', position: 'relative', overflow: 'hidden',
            background: thumb
              ? `center / cover no-repeat url("${thumb}")`
              : 'linear-gradient(135deg, var(--ink-5) 0%, var(--ink-4) 100%)',
            borderBottom: '1px solid var(--rule)',
          }}>
            <button onClick={onClose} aria-label="Close" style={{
              position: 'absolute', top: 12, right: 12, width: 30, height: 30,
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              background: 'rgba(0,0,0,.45)', color: 'white', border: 0, cursor: 'pointer', backdropFilter: 'blur(4px)',
            }}><span style={{ fontSize: 18, lineHeight: 1 }}>×</span></button>
            {!thumb && (
              <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <svg width="56" height="56" viewBox="0 0 24 24" fill="none" stroke="var(--bg)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" style={{ opacity: .55 }}>
                  <polygon points="23 7 16 12 23 17 23 7" /><rect x="1" y="5" width="15" height="14" rx="2" ry="2" />
                </svg>
              </div>
            )}
            {/* Play overlay if YT thumb exists */}
            {thumb && draft['YouTube Link'] && (
              <a href={draft['YouTube Link']} target="_blank" rel="noopener"
                style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(0,0,0,.18)', textDecoration: 'none' }}>
                <div style={{ width: 56, height: 56, borderRadius: '50%', background: 'rgba(0,0,0,.7)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <svg width="20" height="20" viewBox="0 0 24 24" fill="white"><polygon points="6 4 20 12 6 20 6 4" /></svg>
                </div>
              </a>
            )}
            {/* Top-left ID stamp */}
            <span className="ff-mono" style={{
              position: 'absolute', bottom: 12, left: 12, fontSize: 11, fontWeight: 600,
              padding: '4px 8px', background: 'rgba(0,0,0,.65)', color: 'white', letterSpacing: '.04em',
            }}>VIDEO · {draft['Video ID']}</span>
          </div>

          {/* Title bar */}
          <div style={{ padding: '20px 28px 16px', borderBottom: '1px solid var(--rule)' }}>
            <div className="ff-mono upper" style={{ fontSize: 9, letterSpacing: '.14em', color: 'var(--ink-3)', marginBottom: 8 }}>
              EDITING · MUSIC VIDEO · {draft['Recording'] || 'unlinked'}
            </div>
            <div className="ff-display" style={{ fontSize: 26, fontWeight: 700, letterSpacing: '-0.02em', lineHeight: 1.1 }}>
              {draft['Video Name'] || <span style={{ color: 'var(--ink-4)' }}>Untitled</span>}
            </div>
            <div style={{ display: 'flex', gap: 6, marginTop: 12, flexWrap: 'wrap' }}>
              {claimed && (<span className="ff-mono upper" style={{ fontSize: 9, letterSpacing: '.08em', fontWeight: 700, padding: '3px 7px', background: 'var(--ok, #1f7a3a)', color: 'white' }}>CONTENT ID CLAIMED</span>)}
              {(draft['Controlled'] || '').toLowerCase().startsWith('y') && (<span className="ff-mono upper" style={{ fontSize: 9, letterSpacing: '.08em', fontWeight: 700, padding: '3px 7px', background: 'var(--ink)', color: 'var(--bg)' }}>CONTROLLED</span>)}
              {draft['ISRC (Video)'] && (<span className="ff-mono" style={{ fontSize: 10, padding: '3px 7px', border: '1px solid var(--rule)', color: 'var(--ink-2)' }}>{draft['ISRC (Video)']}</span>)}
            </div>
          </div>
        </div>

        {/* Form */}
        <div style={{ padding: '20px 28px 100px' }}>
          <div className="ff-mono upper" style={{ fontSize: 10, fontWeight: 700, letterSpacing: '.12em', color: 'var(--ink-2)', marginBottom: 12, paddingBottom: 6, borderBottom: '1px solid var(--rule)' }}>
            01 · IDENTITY
          </div>
          <Field label="VIDEO TITLE" value={draft['Video Name']} onChange={setF('Video Name')} placeholder="Music video title..." />
          <RecordingPicker value={draft['Recording']} onChange={setF('Recording')} />
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
            <Field label="VIDEO ISRC" value={draft['ISRC (Video)']} onChange={setF('ISRC (Video)')} mono placeholder="USXXX0000000" hint="ISO-3901" />
            <Field label="VIDEO UPC" value={draft['UPC (Video)']} onChange={setF('UPC (Video)')} mono placeholder="000000000000" />
          </div>

          <div className="ff-mono upper" style={{ fontSize: 10, fontWeight: 700, letterSpacing: '.12em', color: 'var(--ink-2)', marginTop: 22, marginBottom: 12, paddingBottom: 6, borderBottom: '1px solid var(--rule)' }}>
            02 · RIGHTS + CONTROL
          </div>
          <YesNo label="CONTROLLED?" value={draft['Controlled']} onChange={setF('Controlled')} />
          <Field label="CONTENT ID CLAIMANT(S)" value={draft['Content ID Claimants']} onChange={setF('Content ID Claimants')} placeholder="Symphonic, AdRev, etc." hint="Comma-separated list of asset claimants" />
          <Field label="VIDEO TERRITORIES" value={draft['Video Territories']} onChange={setF('Video Territories')} mono placeholder="RVIDxxxxx-2WL-I" hint="CWR-style territory code (2WL = world, I = include)" />
          <Field label="VIDEO RELEASE DATE" value={draft['Video Release Date']} onChange={setF('Video Release Date')} mono type="date" />

          <div className="ff-mono upper" style={{ fontSize: 10, fontWeight: 700, letterSpacing: '.12em', color: 'var(--ink-2)', marginTop: 22, marginBottom: 12, paddingBottom: 6, borderBottom: '1px solid var(--rule)' }}>
            03 · DELIVERY LINKS
          </div>
          <Field label="YOUTUBE LINK" value={draft['YouTube Link']} onChange={setF('YouTube Link')} mono placeholder="https://youtu.be/..." hint="Watch URL — thumbnail auto-fetches from YouTube" />
          <Field label="YT AUTO-GEN AUDIO TRACK" value={draft['Youtube Auto-Generated Audio Track']} onChange={setF('Youtube Auto-Generated Audio Track')} mono placeholder="https://youtu.be/..." hint="Topic / auto-track URL if Content ID generated one" />
          <Field label="FACEBOOK VIDEO LINK" value={draft['FB Video Link']} onChange={setF('FB Video Link')} mono placeholder="https://fb.watch/..." />
          <Field label="VIDEO THUMBNAIL URL" value={draft['Video Thumbnail']} onChange={setF('Video Thumbnail')} mono placeholder="https://..." />
          <Field label="CLOSED CAPTION URL" value={draft['Closed Caption']} onChange={setF('Closed Caption')} mono placeholder="https://... (.vtt or .srt)" />
        </div>

        {/* Sticky footer */}
        <div style={{
          position: 'sticky', bottom: 0, left: 0, right: 0, zIndex: 1,
          background: 'var(--bg)', borderTop: '1px solid var(--rule)',
          padding: '14px 28px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12,
        }}>
          <div style={{display:'flex',alignItems:'center',gap:12}}>
            <span className="ff-mono upper" style={{ fontSize: 10, color: dirty ? 'var(--accent, #d4a02a)' : 'var(--ink-4)', letterSpacing: '.1em' }}>
              {dirty ? 'UNSAVED CHANGES' : 'NO CHANGES'}
            </span>
            {window.DetailDelete && (
              <window.DetailDelete kind="video" record={{ id: draft['Video ID'], ...draft }} title={draft['Video Title'] || draft['Video Name'] || draft['Video ID']} subtitle={`Video · ${draft['Video Type'] || ''}`} onDeleted={() => onClose && onClose()} variant="ghost" label="Delete" />
            )}
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            <button onClick={onClose} className="ff-mono upper"
              style={{ padding: '9px 16px', fontSize: 11, letterSpacing: '.08em', fontWeight: 600, background: 'transparent', color: 'var(--ink-2)', border: '1px solid var(--rule)', cursor: 'pointer' }}>Cancel</button>
            <button onClick={save} disabled={!dirty} className="ff-mono upper"
              style={{ padding: '9px 18px', fontSize: 11, letterSpacing: '.08em', fontWeight: 700, background: dirty ? 'var(--ink)' : 'var(--ink-4)', color: 'var(--bg)', border: 0, cursor: dirty ? 'pointer' : 'not-allowed' }}>Save changes</button>
          </div>
        </div>
      </DrawerShell>
    );
  }

  function GlobalVideoDrawer() {
    const [video, setVideo] = useState(null);
    useEffect(() => {
      const open = (e) => {
        const id = e.detail && e.detail.id;
        if (!id) return;
        const v = ((window.RS && window.RS.videos) || []).find((x) => x['Video ID'] === id);
        if (v) setVideo(v);
      };
      window.addEventListener('astro-open-video', open);
      window.addEventListener('astro-videos-changed', () => {
        // If our open video was just upserted, refresh from store.
        if (video) {
          const fresh = ((window.RS && window.RS.videos) || []).find((x) => x['Video ID'] === video['Video ID']);
          if (fresh) setVideo(fresh);
        }
      });
      return () => window.removeEventListener('astro-open-video', open);
    }, [video]);
    if (!video) return null;
    return <VideoDrawer video={video} onClose={() => setVideo(null)} />;
  }

  // ─────────────────────────────────────────────────────────────────
  // ADD VIDEO MODAL — 3-step flow
  // ─────────────────────────────────────────────────────────────────
  function AddVideoModal() {
    const [open, setOpen] = useState(null); // null | { recordingTitle?, onCreated? }
    const [step, setStep] = useState('link'); // link → details → confirm
    const [draft, setDraft] = useState(null);

    useEffect(() => {
      const onOpen = (e) => {
        const detail = (e && e.detail) || {};
        setOpen(detail);
        setStep('link');
        setDraft({
          'Video ID': nextVideoId(),
          'Video Name': '',
          'Recording': detail.recordingTitle || '',
          'ISRC (Video)': '',
          'UPC (Video)': '',
          'Controlled': 'Yes',
          'Video Thumbnail': '',
          'Video Release Date': '',
          'Video Territories': '',
          'FB Video Link': '',
          'YouTube Link': '',
          'Youtube Auto-Generated Audio Track': '',
          'Closed Caption': '',
          'Content ID Claimants': '',
        });
      };
      window.addEventListener('astro-add-video', onOpen);
      return () => window.removeEventListener('astro-add-video', onOpen);
    }, []);

    if (!open || !draft) return null;
    const setF = (k) => (v) => setDraft((d) => ({ ...d, [k]: v }));

    const close = () => { setOpen(null); setDraft(null); setStep('link'); };
    const save = () => {
      // Auto-fill Video Name from recording if blank
      const final = { ...draft };
      if (!final['Video Name'] && final['Recording']) final['Video Name'] = final['Recording'];
      // Auto-derive territory code if blank
      if (!final['Video Territories']) final['Video Territories'] = `${final['Video ID']}-2WL-I`;
      const saved = upsertVideo(final);
      if (open && typeof open.onCreated === 'function') {
        try { open.onCreated(saved); } catch (e) { /* noop */ }
      }
      close();
    };

    const stepNum = step === 'link' ? 1 : step === 'details' ? 2 : 3;

    return (
      <>
        <div onClick={close} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.45)', zIndex: 70 }} />
        <div role="dialog" aria-modal="true" style={{
          position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%,-50%)',
          width: 'min(640px, 92vw)', maxHeight: '88vh',
          background: 'var(--bg)', border: '1px solid var(--ink)',
          boxShadow: '8px 8px 0 rgba(0,0,0,.18)', zIndex: 71, display: 'flex', flexDirection: 'column',
        }}>
          {/* Header */}
          <div style={{ padding: '18px 24px', borderBottom: '1px solid var(--rule)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <div>
              <div className="ff-mono upper" style={{ fontSize: 9, letterSpacing: '.14em', color: 'var(--ink-3)', marginBottom: 4 }}>NEW MUSIC VIDEO · {draft['Video ID']}</div>
              <div className="ff-display" style={{ fontSize: 22, fontWeight: 700, letterSpacing: '-0.02em' }}>
                {step === 'link' ? 'Link to a recording' : step === 'details' ? 'Video metadata' : 'Confirm + create'}
              </div>
            </div>
            <button onClick={close} aria-label="Close" style={{ width: 30, height: 30, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', background: 'transparent', border: '1px solid var(--rule)', cursor: 'pointer' }}><span style={{ fontSize: 18 }}>×</span></button>
          </div>

          {/* Step bar */}
          <div style={{ display: 'flex', borderBottom: '1px solid var(--rule)' }}>
            {['LINK', 'DETAILS', 'CONFIRM'].map((s, i) => {
              const active = (i + 1) === stepNum;
              const done = (i + 1) < stepNum;
              return (
                <div key={s} style={{
                  flex: 1, padding: '10px 16px', textAlign: 'center',
                  background: active ? 'var(--ink)' : done ? 'var(--bg-2)' : 'transparent',
                  color: active ? 'var(--bg)' : done ? 'var(--ink-2)' : 'var(--ink-4)',
                  borderRight: i < 2 ? '1px solid var(--rule)' : '',
                  fontWeight: 600,
                }} className="ff-mono upper">
                  <span style={{ fontSize: 9, letterSpacing: '.12em' }}>0{i + 1} · {s}</span>
                </div>
              );
            })}
          </div>

          {/* Body */}
          <div style={{ padding: '22px 24px', overflowY: 'auto', flex: 1 }}>
            {step === 'link' && (
              <>
                <p style={{ fontSize: 13, color: 'var(--ink-2)', marginBottom: 16, lineHeight: 1.5 }}>
                  A music video points at one Recording in your catalog. Pick the recording this video accompanies — the Work it derives from will be inferred via the recording's Work link.
                </p>
                <RecordingPicker value={draft['Recording']} onChange={setF('Recording')} />
                <Field label="VIDEO TITLE" value={draft['Video Name']} onChange={setF('Video Name')} placeholder={draft['Recording'] ? `(defaults to: ${draft['Recording']})` : 'Music video title'} hint="Leave blank to inherit from the recording title" />
              </>
            )}
            {step === 'details' && (
              <>
                <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                  <Field label="VIDEO ISRC" value={draft['ISRC (Video)']} onChange={setF('ISRC (Video)')} mono placeholder="USXXX0000000" />
                  <Field label="VIDEO UPC" value={draft['UPC (Video)']} onChange={setF('UPC (Video)')} mono placeholder="000000000000" />
                </div>
                <YesNo label="CONTROLLED?" value={draft['Controlled']} onChange={setF('Controlled')} />
                <Field label="CONTENT ID CLAIMANT(S)" value={draft['Content ID Claimants']} onChange={setF('Content ID Claimants')} placeholder="Symphonic, AdRev, etc." />
                <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                  <Field label="VIDEO RELEASE DATE" value={draft['Video Release Date']} onChange={setF('Video Release Date')} mono type="date" />
                  <Field label="TERRITORIES" value={draft['Video Territories']} onChange={setF('Video Territories')} mono hint="auto-fills if blank" />
                </div>
                <Field label="YOUTUBE LINK" value={draft['YouTube Link']} onChange={setF('YouTube Link')} mono placeholder="https://youtu.be/..." />
                <Field label="FACEBOOK VIDEO LINK" value={draft['FB Video Link']} onChange={setF('FB Video Link')} mono placeholder="https://fb.watch/..." />
              </>
            )}
            {step === 'confirm' && (
              <>
                <div style={{ background: 'var(--bg-2)', padding: 16, marginBottom: 16, border: '1px solid var(--rule)' }}>
                  <div className="ff-mono upper" style={{ fontSize: 10, letterSpacing: '.12em', color: 'var(--ink-3)', marginBottom: 12 }}>SUMMARY</div>
                  {[
                    ['ID',         draft['Video ID']],
                    ['Title',      draft['Video Name'] || draft['Recording'] || '(untitled)'],
                    ['Recording',  draft['Recording'] || '(unlinked)'],
                    ['ISRC',       draft['ISRC (Video)'] || '—'],
                    ['Released',   draft['Video Release Date'] || '—'],
                    ['Controlled', draft['Controlled'] || '—'],
                    ['Claimant',   draft['Content ID Claimants'] || '—'],
                    ['YouTube',    draft['YouTube Link'] || '—'],
                  ].map(([k, v]) => (
                    <div key={k} style={{ display: 'grid', gridTemplateColumns: '120px 1fr', gap: 12, padding: '6px 0', borderBottom: '1px solid var(--rule-soft)' }}>
                      <span className="ff-mono upper" style={{ fontSize: 10, color: 'var(--ink-3)', letterSpacing: '.08em' }}>{k}</span>
                      <span className="ff-mono" style={{ fontSize: 12, color: 'var(--ink)', wordBreak: 'break-all' }}>{v}</span>
                    </div>
                  ))}
                </div>
                <p style={{ fontSize: 12, color: 'var(--ink-3)', lineHeight: 1.5 }}>
                  Saving creates this record in your video catalog. You can edit any field later from the Videos tab.
                </p>
              </>
            )}
          </div>

          {/* Footer */}
          <div style={{ padding: '14px 24px', borderTop: '1px solid var(--rule)', display: 'flex', justifyContent: 'space-between' }}>
            {stepNum > 1 ? (
              <button onClick={() => setStep(stepNum === 3 ? 'details' : 'link')} className="ff-mono upper"
                style={{ padding: '9px 16px', fontSize: 11, letterSpacing: '.08em', fontWeight: 600, background: 'transparent', color: 'var(--ink-2)', border: '1px solid var(--rule)', cursor: 'pointer' }}>← Back</button>
            ) : <span />}
            <div style={{ display: 'flex', gap: 8 }}>
              <button onClick={close} className="ff-mono upper"
                style={{ padding: '9px 14px', fontSize: 11, letterSpacing: '.08em', fontWeight: 500, background: 'transparent', color: 'var(--ink-3)', border: 0, cursor: 'pointer' }}>Cancel</button>
              {stepNum < 3 ? (
                <button onClick={() => setStep(stepNum === 1 ? 'details' : 'confirm')}
                  disabled={stepNum === 1 && !draft['Recording']}
                  className="ff-mono upper"
                  style={{ padding: '9px 18px', fontSize: 11, letterSpacing: '.08em', fontWeight: 700,
                    background: (stepNum === 1 && !draft['Recording']) ? 'var(--ink-4)' : 'var(--ink)',
                    color: 'var(--bg)', border: 0,
                    cursor: (stepNum === 1 && !draft['Recording']) ? 'not-allowed' : 'pointer' }}>Continue →</button>
              ) : (
                <button onClick={save} className="ff-mono upper"
                  style={{ padding: '9px 18px', fontSize: 11, letterSpacing: '.08em', fontWeight: 700, background: 'var(--ink)', color: 'var(--bg)', border: 0, cursor: 'pointer' }}>Create video</button>
              )}
            </div>
          </div>
        </div>
      </>
    );
  }

  // ─────────────────────────────────────────────────────────────────
  // VIDEOS-ON-RECORDING — embeds in the recording detail screen
  // (manually mounted by ScreenRecording / RecordingDrawer if they
  // call window.RecordingVideosBlock).
  // ─────────────────────────────────────────────────────────────────
  function RecordingVideosBlock({ recordingTitle, recordingId }) {
    const [tick, setTick] = useState(0);
    useEffect(() => {
      const onChange = () => setTick((t) => t + 1);
      window.addEventListener('astro-videos-changed', onChange);
      return () => window.removeEventListener('astro-videos-changed', onChange);
    }, []);
    const videos = useMemo(() => {
      const all = (window.RS && window.RS.videos) || [];
      return all.filter((v) => (v['Recording'] || '') === (recordingTitle || '') || v['Recording'] === recordingId);
    }, [recordingTitle, recordingId, tick]);
    return (
      <div style={{ marginTop: 20 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
          <div className="ff-mono upper" style={{ fontSize: 11, letterSpacing: '.12em', fontWeight: 700, color: 'var(--ink-2)' }}>
            LINKED VIDEOS · {videos.length}
          </div>
          <button onClick={() => window.dispatchEvent(new CustomEvent('astro-add-video', { detail: { recordingTitle } }))}
            className="ff-mono upper"
            style={{ padding: '5px 10px', fontSize: 10, letterSpacing: '.1em', fontWeight: 600, background: 'transparent', color: 'var(--ink-2)', border: '1px solid var(--rule)', cursor: 'pointer' }}>
            + ADD VIDEO
          </button>
        </div>
        {videos.length === 0 && (
          <div style={{ padding: '18px 14px', textAlign: 'center', border: '1px dashed var(--rule)', color: 'var(--ink-3)', fontSize: 12 }}>
            No music videos linked to this recording.
          </div>
        )}
        {videos.length > 0 && (
          <div>
            {videos.map((v) => {
              const thumb = ytThumb(v['YouTube Link']);
              return (
                <div key={v['Video ID']}
                  onClick={() => window.dispatchEvent(new CustomEvent('astro-open-video', { detail: { id: v['Video ID'] } }))}
                  style={{ display: 'grid', gridTemplateColumns: '88px 1fr auto', gap: 12, alignItems: 'center', padding: '10px', border: '1px solid var(--rule)', marginBottom: 6, cursor: 'pointer', background: 'var(--bg)' }}
                  onMouseEnter={(e) => e.currentTarget.style.background = 'var(--bg-2)'}
                  onMouseLeave={(e) => e.currentTarget.style.background = 'var(--bg)'}>
                  <div style={{
                    aspectRatio: '16 / 9', background: thumb ? `center / cover no-repeat url("${thumb}")` : 'linear-gradient(135deg, var(--ink-5), var(--ink-4))',
                    border: '1px solid var(--rule)', position: 'relative',
                  }}>
                    {!thumb && (
                      <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                        <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="white" strokeOpacity="0.7" strokeWidth="1.5"><polygon points="23 7 16 12 23 17 23 7" /><rect x="1" y="5" width="15" height="14" rx="2" ry="2" /></svg>
                      </div>
                    )}
                  </div>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: 13, fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{v['Video Name']}</div>
                    <div className="ff-mono" style={{ fontSize: 10, color: 'var(--ink-3)', marginTop: 3 }}>
                      {v['Video ID']} · {v['ISRC (Video)'] || 'no ISRC'} · {v['Content ID Claimants'] || 'unclaimed'}
                    </div>
                  </div>
                  <div style={{ display: 'flex', gap: 6 }}>
                    {v['YouTube Link'] && (<span className="ff-mono upper" style={{ fontSize: 9, padding: '2px 6px', border: '1px solid var(--rule)', color: 'var(--ink-2)' }}>YT</span>)}
                    {v['FB Video Link'] && (<span className="ff-mono upper" style={{ fontSize: 9, padding: '2px 6px', border: '1px solid var(--rule)', color: 'var(--ink-2)' }}>FB</span>)}
                    <span className="ff-mono" style={{ fontSize: 14, color: 'var(--ink-3)', alignSelf: 'center' }}>›</span>
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>
    );
  }

  Object.assign(window, {
    GlobalVideoDrawer,
    GlobalAddVideoModal: AddVideoModal,
    RecordingVideosBlock,
  });
})();
