/* ============================================================
   CADENCE — Upload Music (catalog hub)
   window.UploadMusic — upload songs and manage your catalog, grouped
   into releases (albums/EPs) or singles.
   ============================================================ */
(function () {
  const { useState, useRef } = React;
  const I = window.Icon;
  const F = window.CAD.fmt;

  const OFFERING_ERRORS = {
    invalid_title: 'Enter a song title.',
    invalid_genre: 'Pick a genre.',
    invalid_total_shares: 'Enter a valid number of shares.',
    invalid_price: 'Enter a valid share price.',
    invalid_revenue_share: 'Revenue share must be between 5% and 49%.',
    invalid_release_title: 'Enter a name for the new release.',
  };

  function SongRow({ s, releases, onOpen, onMakeSingle, onMoveTo, onDelete }) {
    return (
      <div className="row gap12" style={{ alignItems: 'center', padding: '8px 0', borderBottom: '1px solid var(--border-soft)' }}>
        <window.UI.Cover grad={s.coverGrad} size={34} radius={7} />
        <div className="grow" style={{ minWidth: 0, cursor: 'pointer' }} onClick={() => onOpen(s.id)}>
          <div style={{ fontWeight: 600, fontSize: 13.5, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{s.title}</div>
          <div className="muted" style={{ fontSize: 11.5 }}>{s.genreLabel} · {F.money(s.price, 2)}/sh · sells {F.money(s.salePrice, 2)}</div>
        </div>
        {onMakeSingle && (
          <button className="btn btn-ghost" style={{ padding: '5px 9px', fontSize: 12 }} onClick={() => onMakeSingle(s.id)}>Make single</button>
        )}
        {onMoveTo && releases.length > 0 && (
          <select
            className="cad-move"
            value=""
            onChange={(e) => { if (e.target.value) onMoveTo(s.id, e.target.value); }}
            style={{ background: 'var(--surface-2)', color: 'var(--text)', border: '1px solid var(--border-soft)', borderRadius: 8, fontSize: 12, padding: '5px 7px' }}
          >
            <option value="">Move to…</option>
            {releases.map((r) => <option key={r.id} value={r.id}>{r.title}</option>)}
          </select>
        )}
        <button className="icon-btn" title={`Delete ${s.title}`} onClick={() => onDelete(s)} style={{ width: 28, height: 28, color: 'var(--red, #f87171)' }}><I.x style={{ width: 13 }} /></button>
      </div>
    );
  }

  function ReleaseCard({ release, releases, onOpen, onUpdate, onDelete, onDeleteRelease, onMakeSingle }) {
    const bundleOn = release.bundlePrice != null;
    const [price, setPrice] = useState(release.bundlePrice != null ? release.bundlePrice : 9.99);

    return (
      <div className="panel panel-pad" style={{ marginBottom: 14 }}>
        <div className="row between" style={{ alignItems: 'flex-start', marginBottom: 10 }}>
          <div className="row gap12">
            <window.UI.Cover grad={release.coverGrad} size={44} radius={9} />
            <div>
              <div className="row gap8"><span style={{ fontWeight: 700, fontSize: 15 }}>{release.title}</span><span className="tag" style={{ textTransform: 'uppercase' }}>{release.type}</span></div>
              <div className="muted" style={{ fontSize: 12 }}>{release.songs.length} song{release.songs.length === 1 ? '' : 's'}</div>
            </div>
          </div>
          <button className="btn btn-ghost" style={{ padding: '6px 10px', fontSize: 12 }} onClick={() => onDeleteRelease(release)}>Delete release</button>
        </div>

        {/* sale controls */}
        <div className="row gap16 wrap" style={{ alignItems: 'center', padding: '10px 0', borderTop: '1px solid var(--border-soft)', borderBottom: '1px solid var(--border-soft)', marginBottom: 8 }}>
          <label className="row gap8" style={{ fontSize: 12.5, cursor: 'pointer' }}>
            <input type="checkbox" checked={bundleOn} onChange={(e) => onUpdate(release.id, { bundlePrice: e.target.checked ? Number(price) || 9.99 : null })} />
            Sell as album bundle
          </label>
          {bundleOn && (
            <span className="row gap6">
              <span className="muted" style={{ fontSize: 12 }}>Price</span>
              <span className="input" style={{ width: 110 }}><span className="pre">$</span>
                <input type="number" min="0.01" step="0.01" value={price} onChange={(e) => setPrice(e.target.value)} onBlur={() => onUpdate(release.id, { bundlePrice: Number(price) || 0.01 })} />
              </span>
            </span>
          )}
          <label className="row gap8" style={{ fontSize: 12.5, cursor: 'pointer' }}>
            <input type="checkbox" checked={release.sellIndividually !== false} onChange={(e) => onUpdate(release.id, { sellIndividually: e.target.checked })} />
            Sell songs individually
          </label>
        </div>

        {release.songs.length === 0
          ? <div className="muted" style={{ fontSize: 12.5, padding: '6px 0' }}>No songs yet — upload into this release or move songs in.</div>
          : release.songs.map((s) => (
            <SongRow key={s.id} s={s} releases={[]} onOpen={onOpen} onMakeSingle={onMakeSingle} onDelete={onDelete} />
          ))}
      </div>
    );
  }

  function UploadMusic({ go, openSong }) {
    const cad = window.useCad();
    const a = cad.artist || {};
    const genres = cad.genres || {};
    const releases = a.releases || [];
    const singles = a.singles || [];
    const genreKeys = Object.keys(genres);

    const [title, setTitle] = useState('');
    const [genre, setGenre] = useState(genreKeys[0] || 'indie-electronic');
    const [revShare, setRevShare] = useState(30);
    const [shares, setShares] = useState(30000);
    const [price, setPrice] = useState(1.0);
    const [songPrice, setSongPrice] = useState(9.99);
    const [bpm, setBpm] = useState('');
    const [file, setFile] = useState(null);
    const [releaseType, setReleaseType] = useState('single'); // 'single' | 'ep' | 'album'
    const [releaseTarget, setReleaseTarget] = useState('new'); // 'new' | releaseId
    const [newReleaseTitle, setNewReleaseTitle] = useState('');
    const [busy, setBusy] = useState(false);
    const titleRef = useRef(null);
    const fileRef = useRef(null);

    const typeLabel = releaseType === 'ep' ? 'EP' : 'album';
    const matchingReleases = releases.filter((r) => r.type === releaseType);

    const resetForm = () => { setTitle(''); setFile(null); if (fileRef.current) fileRef.current.value = ''; setBpm(''); setReleaseType('single'); setReleaseTarget('new'); setNewReleaseTitle(''); };

    const launch = async () => {
      if (busy) return;
      if (!title.trim()) { window.toast({ kind: 'sell', title: 'Title required', desc: 'Give your song a title.' }); titleRef.current?.focus(); return; }
      if (releaseType !== 'single' && releaseTarget === 'new' && !newReleaseTitle.trim()) { window.toast({ kind: 'sell', title: 'Release name required', desc: `Name the new ${typeLabel}.` }); return; }
      setBusy(true);
      try {
        const payload = {
          title: title.trim(), genre,
          totalShares: Number(shares), price: Number(price),
          revenueSharePct: Number(revShare), salePrice: Number(songPrice),
        };
        if (String(bpm).trim() !== '') payload.bpm = Number(bpm);
        if (releaseType !== 'single') {
          if (releaseTarget === 'new') { payload.newReleaseTitle = newReleaseTitle.trim(); payload.newReleaseType = releaseType; }
          else { payload.releaseId = releaseTarget; }
        }
        await cad.createOffering(payload, file);
        window.toast({ title: 'Song uploaded', desc: `“${payload.title}” is live in your catalog.` });
        resetForm();
      } catch (error) {
        window.toast({ kind: 'sell', title: 'Upload failed', desc: OFFERING_ERRORS[error?.message] || 'The song could not be uploaded.' });
      } finally {
        setBusy(false);
      }
    };

    const updateRelease = (id, patch) => cad.updateRelease(id, patch).catch(() => window.toast({ kind: 'sell', title: 'Update failed', desc: 'Could not update the release.' }));
    const deleteRelease = (r) => {
      if (!window.confirm(`Delete the release “${r.title}”? Its songs become singles (they are NOT deleted).`)) return;
      cad.deleteRelease(r.id).catch(() => window.toast({ kind: 'sell', title: 'Delete failed', desc: 'Could not delete the release.' }));
    };
    const deleteSong = (s) => {
      if (!window.confirm(`Delete “${s.title}”? This permanently removes the offering and its audio. This can’t be undone.`)) return;
      cad.deleteOffering(s.id)
        .then((res) => window.toast({ title: 'Song deleted', desc: `“${s.title}” removed${res && res.refund ? ` · ${F.money(res.refund, 2)} refunded` : ''}.` }))
        .catch((e) => window.toast({ kind: 'sell', title: 'Delete failed', desc: e?.message === 'offering_has_investors' ? 'Other investors hold shares — can’t delete.' : 'Could not delete the song.' }));
    };
    const makeSingle = (songId) => cad.assignSong(songId, null);
    const moveTo = (songId, releaseId) => cad.assignSong(songId, releaseId);

    const totalSongs = a.songs ? a.songs.length : 0;

    return (
      <div className="page">
        <div className="row between wrap" style={{ marginBottom: 22, gap: 14 }}>
          <div>
            <h1 className="page-title">Upload Music</h1>
            <div className="page-sub">{a.name ? `${a.name} · ` : ''}Your catalog · {releases.length} release{releases.length === 1 ? '' : 's'} · {totalSongs} song{totalSongs === 1 ? '' : 's'}</div>
          </div>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 360px', gap: 18, alignItems: 'start' }} className="pf-mid">
          {/* ---------- catalog ---------- */}
          <div className="col">
            {releases.length === 0 && singles.length === 0 && (
              <div className="panel panel-pad muted" style={{ fontSize: 13 }}>
                No music yet. Use the form to upload your first song — as a single, or into a new album/EP.
              </div>
            )}

            {releases.map((r) => (
              <ReleaseCard
                key={r.id}
                release={r}
                releases={releases}
                onOpen={openSong}
                onUpdate={updateRelease}
                onDelete={deleteSong}
                onDeleteRelease={deleteRelease}
                onMakeSingle={makeSingle}
              />
            ))}

            {singles.length > 0 && (
              <div className="panel panel-pad">
                <div className="row between" style={{ marginBottom: 8 }}>
                  <h3 style={{ margin: 0, fontSize: 14, fontWeight: 700 }}>Singles</h3>
                  <span className="sub muted" style={{ fontSize: 12 }}>{singles.length}</span>
                </div>
                {singles.map((s) => (
                  <SongRow key={s.id} s={s} releases={releases} onOpen={openSong} onMoveTo={moveTo} onDelete={deleteSong} />
                ))}
              </div>
            )}
          </div>

          {/* ---------- upload form ---------- */}
          <div className="panel panel-pad" style={{ background: 'linear-gradient(160deg, var(--blue-tint), transparent)' }}>
            <h3 style={{ margin: '0 0 6px', fontSize: 14, fontWeight: 700 }}>Upload a song</h3>
            <div className="muted" style={{ fontSize: 12.5, lineHeight: 1.5 }}>Add a track to your catalog and raise capital from fans.</div>
            <div className="col gap12 mt16">
              <div className="field"><label>Song title</label><div className="input"><input ref={titleRef} type="text" value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Enter song title" /></div></div>

              <div className="field"><label>Release</label><div className="input">
                <select value={releaseType} onChange={(e) => { setReleaseType(e.target.value); setReleaseTarget('new'); }}>
                  <option value="single">Single</option>
                  <option value="ep">EP</option>
                  <option value="album">Album</option>
                </select>
              </div></div>
              {releaseType !== 'single' && (
                <React.Fragment>
                  <div className="field"><label>{typeLabel === 'EP' ? 'EP' : 'Album'}</label><div className="input">
                    <select value={releaseTarget} onChange={(e) => setReleaseTarget(e.target.value)}>
                      <option value="new">+ New {typeLabel}…</option>
                      {matchingReleases.map((r) => <option key={r.id} value={r.id}>{r.title}</option>)}
                    </select>
                  </div></div>
                  {releaseTarget === 'new' && (
                    <div className="field"><label>{typeLabel === 'EP' ? 'EP' : 'Album'} name</label><div className="input"><input type="text" value={newReleaseTitle} onChange={(e) => setNewReleaseTitle(e.target.value)} placeholder={`${typeLabel === 'EP' ? 'EP' : 'Album'} title`} /></div></div>
                  )}
                </React.Fragment>
              )}

              <div className="field"><label>Genre</label><div className="input"><select value={genre} onChange={(e) => setGenre(e.target.value)}>
                {Object.entries(genres).map(([key, info]) => (<option key={key} value={key}>{info.label}</option>))}
              </select></div></div>
              <div className="field"><label>Share of revenue to offer</label><div className="row gap8"><input type="range" className="rng" min="5" max="49" value={revShare} onChange={(e) => setRevShare(Number(e.target.value))} /><span className="num" style={{ width: 42, textAlign: 'right' }}>{revShare}%</span></div></div>
              <div className="field"><label>Total shares</label><div className="input"><input type="number" min="1" value={shares} onChange={(e) => setShares(e.target.value)} /><span className="suf">sh</span></div></div>
              <div className="field"><label>Initial share price</label><div className="input"><span className="pre">$</span><input type="number" min="0.01" step="0.01" value={price} onChange={(e) => setPrice(e.target.value)} /><span className="suf">/sh</span></div></div>
              <div className="field"><label>Song price (fans pay to buy)</label><div className="input"><span className="pre">$</span><input type="number" min="0.01" step="0.01" value={songPrice} onChange={(e) => setSongPrice(e.target.value)} /></div></div>
              <div className="field"><label>Tempo (optional)</label><div className="input"><input type="number" min="1" max="400" step="1" value={bpm} onChange={(e) => setBpm(e.target.value)} placeholder="e.g. 120" /><span className="suf">BPM</span></div></div>
              <div className="field"><label>Audio file (optional)</label>
                <input ref={fileRef} type="file" accept="audio/*" onChange={(e) => setFile(e.target.files && e.target.files[0] ? e.target.files[0] : null)} style={{ display: 'none' }} />
                <div className="row gap8" style={{ alignItems: 'center' }}>
                  <button type="button" className="btn btn-ghost" style={{ padding: '8px 12px', fontSize: 12.5, flex: 'none' }} onClick={() => fileRef.current && fileRef.current.click()}>
                    <I.upload style={{ width: 14 }} />Choose file
                  </button>
                  <span className="muted" style={{ fontSize: 12, minWidth: 0, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{file ? file.name : 'No file chosen'}</span>
                  {file && <button type="button" className="icon-btn" title="Remove file" onClick={() => { setFile(null); if (fileRef.current) fileRef.current.value = ''; }} style={{ width: 26, height: 26, flex: 'none' }}><I.x style={{ width: 12 }} /></button>}
                </div>
              </div>
            </div>
            <button className="btn btn-primary btn-block mt16" disabled={busy} style={{ opacity: busy ? 0.7 : 1 }} onClick={launch}>{busy ? 'Uploading…' : 'Upload song'}</button>
          </div>
        </div>
      </div>
    );
  }

  window.UploadMusic = UploadMusic;
})();
