/* Single Campaign — wired to live /api/campaigns/:id.
   Returns { campaign, creatives, targets, submissions }. */

function SC_StatusPill({ status }) {
  const map = {
    live:        { label: 'Live',         cls: 'is-live' },
    scheduled:   { label: 'Scheduled',    cls: 'is-scheduled' },
    in_review:   { label: 'In review',    cls: 'is-warn' },
    draft:       { label: 'Draft',        cls: 'is-draft' },
    paused:      { label: 'Paused',       cls: 'is-paused' },
    archived:    { label: 'Archived',     cls: 'is-archived' },
    needs_changes: { label: 'Changes',    cls: 'is-warn' },
  };
  const s = map[status] || { label: status || 'Draft', cls: '' };
  return <span className={`cp-status ${s.cls}`}><span className="cp-status-dot" />{s.label}</span>;
}

function SC_relativeTime(iso) {
  if (!iso) return '—';
  const ageMs = Date.now() - new Date(iso).getTime();
  const m = Math.round(ageMs / 60000);
  if (m < 1) return 'just now';
  if (m < 60) return `${m} min ago`;
  const h = Math.round(m / 60);
  if (h < 24) return `${h} h ago`;
  const d = Math.round(h / 24);
  return `${d} d ago`;
}

/* Review-decision modal — used for both "Request changes" and
   "Reject", which share UX (a note + a submit). The decision string is
   passed through to /api/campaigns/:id/review which expects
   "changes_requested" or "rejected" plus an optional note. */
function ReviewDecisionModal({ open, decision, campaignId, onClose, onDone }) {
  const [note, setNote] = useState('');
  const [busy, setBusy] = useState(false);
  const [err, setErr]   = useState(null);

  useEffect(() => {
    if (!open) return;
    setNote(''); setBusy(false); setErr(null);
  }, [open, decision]);

  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') onClose && onClose(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, onClose]);

  async function submit(e) {
    e && e.preventDefault();
    setBusy(true); setErr(null);
    try {
      await apiFetch(`/api/campaigns/${campaignId}/review`, {
        method: 'POST',
        body: JSON.stringify({ decision, note: note.trim() }),
      });
      if (decision === 'rejected') {
        window.toast && window.toast.warn('Campaign rejected');
      } else {
        window.toast && window.toast.success('Changes requested');
      }
      if (onDone) onDone();
      onClose && onClose();
    } catch (e2) {
      setErr(e2.message);
    } finally {
      setBusy(false);
    }
  }

  if (!open) return null;
  const isReject = decision === 'rejected';
  return (
    <div
      onClick={(e) => { if (e.target === e.currentTarget) onClose && onClose(); }}
      style={{
        position: 'fixed', inset: 0, zIndex: 220,
        background: 'rgba(6, 7, 10, 0.78)', backdropFilter: 'blur(6px)',
        display: 'grid', placeItems: 'center', padding: 24,
      }}
    >
      <form
        onSubmit={submit}
        style={{
          width: 'min(480px, 100%)',
          background: 'var(--aq-surface)',
          border: '1px solid var(--aq-line)',
          borderRadius: 14, boxShadow: 'var(--aq-shadow-2)',
          display: 'flex', flexDirection: 'column', maxHeight: '82vh',
        }}
      >
        <header style={{
          padding: '14px 18px', borderBottom: '1px solid var(--aq-line)',
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <div style={{
            width: 28, height: 28, borderRadius: 8,
            background: isReject ? 'color-mix(in srgb, var(--aq-danger) 20%, transparent)' : 'var(--aq-accent-soft)',
            color: isReject ? 'var(--aq-danger)' : 'var(--aq-accent)',
            display: 'grid', placeItems: 'center',
          }}><Icon name={isReject ? 'close' : 'alert'} size={14} /></div>
          <div style={{ flex: 1 }}>
            <div style={{ fontFamily: 'var(--aq-ff-display)', fontSize: 14.5, color: 'var(--aq-text)', fontWeight: 500 }}>
              {isReject ? 'Reject this campaign' : 'Request changes'}
            </div>
            <div style={{ fontSize: 11.5, color: 'var(--aq-text-faint)' }}>
              {isReject
                ? 'The submitter will see this reason and can resubmit.'
                : 'Tell the submitter what to fix before they resubmit.'}
            </div>
          </div>
          <button type="button" className="aq-icon-btn" onClick={onClose}><Icon name="close" size={13} /></button>
        </header>

        <div style={{ overflowY: 'auto', padding: 16, display: 'flex', flexDirection: 'column', gap: 14 }}>
          <label style={{ display: 'block' }}>
            <div style={{ fontSize: 11.5, color: 'var(--aq-text-dim)', marginBottom: 5 }}>
              {isReject ? 'Reason' : 'What changes are needed'}
            </div>
            <textarea
              autoFocus rows={5} maxLength={1000}
              value={note} onChange={(e) => setNote(e.target.value)}
              placeholder={isReject
                ? 'IUCN status conflict — please double-check and rebuild from a Vulnerable variant.'
                : 'Reduce the body copy to two lines and tighten the CTA wording.'}
              style={{
                width: '100%', padding: '8px 10px', fontSize: 13,
                background: 'var(--aq-surface-2)', border: '1px solid var(--aq-line)',
                borderRadius: 7, color: 'var(--aq-text)', font: 'inherit', outline: 0,
                resize: 'vertical',
              }}
            />
          </label>

          {err && (
            <div style={{
              padding: '8px 10px', borderRadius: 6,
              background: 'color-mix(in srgb, var(--aq-danger) 12%, transparent)',
              color: 'var(--aq-danger)', fontSize: 12,
            }}>{err}</div>
          )}
        </div>

        <footer style={{
          padding: '10px 16px', borderTop: '1px solid var(--aq-line)',
          background: 'var(--aq-surface-2)',
          display: 'flex', justifyContent: 'flex-end', gap: 8,
        }}>
          <button type="button" className="x-btn ghost" onClick={onClose}>Cancel</button>
          <button
            type="submit"
            className={isReject ? 'x-btn is-danger' : 'x-btn'}
            disabled={busy}
          >
            {busy
              ? (isReject ? 'Rejecting…' : 'Sending…')
              : (isReject ? 'Reject campaign' : 'Send change request')}
          </button>
        </footer>
      </form>
    </div>
  );
}

function SingleCampaignScreen({ param }) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  /* Review modal — null when closed, else { decision: 'rejected' | 'changes_requested' }. */
  const [reviewModal, setReviewModal] = useState(null);

  useEffect(() => {
    if (!param) return;
    let cancelled = false;
    setLoading(true);
    apiFetch(`/api/campaigns/${encodeURIComponent(param)}`)
      .then((res) => {
        if (cancelled) return;
        setData(res);
        setLoading(false);
      })
      .catch((err) => {
        if (cancelled) return;
        setError(err.message);
        setLoading(false);
      });
    return () => { cancelled = true; };
  }, [param]);

  if (loading) {
    return (
      <div className="aq-content">
        <div style={{ padding: 60, textAlign: 'center', color: 'var(--aq-text-faint)' }}>
          Loading campaign…
        </div>
      </div>
    );
  }

  if (error || !data || !data.campaign) {
    return (
      <div className="aq-content">
        <div className="x-err-stage" style={{ minHeight: 280 }}>
          <div className="x-err-card">
            <div className="x-err-code">Campaign not found</div>
            <div className="x-err-glyph is-warn"><Icon name="alert" size={28} /></div>
            <h1 className="x-err-headline">{param || '—'}</h1>
            <p className="x-err-body">{error || 'No campaign with this ID.'}</p>
            <div className="x-err-actions">
              <button className="x-btn ghost" onClick={() => { window.location.hash = '#campaigns'; }}>
                Back to campaigns
              </button>
            </div>
          </div>
        </div>
      </div>
    );
  }

  const c = data.campaign;
  const creatives = data.creatives || [];
  const targets = data.targets || [];
  const submissions = data.submissions || [];
  const thumb = c.thumb_gradient || `linear-gradient(135deg, ${c.accent_color || '#1a3d5f'}, oklch(0.20 0.06 220))`;

  return (
    <div className="aq-content">
      <div className="aq-content-inner" style={{ maxWidth: 1100 }}>
        <section className="sc-hero">
          <div className="sc-hero-thumb" style={{ background: thumb }}>
            <span className="sc-hero-glyph">{(c.name || '?')[0].toUpperCase()}</span>
          </div>
          <div className="sc-hero-body">
            <div className="aq-eyebrow">
              <span>{c.objective || c.mode || 'Campaign'}</span>
              <span className="aq-sep">·</span>
              <span>{c.layout_id || 'Custom layout'}</span>
              <span className="aq-sep">·</span>
              <span style={{ fontFamily: 'var(--aq-ff-mono)', fontSize: 10.5 }}>ID {(c.id || '').slice(0, 8)}</span>
            </div>
            <h1 style={{ marginTop: 12, fontSize: 28, letterSpacing: '-0.02em', color: 'var(--aq-text)' }}>{c.name}</h1>
            <div className="aq-hero-meta" style={{ marginTop: 10, gap: 12 }}>
              <SC_StatusPill status={c.status} />
              <span className="aq-sep">·</span>
              <span>
                {c.starts_at ? new Date(c.starts_at).toLocaleDateString() : '—'}
                {c.ends_at && <> → {new Date(c.ends_at).toLocaleDateString()}</>}
              </span>
              <span className="aq-sep">·</span>
              <span>{c.site_name || 'All sites'}</span>
            </div>
          </div>
          <div className="sc-hero-actions">
            <button
              className="aq-pa-pill"
              onClick={() => { window.location.hash = `#audit?entity_type=campaign&entity_id=${c.id}`; }}
            ><Icon name="chart" size={13} />Audit</button>
            {Auth.canEditCampaigns() && (
              <button
                className="aq-pa-pill"
                onClick={() => { window.location.hash = `#campaign-edit/${c.id}`; }}
              ><Icon name="settings" size={13} />Edit</button>
            )}
            {window.CP_APPROVALS_ENABLED && c.status === 'in_review' && Auth.canApprove() && (
              <>
                <button
                  className="aq-pa-pill"
                  onClick={() => setReviewModal({ decision: 'changes_requested' })}
                ><Icon name="alert" size={13} />Request changes</button>
                <button
                  className="aq-pa-pill"
                  style={{ color: 'var(--aq-danger)' }}
                  onClick={() => setReviewModal({ decision: 'rejected' })}
                ><Icon name="close" size={13} />Reject</button>
                <button
                  className="cp-new-main"
                  onClick={async () => {
                    if (!window.confirm('Approve & publish this campaign?')) return;
                    try {
                      await apiFetch(`/api/campaigns/${c.id}/review`, {
                        method: 'POST',
                        body: JSON.stringify({ decision: 'approved' }),
                      });
                      window.toast && window.toast.success('Campaign approved');
                      window.location.reload();
                    } catch (err) {
                      window.toast && window.toast.danger(`Approve failed: ${err.message}`);
                    }
                  }}
                ><Icon name="check" size={13} />Approve & publish</button>
              </>
            )}
          </div>
        </section>

        <div className="aq-pa-kpis" style={{ gridTemplateColumns: 'repeat(4, 1fr)' }}>
          <div className="aq-pa-kpi">
            <div className="aq-pa-kpi-label">Creatives</div>
            <div className="aq-pa-kpi-value-row"><div className="aq-pa-kpi-value">{creatives.length}</div></div>
            <div className="aq-pa-kpi-sub">{creatives.filter((cr) => cr.is_active).length} active</div>
          </div>
          <div className="aq-pa-kpi">
            <div className="aq-pa-kpi-label">Targets</div>
            <div className="aq-pa-kpi-value-row"><div className="aq-pa-kpi-value">{targets.length}</div></div>
            <div className="aq-pa-kpi-sub">screen / zone targets</div>
          </div>
          <div className="aq-pa-kpi">
            <div className="aq-pa-kpi-label">Priority</div>
            <div className="aq-pa-kpi-value-row"><div className="aq-pa-kpi-value">{c.priority || 0}</div></div>
            <div className="aq-pa-kpi-sub">rotation slot</div>
          </div>
          <div className="aq-pa-kpi">
            <div className="aq-pa-kpi-label">Last updated</div>
            <div className="aq-pa-kpi-value-row">
              <div className="aq-pa-kpi-value" style={{ fontSize: 18 }}>{SC_relativeTime(c.updated_at)}</div>
            </div>
            <div className="aq-pa-kpi-sub">
              {c.created_at ? `created ${new Date(c.created_at).toLocaleDateString()}` : ''}
            </div>
          </div>
        </div>

        <section className="aq-pa-card" style={{ padding: 18 }}>
          <h2 style={{
            margin: '0 0 12px', fontFamily: 'var(--aq-ff-display)',
            fontSize: 14, fontWeight: 500, color: 'var(--aq-text)',
          }}>Creatives</h2>
          {creatives.length === 0 ? (
            <div style={{ color: 'var(--aq-text-faint)', fontSize: 12.5, padding: '20px 0' }}>
              No creatives yet — open the editor to add one.
            </div>
          ) : (
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10 }}>
              {creatives.map((cr) => (
                <div key={cr.id} style={{
                  aspectRatio: '16/10',
                  background: thumb,
                  borderRadius: 6,
                  display: 'grid', placeItems: 'center',
                  color: 'rgba(255,255,255,0.85)', fontSize: 12,
                  fontFamily: 'var(--aq-ff-display)',
                  position: 'relative',
                }}>
                  <span>{cr.name || cr.layout_id || `v${cr.version}`}</span>
                  {!cr.is_active && (
                    <span style={{
                      position: 'absolute', top: 6, left: 6,
                      fontSize: 9, padding: '1px 5px',
                      background: 'rgba(0,0,0,0.5)', color: 'rgba(255,255,255,0.7)',
                      borderRadius: 3, letterSpacing: '0.04em',
                      fontFamily: 'var(--aq-ff-mono)',
                    }}>INACTIVE</span>
                  )}
                </div>
              ))}
            </div>
          )}
        </section>

        <section className="aq-pa-card" style={{ padding: 18 }}>
          <h2 style={{
            margin: '0 0 12px', fontFamily: 'var(--aq-ff-display)',
            fontSize: 14, fontWeight: 500, color: 'var(--aq-text)',
          }}>Audit trail</h2>
          {submissions.length === 0 ? (
            <div style={{ color: 'var(--aq-text-faint)', fontSize: 12.5, padding: '8px 0' }}>
              No review submissions yet.
            </div>
          ) : (
            <ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: 8 }}>
              {submissions.map((s) => (
                <li key={s.id} style={{ display: 'flex', gap: 12, fontSize: 12.5, color: 'var(--aq-text-dim)' }}>
                  <span style={{ width: 100, color: 'var(--aq-text-faint)', fontFamily: 'var(--aq-ff-mono)' }}>
                    {SC_relativeTime(s.submitted_at)}
                  </span>
                  <span>
                    <b style={{ color: 'var(--aq-text)' }}>{s.submitted_by_name || 'Someone'}</b>
                    {' '}submitted for review
                    {s.reviewed_at && (
                      <> · <b style={{ color: s.decision === 'approved' ? 'var(--aq-success)' : 'var(--aq-warn)' }}>
                        {s.reviewed_by_name || 'reviewer'}
                      </b> {s.decision || 'reviewed'}</>
                    )}
                  </span>
                </li>
              ))}
            </ul>
          )}
        </section>
      </div>

      <ReviewDecisionModal
        open={reviewModal != null}
        decision={reviewModal && reviewModal.decision}
        campaignId={c && c.id}
        onClose={() => setReviewModal(null)}
        onDone={() => {
          /* Re-pull the campaign so status / pill / submission rows
             rehydrate without a hard reload. */
          if (param) {
            apiFetch(`/api/campaigns/${encodeURIComponent(param)}`)
              .then((res) => setData(res))
              .catch(() => { /* surface keeps stale data */ });
          }
        }}
      />
    </div>
  );
}

window.SingleCampaignScreen = SingleCampaignScreen;
