// BroadcastsScreen.jsx — simple notice board. Each broadcast is a short text.
// Tapping a broadcast opens a multi-staff ack picker. Acks render as avatars on the card.

const { useState: useBc, useEffect: useBcEffect, useMemo: useBcMemo } = React;

// ------------------------------------------------------------------
// Audio — synthesize a gentle two-tone chime (no external files)
// ------------------------------------------------------------------
function playBroadcastSound() {
  try {
    const Ctx = window.AudioContext || window.webkitAudioContext;
    if (!Ctx) return;
    const ctx = new Ctx();
    const now = ctx.currentTime;
    const notes = [660, 880];
    const dur = 0.28;
    notes.forEach((freq, i) => {
      const osc = ctx.createOscillator();
      const gain = ctx.createGain();
      osc.type = 'sine';
      osc.frequency.value = freq;
      const start = now + i * (dur + 0.05);
      gain.gain.setValueAtTime(0, start);
      gain.gain.linearRampToValueAtTime(0.22, start + 0.02);
      gain.gain.exponentialRampToValueAtTime(0.001, start + dur);
      osc.connect(gain);
      gain.connect(ctx.destination);
      osc.start(start);
      osc.stop(start + dur + 0.05);
    });
    setTimeout(() => ctx.close(), 2500);
  } catch { /* noop */ }
}

// ------------------------------------------------------------------
// Format "just now / 12m ago / Tue"
// ------------------------------------------------------------------
function fmtAgo(iso) {
  const d = new Date(iso);
  const diffMin = Math.round((Date.now() - d.getTime()) / 60000);
  if (diffMin < 1) return 'Just now';
  if (diffMin < 60) return `${diffMin} min ago`;
  if (diffMin < 60 * 24) return `${Math.round(diffMin / 60)}h ago`;
  const days = Math.round(diffMin / (60 * 24));
  if (days < 7) return `${days}d ago`;
  return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
}

// ------------------------------------------------------------------
// Arrival overlay — full screen, single tap to dismiss
// ------------------------------------------------------------------
const BroadcastArrival = ({ broadcast, onAcknowledge }) => {
  const [phase, setPhase] = useBc(0);
  const [elapsed, setElapsed] = useBc(0);
  const [mounted, setMounted] = useBc(false);

  useBcEffect(() => {
    // Trigger fade-in after mount
    const raf = requestAnimationFrame(() => setMounted(true));
    const flashLoop = setInterval(() => setPhase(p => (p + 1) % 2), 700);
    const tickStart = Date.now();
    const tick = setInterval(() => setElapsed(Math.floor((Date.now() - tickStart) / 1000)), 1000);
    return () => { cancelAnimationFrame(raf); clearInterval(flashLoop); clearInterval(tick); };
  }, [broadcast.id]);

  const colorA = '#1D4ED8';
  const colorB = '#1E40AF';

  // Look up sender — broadcasts from portal set senderName directly
  const senderName = broadcast.senderName
    || (broadcast.senderId && window.SAMPLE_STAFF?.find(s => s.id === broadcast.senderId)?.name)
    || 'Web portal';

  return (
    <div className="bc-arrival-root" style={{
      position: 'absolute', inset: 0, zIndex: 900,
      background: phase === 0 ? colorA : colorB,
      transition: 'background 400ms var(--ease-snap), opacity 260ms ease-out, transform 260ms ease-out',
      color: '#FFFFFF',
      display: 'flex', flexDirection: 'column',
      padding: '64px 56px 52px',
      overflow: 'hidden',
      opacity: mounted ? 1 : 0,
      transform: mounted ? 'scale(1)' : 'scale(0.97)',
    }}>
      <style>{`
        @keyframes bcDotPulse {
          0%, 100% { transform: scale(1); opacity: 1; }
          50% { transform: scale(1.5); opacity: 0.6; }
        }
        @keyframes bcRipple {
          0% { transform: scale(0.9); opacity: 0.5; }
          100% { transform: scale(2.4); opacity: 0; }
        }
      `}</style>

      {/* Decorative rings behind content */}
      <div style={{
        position: 'absolute', top: -200, right: -200,
        width: 520, height: 520, borderRadius: '50%',
        border: '1px solid rgba(255,255,255,0.12)',
        pointerEvents: 'none',
      }} />
      <div style={{
        position: 'absolute', top: -120, right: -120,
        width: 360, height: 360, borderRadius: '50%',
        border: '1px solid rgba(255,255,255,0.10)',
        pointerEvents: 'none',
      }} />

      {/* Top row: label + time */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 14,
        position: 'relative', zIndex: 1,
      }}>
        <div style={{ position: 'relative', width: 14, height: 14 }}>
          <div style={{
            position: 'absolute', inset: 0, borderRadius: 999,
            background: '#FFFFFF',
            animation: 'bcDotPulse 1.2s ease-in-out infinite',
          }} />
          <div style={{
            position: 'absolute', inset: 0, borderRadius: 999,
            background: 'rgba(255,255,255,0.4)',
            animation: 'bcRipple 1.6s ease-out infinite',
          }} />
        </div>
        <div style={{
          fontSize: 13, fontWeight: 700, letterSpacing: '0.18em',
          textTransform: 'uppercase',
        }}>
          New broadcast
        </div>
        <div style={{ flex: 1 }} />
        <div style={{
          fontSize: 12, fontWeight: 500, letterSpacing: '0.08em',
          textTransform: 'uppercase', opacity: 0.7,
        }}>
          {elapsed < 60 ? `${elapsed}s ago` : `${Math.floor(elapsed/60)}m ago`}
        </div>
      </div>

      {/* Divider */}
      <div style={{
        height: 1, background: 'rgba(255,255,255,0.18)',
        marginTop: 22, marginBottom: 28,
        position: 'relative', zIndex: 1,
      }} />

      {/* Sender */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 12,
        fontSize: 15, fontWeight: 500, opacity: 0.85,
        position: 'relative', zIndex: 1,
      }}>
        <Icon name="send" size={14} color="rgba(255,255,255,0.75)" strokeWidth={2} />
        <span>From <strong style={{ fontWeight: 700, opacity: 1 }}>{senderName}</strong></span>
      </div>

      {/* Body */}
      <div style={{
        flex: 1,
        display: 'flex', flexDirection: 'column', justifyContent: 'center',
        paddingRight: 20,
        position: 'relative', zIndex: 1,
      }}>
        <div style={{
          fontSize: 56, fontWeight: 500,
          letterSpacing: '-0.03em', lineHeight: 1.12,
          textWrap: 'balance',
          maxWidth: 640,
        }}>
          {broadcast.body}
        </div>
      </div>

      {/* Hint */}
      <div style={{
        fontSize: 14, fontWeight: 500, opacity: 0.75,
        marginBottom: 16, textAlign: 'center',
        letterSpacing: '-0.005em',
        position: 'relative', zIndex: 1,
      }}>
        Acknowledge to confirm who has read this
      </div>

      {/* CTA */}
      <button onClick={onAcknowledge} style={{
        width: '100%', height: 88,
        borderRadius: 20,
        background: '#FFFFFF',
        color: '#1E3A8A',
        fontSize: 24, fontWeight: 600,
        letterSpacing: '-0.01em',
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 12,
        cursor: 'pointer',
        boxShadow: '0 12px 32px rgba(0,0,0,0.25)',
        border: 'none',
        position: 'relative', zIndex: 1,
      }}>
        <Icon name="check" size={24} color="#1E3A8A" strokeWidth={2.4} />
        Acknowledge
      </button>
    </div>
  );
};

// ------------------------------------------------------------------
// Single broadcast card
// ------------------------------------------------------------------
const BroadcastCard = ({ broadcast, onOpenAck }) => {
  const acks = broadcast.acks || [];
  const ackedStaff = acks
    .map(a => window.SAMPLE_STAFF.find(s => s.id === a.staffId))
    .filter(Boolean);

  return (
    <button
      onClick={() => onOpenAck(broadcast)}
      style={{
        textAlign: 'left',
        background: '#FFFFFF',
        borderRadius: 16,
        border: '1px solid var(--border-1)',
        padding: '20px 22px',
        display: 'flex', flexDirection: 'column', gap: 14,
        cursor: 'pointer',
        transition: 'transform 120ms var(--ease-snap), border-color 120ms var(--ease-snap)',
      }}
      onMouseDown={e => { e.currentTarget.style.transform = 'scale(0.995)'; }}
      onMouseUp={e => { e.currentTarget.style.transform = ''; }}
      onMouseLeave={e => { e.currentTarget.style.transform = ''; }}
    >
      {/* The body is the whole thing — large, readable, balanced */}
      <div style={{
        fontSize: 22, fontWeight: 500,
        lineHeight: 1.35, letterSpacing: '-0.01em',
        color: 'var(--fg-1)',
        textWrap: 'pretty',
      }}>
        {broadcast.body}
      </div>

      {/* Footer: time + ack avatars */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 14,
        paddingTop: 12,
        borderTop: '1px solid var(--border-1)',
      }}>
        <div style={{ fontSize: 12, color: 'var(--fg-3)', fontWeight: 500 }}>
          {fmtAgo(broadcast.sentAt)}
        </div>
        <div style={{ flex: 1 }} />
        {ackedStaff.length > 0 ? (
          <div style={{ display: 'inline-flex', alignItems: 'center', gap: -6 }}>
            <div style={{ display: 'inline-flex', alignItems: 'center' }}>
              {ackedStaff.slice(0, 6).map((s, i) => (
                <div key={s.id} style={{
                  marginLeft: i === 0 ? 0 : -8,
                  border: '2px solid #FFFFFF',
                  borderRadius: 999,
                  zIndex: ackedStaff.length - i,
                  position: 'relative',
                }}>
                  <Avatar staff={s} size={28} />
                </div>
              ))}
              {ackedStaff.length > 6 && (
                <div style={{
                  marginLeft: -8,
                  width: 28, height: 28, borderRadius: 999,
                  background: 'var(--bg-sunken)',
                  color: 'var(--fg-2)',
                  fontSize: 11, fontWeight: 600,
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                  border: '2px solid #FFFFFF',
                }}>+{ackedStaff.length - 6}</div>
              )}
            </div>
            <span style={{ marginLeft: 10, fontSize: 12, color: 'var(--fg-3)', fontWeight: 500 }}>
              seen
            </span>
          </div>
        ) : (
          <div style={{
            display: 'inline-flex', alignItems: 'center', gap: 8,
            padding: '6px 12px', borderRadius: 999,
            background: '#EFF6FF', color: '#1D4ED8',
            fontSize: 12, fontWeight: 600,
          }}>
            <Icon name="plus" size={12} color="#1D4ED8" strokeWidth={2.2} />
            Tap to acknowledge
          </div>
        )}
      </div>
    </button>
  );
};

// ------------------------------------------------------------------
// Ack picker — multi-select staff who've seen this
// ------------------------------------------------------------------
const AckPicker = ({ open, onClose, broadcast, onSave }) => {
  if (!broadcast) return null;
  const alreadyAckedIds = (broadcast.acks || []).map(a => a.staffId);
  return (
    <StaffMultiPicker
      open={open}
      onClose={onClose}
      selectedIds={alreadyAckedIds}
      lockedIds={alreadyAckedIds}
      onSave={onSave}
      title="Who's seen this?"
      saveLabel="Mark acknowledged"
      subtitle="Select everyone who has read this broadcast"
    />
  );
};

// ------------------------------------------------------------------
// Main screen
// ------------------------------------------------------------------
const BroadcastsScreen = ({ broadcasts, setBroadcasts, currentStaff, showToast }) => {
  const [ackFor, setAckFor] = useBc(null);

  // Sort newest first
  const sorted = useBcMemo(
    () => [...broadcasts].sort((a, b) => new Date(b.sentAt) - new Date(a.sentAt)),
    [broadcasts]
  );

  const addAcks = (broadcastId, staffIds) => {
    const at = new Date().toISOString();
    setBroadcasts(prev => prev.map(b => {
      if (b.id !== broadcastId) return b;
      const existing = new Set((b.acks || []).map(a => a.staffId));
      const merged = [...(b.acks || [])];
      staffIds.forEach(id => {
        if (!existing.has(id)) merged.push({ staffId: id, at });
      });
      return { ...b, acks: merged };
    }));
  };

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', position: 'relative' }}>
      {/* Header */}
      <div style={{
        padding: '16px 24px 14px',
        background: 'var(--bg-surface)',
        borderBottom: '1px solid var(--border-1)',
      }}>
        <div style={{ fontSize: 11, color: 'var(--fg-3)', fontWeight: 500, letterSpacing: '0.06em', textTransform: 'uppercase' }}>
          From the web portal
        </div>
        <div style={{ fontSize: 22, fontWeight: 600, letterSpacing: '-0.02em', color: 'var(--fg-1)', marginTop: 2, lineHeight: 1.1 }}>
          Broadcasts
        </div>
      </div>

      {/* List */}
      <div className="scroll-soft" style={{
        flex: 1, overflowY: 'auto',
        padding: '16px 24px 28px',
        display: 'flex', flexDirection: 'column', gap: 12,
      }}>
        {sorted.length === 0 ? (
          <div style={{
            flex: 1, display: 'flex', flexDirection: 'column',
            alignItems: 'center', justifyContent: 'center',
            padding: 40,
            color: 'var(--fg-3)', textAlign: 'center',
          }}>
            <Icon name="megaphone" size={48} color="var(--fg-3)" strokeWidth={1.4} />
            <div style={{ fontSize: 16, fontWeight: 500, color: 'var(--fg-2)', marginTop: 12 }}>
              No broadcasts yet
            </div>
            <div style={{ fontSize: 13, color: 'var(--fg-3)', marginTop: 4 }}>
              Messages from the web portal will appear here
            </div>
          </div>
        ) : sorted.map(b => (
          <BroadcastCard
            key={b.id}
            broadcast={b}
            onOpenAck={(bc) => setAckFor(bc)}
          />
        ))}
      </div>

      <AckPicker
        open={!!ackFor}
        onClose={() => setAckFor(null)}
        broadcast={ackFor}
        onSave={(ids) => {
          if (ackFor) {
            const newAcks = ids.filter(id => !(ackFor.acks || []).some(a => a.staffId === id));
            addAcks(ackFor.id, ids);
            if (newAcks.length > 0) {
              const names = newAcks.map(id => window.SAMPLE_STAFF.find(s => s.id === id)?.name).filter(Boolean);
              showToast({
                message: newAcks.length === 1
                  ? `${names[0]} acknowledged`
                  : `${newAcks.length} acknowledged`,
                icon: 'check',
              });
            }
          }
          setAckFor(null);
        }}
      />

    </div>
  );
};

Object.assign(window, { BroadcastsScreen, BroadcastArrival, playBroadcastSound });
