/* global React, Icon, Placeholder, TrackArt, fmtTime */

const { useState: useStateAdmin } = React;

const readAudioDuration = (file) => new Promise((resolve) => {
  const audio = document.createElement("audio");
  const url = URL.createObjectURL(file);
  audio.preload = "metadata";
  audio.onloadedmetadata = () => {
    URL.revokeObjectURL(url);
    resolve(Math.round(audio.duration || 0));
  };
  audio.onerror = () => {
    URL.revokeObjectURL(url);
    resolve(0);
  };
  audio.src = url;
});

const AdminScreen = ({ onNav, tracks = [], onAddTrack, onPlayTrack }) => {
  const [title, setTitle] = useStateAdmin("");
  const [artist, setArtist] = useStateAdmin("Viral Tension");
  const [album, setAlbum] = useStateAdmin("Singles");
  const [audioFile, setAudioFile] = useStateAdmin(null);
  const [artFile, setArtFile] = useStateAdmin(null);
  const [explicit, setExplicit] = useStateAdmin(false);
  const [duration, setDuration] = useStateAdmin(0);
  const [saving, setSaving] = useStateAdmin(false);
  const [message, setMessage] = useStateAdmin("");

  const metrics = [
    { label: "Active subscriptions", value: "1,284", note: "$4.99/month Stripe plan" },
    { label: "Trials active", value: "217", note: "3-day free trial" },
    { label: "Monthly recurring", value: "$6.4K", note: "Estimate from active plans" },
    { label: "Preview listeners", value: "8,902", note: "Free accounts · 30 sec limit" },
  ];

  const streams = [
    ...tracks.slice(0, 4).map((track, index) => ({
      title: track.shortTitle || track.title,
      track,
      count: index === 0 ? "48,219" : index === 1 ? "36,904" : index === 2 ? "21,774" : "18,502",
      delta: index === 0 ? "+12%" : index === 1 ? "+7%" : index === 2 ? "+4%" : "+9%",
    })),
  ];

  const artPreview = artFile ? URL.createObjectURL(artFile) : "";

  const handleAudio = async (file) => {
    setAudioFile(file || null);
    if (!file) return;
    if (!title) setTitle(file.name.replace(/\.[^.]+$/, "").replace(/[-_]+/g, " "));
    setDuration(await readAudioDuration(file));
  };

  const handleSave = async (event) => {
    event.preventDefault();
    if (!audioFile || !title.trim()) {
      setMessage("Add a WAV/MP3 file and song title first.");
      return;
    }
    setSaving(true);
    setMessage("");
    try {
      const saved = await onAddTrack({
        title: title.trim(),
        artist: artist.trim() || "Viral Tension",
        album: album.trim() || "Singles",
        duration,
        audioBlob: audioFile,
        audioName: audioFile.name,
        artBlob: artFile,
        artName: artFile ? artFile.name : "",
        explicit,
      });
      setTitle("");
      setAlbum("Singles");
      setAudioFile(null);
      setArtFile(null);
      setExplicit(false);
      setDuration(0);
      setMessage(`${saved.title} added to your local streaming catalog.`);
    } catch (error) {
      setMessage("That upload did not save. Try a smaller file or a different browser.");
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="admin page" data-screen-label="08 Admin Console">
      <section className="admin-hero glass">
        <div>
          <span className="eyebrow">Admin Console</span>
          <h1 className="admin-title">Catalog Control Room</h1>
          <p className="admin-copy">Manage Viral Tension streaming without turning the public site into a dashboard. Upload songs, attach artwork, watch subscriptions, and track real listening activity.</p>
        </div>
        <div className="admin-actions">
          <button className="btn btn-primary" onClick={() => document.getElementById("song-upload-form").scrollIntoView({ behavior: "smooth" })}><Icon name="plus" size={14} /> Upload New Song</button>
          <button className="btn btn-ghost" onClick={() => onNav("Home")}>View Main Site</button>
        </div>
      </section>

      <section className="admin-metrics">
        {metrics.map((m) => (
          <div key={m.label} className="admin-metric glass">
            <span>{m.label}</span>
            <b>{m.value}</b>
            <small>{m.note}</small>
          </div>
        ))}
      </section>

      <section className="admin-grid">
        <div className="admin-panel glass">
          <div className="section-title"><h2>Song Stream Counts</h2><button className="see-all">Export CSV <Icon name="download" size={12} /></button></div>
          <div className="admin-table">
            {streams.map((s, i) => (
              <button key={s.title} className="admin-row" onClick={() => s.track ? onPlayTrack(s.track) : onNav("Song")}>
                <span className="rank">{String(i + 1).padStart(2, "0")}</span>
                <div className="rart">{s.track ? <TrackArt track={s.track} /> : <Placeholder variant={i === 0 ? "mic" : i === 1 ? "crowd" : i === 2 ? "drive" : "iron"} />}</div>
                <div><strong>{s.title}</strong><small>Viral Tension · full + preview plays</small></div>
                <b>{s.count}</b>
                <em>{s.delta}</em>
              </button>
            ))}
          </div>
        </div>

        <div className="admin-panel glass">
          <div className="section-title"><h2>Upload Pipeline</h2><button className="see-all">{tracks.length} Tracks</button></div>
          <form id="song-upload-form" className="song-upload-form" onSubmit={handleSave}>
            <label>
              <span>Song Title</span>
              <input value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Get Low" />
            </label>
            <label>
              <span>Artist</span>
              <input value={artist} onChange={(e) => setArtist(e.target.value)} placeholder="Viral Tension" />
            </label>
            <label>
              <span>Album / Collection</span>
              <input value={album} onChange={(e) => setAlbum(e.target.value)} placeholder="Singles" />
            </label>

            <label className="file-drop">
              <input type="file" accept="audio/wav,audio/x-wav,audio/mpeg,audio/mp3" onChange={(e) => handleAudio(e.target.files[0])} />
              <Icon name="download" size={22} />
              <b>{audioFile ? audioFile.name : "Choose WAV or MP3"}</b>
              <span>{duration ? `Detected length: ${fmtTime(duration)}` : "Audio file for streaming playback"}</span>
            </label>

            <label className="file-drop art-file-drop">
              <input type="file" accept="image/*" onChange={(e) => setArtFile(e.target.files[0] || null)} />
              {artPreview ? <img src={artPreview} alt="" /> : <Placeholder variant="stage" />}
              <div>
                <b>{artFile ? artFile.name : "Choose Song Art"}</b>
                <span>YouTube thumbnail art works here.</span>
              </div>
            </label>

            <label className="explicit-upload-toggle">
              <input type="checkbox" checked={explicit} onChange={(e) => setExplicit(e.target.checked)} />
              <span>Mark this song as explicit</span>
            </label>

            <button className="btn btn-primary upload-submit" type="submit" disabled={saving}>
              <Icon name="plus" size={14} /> {saving ? "Saving..." : "Add Song to Streaming"}
            </button>
            {message && <div className="admin-note">{message}</div>}
          </form>
          <div className="admin-note">Prototype mode: uploads are saved to this browser for testing. Public customer uploads need backend storage next.</div>
        </div>

        <div className="admin-panel glass wide">
          <div className="section-title"><h2>Subscription State</h2><button className="see-all">Stripe Synced</button></div>
          <div className="subscription-lanes">
            <div><b>Free login</b><span>Can browse and play 30-second previews.</span></div>
            <div><b>Trialing</b><span>3 days full access before $4.99/month billing.</span></div>
            <div><b>Active</b><span>Full streams across signed-in devices.</span></div>
            <div><b>Expired</b><span>Falls back to preview-only access.</span></div>
          </div>
        </div>
      </section>
    </div>
  );
};

window.AdminScreen = AdminScreen;
