// NewsScreen.jsx — AegisComply
// Full feed of product announcements + system updates broadcast by master.
// Reads from public.announcements (set up by supabase/07_announcements.sql)
// and per-user read state from public.announcement_reads.

const NEWS_SEVERITIES = {
  info:     { label: 'Update',   color: '#0EA5E9', bg: '#F0F9FF', border: '#BAE6FD' },
  feature:  { label: 'New',      color: '#0D9488', bg: '#F0FDFA', border: '#A7F3D0' },
  warning:  { label: 'Heads up', color: '#D97706', bg: '#FFFBEB', border: '#FDE68A' },
  critical: { label: 'Critical', color: '#DC2626', bg: '#FEF2F2', border: '#FECACA' },
};

function newsSev(sev) {
  return NEWS_SEVERITIES[sev] || NEWS_SEVERITIES.info;
}

function fmtNewsDate(d) {
  if (!d) return '—';
  try {
    const date = new Date(d);
    const now  = new Date();
    const diffMs = now - date;
    const diffMin = Math.floor(diffMs / 60000);
    if (diffMin < 1) return 'Just now';
    if (diffMin < 60) return `${diffMin} min ago`;
    const diffHr = Math.floor(diffMin / 60);
    if (diffHr < 24) return `${diffHr}h ago`;
    const diffDay = Math.floor(diffHr / 24);
    if (diffDay < 7) return `${diffDay}d ago`;
    return date.toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' });
  } catch { return d; }
}
function fmtNewsExact(d) {
  if (!d) return '';
  try { return new Date(d).toLocaleString('en-GB', { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit' }); }
  catch { return ''; }
}

const newsStyles = {
  page: { padding: 24, maxWidth: 880 },
  header: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 18, gap: 16, flexWrap: 'wrap' },
  intro: { fontSize: 13, color: '#64748B', lineHeight: 1.55, maxWidth: 560 },
  filterRow: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 18, flexWrap: 'wrap' },
  filterPill: { height: 32, padding: '0 14px', border: '1px solid #CBD5E1', borderRadius: 18, fontSize: 12, fontWeight: 600, color: '#475569', background: 'white', cursor: 'pointer', fontFamily: "'DM Sans',sans-serif" },
  filterPillActive: { background: '#0F172A', color: 'white', borderColor: '#0F172A' },
  markAllBtn: { height: 32, padding: '0 14px', border: '1px solid #CBD5E1', borderRadius: 6, background: 'white', fontSize: 12, fontWeight: 600, color: '#475569', cursor: 'pointer', fontFamily: "'DM Sans',sans-serif", display: 'inline-flex', alignItems: 'center', gap: 6, marginLeft: 'auto' },
  markAllBtnDisabled: { color: '#94A3B8', cursor: 'not-allowed' },
  feed: { display: 'flex', flexDirection: 'column', gap: 12 },
  card: { background: 'white', border: '1px solid #E2E8F0', borderRadius: 10, padding: '18px 20px', position: 'relative', transition: 'all 150ms', boxShadow: '0 1px 3px rgba(0,0,0,0.03)' },
  cardUnread: { borderLeft: '4px solid #0D9488', boxShadow: '0 2px 6px rgba(13,148,136,0.10)' },
  cardRow: { display: 'flex', alignItems: 'flex-start', gap: 14 },
  sevBadge: { display: 'inline-flex', alignItems: 'center', gap: 6, padding: '4px 10px', borderRadius: 100, fontSize: 11, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase' },
  unreadDot: { width: 8, height: 8, borderRadius: '50%', background: '#0D9488', display: 'inline-block' },
  title: { fontFamily: "'Helvetica',Arial,sans-serif", fontSize: 17, fontWeight: 700, color: '#0F172A', marginBottom: 6, lineHeight: 1.3 },
  meta: { fontSize: 11, color: '#94A3B8', display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12 },
  body: { fontSize: 14, color: '#334155', lineHeight: 1.6, whiteSpace: 'pre-wrap', wordBreak: 'break-word' },
  ctaRow: { display: 'flex', gap: 8, marginTop: 14, alignItems: 'center', flexWrap: 'wrap' },
  ctaBtn: { display: 'inline-flex', alignItems: 'center', gap: 6, padding: '8px 14px', borderRadius: 6, background: '#0D9488', color: 'white', fontSize: 12, fontWeight: 700, textDecoration: 'none', fontFamily: "'DM Sans',sans-serif", cursor: 'pointer', border: 'none' },
  markReadBtn: { padding: '6px 12px', borderRadius: 6, background: 'transparent', border: '1px solid #E2E8F0', color: '#64748B', fontSize: 11, fontWeight: 600, cursor: 'pointer', fontFamily: "'DM Sans',sans-serif" },
  // Empty state
  empty: { padding: 60, textAlign: 'center', border: '2px dashed #E2E8F0', borderRadius: 12, background: 'white' },
  emptyIcon: { width: 60, height: 60, borderRadius: 12, background: '#F1F5F9', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', marginBottom: 14, color: '#94A3B8' },
  emptyTitle: { fontSize: 16, fontWeight: 700, color: '#334155', marginBottom: 6 },
  emptySub: { fontSize: 13, color: '#94A3B8', maxWidth: 420, marginLeft: 'auto', marginRight: 'auto', lineHeight: 1.5 },
  errorBox: { background: '#FFF5F5', border: '1px solid #FECACA', borderRadius: 6, padding: '10px 14px', fontSize: 12, color: '#DC2626', marginBottom: 14 },
};

function NewsScreen({ user }) {
  const [items, setItems]       = React.useState([]);
  const [reads, setReads]       = React.useState(new Set());
  const [loading, setLoading]   = React.useState(false);
  const [error, setError]       = React.useState('');
  const [filter, setFilter]     = React.useState('all'); // 'all' | 'unread' | severity id

  const fetchAll = React.useCallback(async () => {
    if (!user) return;
    setLoading(true); setError('');
    try {
      const sb = window.supabaseClient;
      const [annR, readR] = await Promise.all([
        sb.from('announcements').select('*').order('published_at', { ascending: false }).limit(100),
        sb.from('announcement_reads').select('announcement_id').eq('user_id', user.id),
      ]);
      if (annR.error) throw annR.error;
      if (readR.error) throw readR.error;
      setItems(annR.data || []);
      setReads(new Set((readR.data || []).map(r => r.announcement_id)));
    } catch (err) {
      console.error('[News] fetch error:', err);
      setError(err.message);
    } finally {
      setLoading(false);
    }
  }, [user]);

  React.useEffect(() => { fetchAll(); }, [fetchAll]);

  // Live updates — new announcements + new reads
  React.useEffect(() => {
    if (!user) return;
    const sb = window.supabaseClient;
    if (!sb) return;
    const ch = sb.channel(`news-${user.id}`)
      .on('postgres_changes', { event: '*', schema: 'public', table: 'announcements' }, () => fetchAll())
      .on('postgres_changes', { event: '*', schema: 'public', table: 'announcement_reads', filter: `user_id=eq.${user.id}` }, () => fetchAll())
      .subscribe();
    return () => { sb.removeChannel(ch); };
  }, [user, fetchAll]);

  const markRead = async (announcementId) => {
    if (!user || reads.has(announcementId)) return;
    try {
      const sb = window.supabaseClient;
      const { error: insErr } = await sb.from('announcement_reads').insert({ user_id: user.id, announcement_id: announcementId });
      if (insErr && !/duplicate/i.test(insErr.message || '')) throw insErr;
      setReads(prev => new Set(prev).add(announcementId));
    } catch (err) {
      console.warn('[News] mark read failed:', err);
    }
  };

  const markAllRead = async () => {
    if (!user) return;
    const unreadIds = items.filter(it => !reads.has(it.id)).map(it => it.id);
    if (unreadIds.length === 0) return;
    try {
      const sb = window.supabaseClient;
      const rows = unreadIds.map(id => ({ user_id: user.id, announcement_id: id }));
      const { error: insErr } = await sb.from('announcement_reads').insert(rows);
      if (insErr && !/duplicate/i.test(insErr.message || '')) throw insErr;
      setReads(prev => {
        const next = new Set(prev);
        unreadIds.forEach(id => next.add(id));
        return next;
      });
    } catch (err) {
      console.warn('[News] mark all read failed:', err);
      alert('Could not mark all as read: ' + err.message);
    }
  };

  const counts = React.useMemo(() => {
    const c = { all: items.length, unread: 0, info: 0, feature: 0, warning: 0, critical: 0 };
    items.forEach(it => {
      c[it.severity] = (c[it.severity] || 0) + 1;
      if (!reads.has(it.id)) c.unread++;
    });
    return c;
  }, [items, reads]);

  const visible = React.useMemo(() => items.filter(it => {
    if (filter === 'all')     return true;
    if (filter === 'unread')  return !reads.has(it.id);
    return it.severity === filter;
  }), [items, reads, filter]);

  return (
    <div style={newsStyles.page}>
      <div style={newsStyles.header}>
        <div>
          <div style={{ fontFamily: "'Helvetica',Arial,sans-serif", fontSize: 22, fontWeight: 700, color: '#0F172A', marginBottom: 4 }}>What's new</div>
          <div style={newsStyles.intro}>Product updates, feature releases, scheduled maintenance and important notices from the AegisComply team.</div>
        </div>
      </div>

      <div style={newsStyles.filterRow}>
        {[
          { id: 'all',      label: `All (${counts.all})` },
          { id: 'unread',   label: `Unread (${counts.unread})` },
          { id: 'feature',  label: `New (${counts.feature || 0})` },
          { id: 'info',     label: `Updates (${counts.info || 0})` },
          { id: 'warning',  label: `Heads up (${counts.warning || 0})` },
          { id: 'critical', label: `Critical (${counts.critical || 0})` },
        ].map(p => (
          <button
            key={p.id}
            style={{ ...newsStyles.filterPill, ...(filter === p.id ? newsStyles.filterPillActive : {}) }}
            onClick={() => setFilter(p.id)}
          >{p.label}</button>
        ))}
        <button
          style={{ ...newsStyles.markAllBtn, ...(counts.unread === 0 ? newsStyles.markAllBtnDisabled : {}) }}
          onClick={markAllRead}
          disabled={counts.unread === 0}
        >
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
          Mark all as read
        </button>
      </div>

      {error && <div style={newsStyles.errorBox}>{error}</div>}

      {loading && items.length === 0 ? (
        <div style={{ padding: 40, textAlign: 'center', color: '#94A3B8' }}>Loading news…</div>
      ) : visible.length === 0 ? (
        <div style={newsStyles.empty}>
          <div style={newsStyles.emptyIcon}>
            <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1"/></svg>
          </div>
          <div style={newsStyles.emptyTitle}>
            {filter === 'all' ? 'No announcements yet' : 'No items match this filter'}
          </div>
          <div style={newsStyles.emptySub}>
            {filter === 'all'
              ? 'Product updates and important notices from the AegisComply team will show up here.'
              : 'Try a different filter.'}
          </div>
        </div>
      ) : (
        <div style={newsStyles.feed}>
          {visible.map(it => {
            const isUnread = !reads.has(it.id);
            const sev = newsSev(it.severity);
            return (
              <div
                key={it.id}
                style={{ ...newsStyles.card, ...(isUnread ? newsStyles.cardUnread : {}) }}
                onMouseEnter={() => isUnread && markRead(it.id)}
              >
                <div style={newsStyles.cardRow}>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 8, flexWrap: 'wrap' }}>
                      <span style={{ ...newsStyles.sevBadge, background: sev.bg, color: sev.color, border: `1px solid ${sev.border}` }}>{sev.label}</span>
                      {isUnread && <span style={newsStyles.unreadDot} title="Unread"/>}
                    </div>
                    <div style={newsStyles.title}>{it.title}</div>
                    <div style={newsStyles.meta} title={fmtNewsExact(it.published_at)}>
                      <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
                      {fmtNewsDate(it.published_at)}
                      <span style={{ color: '#CBD5E1' }}>·</span>
                      <span>{fmtNewsExact(it.published_at)}</span>
                    </div>
                    <div style={newsStyles.body}>{it.body}</div>
                    <div style={newsStyles.ctaRow}>
                      {it.link_url && (
                        <a
                          href={it.link_url}
                          target="_blank"
                          rel="noopener noreferrer"
                          style={newsStyles.ctaBtn}
                          onClick={() => markRead(it.id)}
                        >
                          {it.link_label || 'Learn more'}
                          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><line x1="7" y1="17" x2="17" y2="7"/><polyline points="7 7 17 7 17 17"/></svg>
                        </a>
                      )}
                      {isUnread && (
                        <button style={newsStyles.markReadBtn} onClick={() => markRead(it.id)}>
                          Mark as read
                        </button>
                      )}
                    </div>
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

Object.assign(window, { NewsScreen });
