// Composer.jsx — upload + metadata + platform picker + schedule.
/* global React, I, PlatGlyph, PLATFORMS, PRODUCTS */

const fmtTime = (s) => {
  if (!isFinite(s)) return '00:00';
  const m = Math.floor(s / 60), sec = Math.floor(s % 60);
  return `${String(m).padStart(2, '0')}:${String(sec).padStart(2, '0')}`;
};
const fmtSize = (b) => b > 1e6 ? (b / 1e6).toFixed(1) + ' MB' : Math.max(1, Math.round(b / 1e3)) + ' KB';
const fmtSched = (d) => {
  if (!d) return '';
  try { return new Date(d + 'T00:00').toLocaleDateString('id-ID', { weekday: 'short', day: 'numeric', month: 'short', year: 'numeric' }); }
  catch (e) { return d; }
};

const isoOf = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
const DOW = ['Min', 'Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab'];

function useOutside(ref, onOut) {
  React.useEffect(() => {
    const h = (e) => { if (ref.current && !ref.current.contains(e.target)) onOut(); };
    document.addEventListener('mousedown', h);
    return () => document.removeEventListener('mousedown', h);
  }, [onOut]);
}

function DatePicker({ value, onChange }) {
  const [open, setOpen] = React.useState(false);
  const [view, setView] = React.useState(() => value ? new Date(value + 'T00:00') : new Date());
  const ref = React.useRef(null);
  useOutside(ref, () => setOpen(false));

  const today = new Date(); const todayIso = isoOf(today);
  const y = view.getFullYear(), m = view.getMonth();
  const start = new Date(y, m, 1); start.setDate(1 - start.getDay());
  const cells = Array.from({ length: 42 }, (_, i) => { const d = new Date(start); d.setDate(start.getDate() + i); return d; });

  const pick = (d) => { onChange(isoOf(d)); setOpen(false); };

  return (
    <div className="dp" ref={ref}>
      <button type="button" className={'dp-trigger' + (open ? ' open' : '')} onClick={() => setOpen(o => !o)}>
        <I.calendar />
        <span className={value ? 'v' : 'ph'}>{value ? fmtSched(value) : 'Pilih tanggal'}</span>
        <span className="dp-caret"><I.chev /></span>
      </button>
      {open && (
        <div className="dp-pop">
          <div className="dp-head">
            <button type="button" onClick={() => setView(new Date(y, m - 1, 1))} aria-label="Bulan sebelumnya"><I.chev style={{ transform: 'rotate(90deg)' }} /></button>
            <b>{view.toLocaleDateString('id-ID', { month: 'long', year: 'numeric' })}</b>
            <button type="button" onClick={() => setView(new Date(y, m + 1, 1))} aria-label="Bulan berikutnya"><I.chev style={{ transform: 'rotate(-90deg)' }} /></button>
          </div>
          <div className="dp-grid dp-dow">{DOW.map(d => <span key={d} className="dp-dowc">{d}</span>)}</div>
          <div className="dp-grid">
            {cells.map((d, i) => {
              const di = isoOf(d);
              const cls = ['dp-cell'];
              if (d.getMonth() !== m) cls.push('mute');
              if (di === value) cls.push('sel');
              else if (di === todayIso) cls.push('today');
              return <button type="button" key={i} className={cls.join(' ')} onClick={() => pick(d)}>{d.getDate()}</button>;
            })}
          </div>
          <div className="dp-foot">
            <button type="button" onClick={() => { setView(new Date()); pick(new Date()); }}>Hari ini</button>
            {value && <button type="button" className="clr" onClick={() => { onChange(''); setOpen(false); }}>Bersihkan</button>}
          </div>
        </div>
      )}
    </div>
  );
}

function TimePicker({ value, onChange }) {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null), listRef = React.useRef(null);
  useOutside(ref, () => setOpen(false));
  const slots = React.useMemo(() => Array.from({ length: 48 }, (_, i) =>
    `${String(Math.floor(i / 2)).padStart(2, '0')}:${i % 2 ? '30' : '00'}`), []);
  React.useEffect(() => {
    if (open && listRef.current) {
      const el = listRef.current.querySelector('.tp-item.sel');
      if (el) listRef.current.scrollTop = el.offsetTop - 90;
    }
  }, [open]);
  return (
    <div className="dp" ref={ref}>
      <button type="button" className={'dp-trigger' + (open ? ' open' : '')} onClick={() => setOpen(o => !o)}>
        <I.clock />
        <span className="v">{value || '07:00'} <em>WIB</em></span>
        <span className="dp-caret"><I.chev /></span>
      </button>
      {open && (
        <div className="dp-pop tp-pop" ref={listRef}>
          {slots.map(s => (
            <button type="button" key={s} className={'tp-item' + (s === value ? ' sel' : '')}
                    onClick={() => { onChange(s); setOpen(false); }}>{s}</button>
          ))}
        </div>
      )}
    </div>
  );
}

async function grabFrames(video) {
  const W = 198, H = 352, pts = [0.12, 0.5, 0.82], out = [];
  for (const p of pts) {
    try {
      await new Promise((res, rej) => {
        const ok = () => { video.removeEventListener('seeked', ok); res(); };
        video.addEventListener('seeked', ok);
        setTimeout(res, 900);
        video.currentTime = Math.min((video.duration || 1) * p, (video.duration || 1) - 0.05);
      });
      const c = document.createElement('canvas'); c.width = W; c.height = H;
      c.getContext('2d').drawImage(video, 0, 0, W, H);
      out.push(c.toDataURL('image/jpeg', 0.72));
    } catch (e) { /* frame skip */ }
  }
  try { video.currentTime = 0; } catch (e) {}
  return out;
}

// Sorot bagian nama yang cocok dengan kueri pencarian.
function highlightMatch(text, q) {
  const query = (q || '').trim();
  if (!query) return text;
  const i = text.toLowerCase().indexOf(query.toLowerCase());
  if (i < 0) return text;
  return (<>{text.slice(0, i)}<mark className="pp-hl">{text.slice(i, i + query.length)}</mark>{text.slice(i + query.length)}</>);
}

// Dropdown produk yang bisa DICARI (pengganti <select> biasa).
function ProductPicker({ products, value, onChange }) {
  const [open, setOpen] = React.useState(false);
  const [q, setQ] = React.useState('');
  const ref = React.useRef(null);
  const searchRef = React.useRef(null);
  useOutside(ref, () => setOpen(false));

  const selected = products.find(p => p.id === value);
  const filtered = q.trim()
    ? products.filter(p => (p.name || '').toLowerCase().includes(q.trim().toLowerCase()))
    : products;

  React.useEffect(() => { if (open && searchRef.current) searchRef.current.focus(); }, [open]);

  const pick = (id) => { onChange(id); setOpen(false); setQ(''); };

  return (
    <div className="dp pp" ref={ref} style={{ gridColumn: '1 / -1' }}>
      <button type="button" className={'dp-trigger' + (open ? ' open' : '')} onClick={() => setOpen(o => !o)}>
        <span className="pp-tag"><I.pin /></span>
        <span className={selected ? 'v pp-val' : 'ph pp-val'}>{selected ? selected.name : 'Tanpa produk'}</span>
        <span className="dp-caret"><I.chev /></span>
      </button>
      {open && (
        <div className="dp-pop pp-pop">
          <div className="pp-search">
            <I.search />
            <input ref={searchRef} className="pp-search-in" placeholder="Cari produk…"
                   value={q} onChange={e => setQ(e.target.value)} spellCheck="false" />
            {q && <button type="button" className="pp-clear" onClick={() => setQ('')} aria-label="Bersihkan"><I.xsm /></button>}
          </div>
          <div className="pp-list">
            <button type="button" className={'pp-item' + (!value ? ' sel' : '')} onClick={() => pick('')}>
              <span className="pp-none">— Tanpa produk —</span>
            </button>
            {filtered.map(p => (
              <button type="button" key={p.id} className={'pp-item' + (p.id === value ? ' sel' : '')} onClick={() => pick(p.id)}>
                {highlightMatch(p.name, q)}
              </button>
            ))}
            {filtered.length === 0 && <div className="pp-empty">Tidak ada produk cocok “{q}”.</div>}
          </div>
        </div>
      )}
    </div>
  );
}

function Composer({ onSubmit, conn = {}, goIntegrasi }) {
  const [file, setFile] = React.useState(null);     // {url,name,size,dur}
  const [drag, setDrag] = React.useState(false);
  const [covers, setCovers] = React.useState([]);
  const [coverIdx, setCoverIdx] = React.useState(0);
  const [caption, setCaption] = React.useState('');
  const [tagInput, setTagInput] = React.useState('');
  const [tags, setTags] = React.useState(['Assuffah']);
  const [plats, setPlats] = React.useState({ facebook: true, instagram: true, youtube: true, tiktok: true, shopee: false, website: true });
  const [product, setProduct] = React.useState('');
  const [products, setProducts] = React.useState(PRODUCTS);   // fallback contoh
  const [productSource, setProductSource] = React.useState('mock');
  const [mode, setMode] = React.useState('now');    // now | schedule
  const [date, setDate] = React.useState('');
  const [time, setTime] = React.useState('07:00');
  const inputRef = React.useRef(null);
  const vidRef = React.useRef(null);
  const grabRef = React.useRef(null);

  // muat produk ASLI website (bila terhubung) untuk pemilih "tempel ke produk"
  React.useEffect(() => {
    window.MUAPI.websiteProducts().then(list => {
      if (list && list.length) { setProducts(list); setProductSource('website'); }
    }).catch(() => {});
  }, []);

  const selected = PLATFORMS.filter(p => plats[p.id]);
  const attachOn = selected.some(p => p.attach);
  const canSubmit = !!file && selected.length > 0 && !(mode === 'schedule' && !date);

  function loadFile(f) {
    if (!f || !f.type.startsWith('video/')) return;
    const url = URL.createObjectURL(f);
    const v = document.createElement('video');
    v.preload = 'metadata'; v.muted = true; v.src = url;
    v.onloadedmetadata = async () => {
      setFile({ url, name: f.name, size: f.size, dur: v.duration, raw: f });
      setCovers([]); setCoverIdx(0);
      try {
        grabRef.current = v;
        const frames = await grabFrames(v);
        if (frames.length) setCovers(frames);
      } catch (e) {}
    };
  }

  const onDrop = (e) => { e.preventDefault(); setDrag(false); loadFile(e.dataTransfer.files[0]); };
  const addTag = (raw) => {
    const t = raw.trim().replace(/^#/, '');
    if (t && !tags.includes(t)) setTags([...tags, t]);
    setTagInput('');
  };
  const onTagKey = (e) => {
    if ((e.key === 'Enter' || e.key === ',') && tagInput.trim()) { e.preventDefault(); addTag(tagInput); }
    else if (e.key === 'Backspace' && !tagInput && tags.length) setTags(tags.slice(0, -1));
  };

  const togglePlat = (id) => setPlats(p => ({ ...p, [id]: !p[id] }));

  const submit = () => {
    if (!canSubmit) return;
    onSubmit({
      file: file.raw,                              // objek File asli untuk diunggah ke backend
      title: caption.trim() || 'Tanpa judul',
      caption,                                     // caption penuh (judul/deskripsi diturunkan di backend)
      tags, platforms: selected.map(p => p.id),
      product: attachOn && product ? product : null,
      schedule: mode === 'schedule' ? { date, time } : null,
      dur: fmtTime(file.dur),
      cover: covers[coverIdx] || null,
      hue: Math.floor(Math.random() * 360),
    });
  };

  const clear = () => { setFile(null); setCovers([]); };

  return (
    <div className="wrap">
      <div className="page-head">
        <h1>Multi Upload Video</h1>
        <p>Unggah satu video portrait, lalu pilih kanal tujuannya. Caption dipakai sama untuk semua platform.</p>
      </div>

      <div className="compose-grid">
        {/* LEFT — upload + preview */}
        <div className="compose-left">
          <div className="card card-pad">
            <div className="card-h"><span className="step">1</span><span className="ttl">Video Portrait</span></div>

            {!file ? (
              <div className={'uploader' + (drag ? ' drag' : '')}
                   onClick={() => inputRef.current.click()}
                   onDragOver={e => { e.preventDefault(); setDrag(true); }}
                   onDragLeave={() => setDrag(false)} onDrop={onDrop}>
                <div className="drop-in">
                  <div className="ic"><I.upload /></div>
                  <b>Seret video ke sini</b>
                  <small>atau klik untuk memilih berkas<br />MP4 / MOV · rasio 9:16 · maks 500 MB</small>
                </div>
              </div>
            ) : (
              <div className="uploader filled">
                <video ref={vidRef} src={file.url} muted loop playsInline
                       onClick={e => { e.currentTarget.paused ? e.currentTarget.play() : e.currentTarget.pause(); }} />
                <div className="pv-grad" />
                <div className="pv-badge"><span className="dot" />9:16</div>
                <div className="pv-controls">
                  <button className="pv-mini" title="Putar / jeda"
                          onClick={() => { const v = vidRef.current; v.paused ? v.play() : v.pause(); }}><I.play /></button>
                  <button className="pv-mini" title="Ganti video" onClick={() => inputRef.current.click()}><I.swap /></button>
                  <button className="pv-mini" title="Hapus" onClick={clear}><I.trash /></button>
                </div>
                <div className="pv-foot">
                  <div className="fn">{file.name}</div>
                  <div className="meta"><span>{fmtTime(file.dur)}</span><span>{fmtSize(file.size)}</span></div>
                </div>
              </div>
            )}
            <input ref={inputRef} type="file" accept="video/*" hidden
                   onChange={e => loadFile(e.target.files[0])} />

            {file && (
              <div className="covers">
                {covers.length ? covers.map((c, i) => (
                  <button key={i} className={'cover-thumb' + (i === coverIdx ? ' sel' : '')} onClick={() => setCoverIdx(i)}>
                    <img src={c} alt={'Sampul ' + (i + 1)} />
                  </button>
                )) : null}
                <span className="hint">{covers.length ? 'Pilih sampul (cover) otomatis' : 'Menyiapkan sampul…'}</span>
              </div>
            )}
          </div>
        </div>

        {/* RIGHT — metadata + platforms + schedule */}
        <div className="compose-right">
          {/* metadata */}
          <div className="card card-pad" style={{ marginBottom: 20 }}>
            <div className="card-h"><span className="step">2</span><span className="ttl">Judul &amp; Tag</span></div>

            <div className="field">
              <label>
                <span className="lt">Judul / Caption</span>
                <span className="cnt">{caption.length} karakter</span>
              </label>
              <textarea className="textarea" value={caption} placeholder="Tulis caption yang dipakai bersama di semua platform…"
                        onChange={e => setCaption(e.target.value)} rows={4} />
              {selected.length > 0 && caption.length > 0 && (
                <div className="tags" style={{ marginTop: 9 }}>
                  {selected.map(p => {
                    const rem = p.limit - caption.length;
                    return (
                      <span key={p.id} className="tag" style={rem < 0
                        ? { background: 'var(--danger-soft)', color: 'var(--danger)' }
                        : { background: 'var(--surface-2)', color: 'var(--ink-2)' }}>
                        <PlatGlyph id={p.id} size={16} radius={5} />
                        {rem < 0 ? `${-rem} lebih` : `sisa ${rem}`}
                      </span>
                    );
                  })}
                </div>
              )}
            </div>

            <div className="field">
              <label><span className="lt">Tag / Hashtag</span><span className="opt">opsional</span></label>
              <input className="input" value={tagInput} placeholder="Ketik lalu Enter — mis. promo, produk, diskon"
                     onChange={e => setTagInput(e.target.value)} onKeyDown={onTagKey} onBlur={() => tagInput && addTag(tagInput)} />
              {tags.length > 0 && (
                <div className="tags">
                  {tags.map(t => (
                    <span className="tag" key={t}>#{t}
                      <button onClick={() => setTags(tags.filter(x => x !== t))} aria-label={'Hapus ' + t}><I.xsm /></button>
                    </span>
                  ))}
                </div>
              )}
            </div>
          </div>

          {/* platforms */}
          <div className="card card-pad" style={{ marginBottom: 20 }}>
            <div className="card-h"><span className="step">3</span><span className="ttl">Pilih Platform</span>
              <button type="button" onClick={goIntegrasi} style={{ marginLeft: 'auto', background: 'transparent', border: 0, cursor: 'pointer', fontSize: 13, fontWeight: 700, color: 'var(--primary-ink)', display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                <I.plug width="15" height="15" /> Kelola koneksi
              </button>
            </div>

            <div className="plat-list">
              {PLATFORMS.map(p => {
                const on = !!plats[p.id];
                const cs = (conn[p.id] && conn[p.id].status) || 'connected';
                const linked = cs === 'connected';
                return (
                  <div className={'plat' + (on ? ' on' : '')} key={p.id}>
                    <div className="plat-row" onClick={() => togglePlat(p.id)}>
                      <span className="plat-ic"><PlatGlyph id={p.id} /></span>
                      <div className="plat-name">
                        <b>{p.name}<span className={'conn-mini ' + cs} title={linked ? 'Terhubung' : 'Belum terhubung'} /></b>
                        <small className={on && (caption.length > p.limit || !linked) ? 'over' : ''}>
                          {on && !linked
                            ? (cs === 'expired' ? 'Token kedaluwarsa — perbarui di Integrasi' : 'Belum terhubung — atur di Integrasi')
                            : on && caption.length > p.limit ? `Caption ${caption.length - p.limit} karakter terlalu panjang`
                            : p.sub}
                        </small>
                      </div>
                      <button className="switch" data-on={on ? '1' : '0'} aria-label={p.name}
                              onClick={e => { e.stopPropagation(); togglePlat(p.id); }}><i /></button>
                    </div>

                  </div>
                );
              })}
            </div>

            {/* tempel ke produk — muncul bila Shopee / Website dipilih */}
            {attachOn && (
              <div className="attach" style={{ marginTop: 14 }}>
                <div className="alab"><span className="pin"><I.pin /></span>Tempel video ke produk (opsional):</div>
                <ProductPicker products={products} value={product} onChange={setProduct} />
                <small className="hint" style={{ gridColumn: '1 / -1' }}>
                  {productSource === 'website'
                    ? 'Produk asli dari Assuffah Store'
                    : 'Contoh produk — hubungkan Website di Integrasi untuk daftar produk asli'}
                </small>
              </div>
            )}
          </div>

          {/* schedule */}
          <div className="card card-pad" style={{ marginBottom: 22 }}>
            <div className="card-h"><span className="step">4</span><span className="ttl">Waktu Tayang</span></div>
            <div className="seg">
              <button className={mode === 'now' ? 'on' : ''} onClick={() => setMode('now')}><I.bolt width="15" height="15" />Sebar sekarang</button>
              <button className={mode === 'schedule' ? 'on' : ''} onClick={() => setMode('schedule')}><I.calendar />Jadwalkan</button>
            </div>
            {mode === 'schedule' && (
              <>
                <div className="sched-fields">
                  <div className="field"><label><span className="lt">Tanggal</span></label>
                    <DatePicker value={date} onChange={setDate} />
                  </div>
                  <div className="field"><label><span className="lt">Jam</span></label>
                    <TimePicker value={time} onChange={setTime} />
                  </div>
                </div>
                <div className="sched-preview">
                  <span className="sp-ic"><I.calendar /></span>
                  {date
                    ? <span>Tayang otomatis <b>{fmtSched(date)}</b> pukul <b>{time} WIB</b></span>
                    : <span>Pilih tanggal untuk menjadwalkan tayang.</span>}
                </div>
              </>
            )}
          </div>

          {/* submit */}
          <div className="submit-bar">
            <button className="btn-primary" disabled={!canSubmit} onClick={submit}>
              <I.send />{mode === 'schedule' ? 'Jadwalkan & Sebar' : 'Upload & Sebar'}
            </button>
            <div className="submit-note">
              {!file ? 'Unggah video dulu untuk melanjutkan.'
                : selected.length === 0 ? 'Pilih minimal satu platform.'
                : mode === 'schedule' && !date ? 'Tentukan tanggal jadwal.'
                : `Akan dikirim ke ${selected.length} platform${plats.shopee ? ' (termasuk listing Shopee)' : ''}.`}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Composer });
