/**
 * 通知中心 — 烽火台
 * 数据来源：未读邮件 + SSE 实时事件
 * 按 topic7-9 设计：按级别分组、操作按钮、任务链接、全部已读
 */

import { useState, useEffect } from 'react';
import { useStore } from '../store';

interface NotifItem {
  id: string;
  type: 'info' | 'warning' | 'success' | 'error';
  title: string;
  message: string;
  time: string;
  read: boolean;
  source: 'mail' | 'event';
  taskId?: string;
  projectId?: string;
  actionUrl?: string;
}

const LEVEL_ORDER: NotifItem['type'][] = ['error', 'warning', 'success', 'info'];
const TYPE_STYLES: Record<string, { icon: string; color: string; label: string }> = {
  error:   { icon: '🚨', color: '#ff5270', label: '🔴 紧急' },
  warning: { icon: '⚠️', color: '#f5c842', label: '🟡 警告' },
  success: { icon: '✅', color: '#2ecc8a', label: '🟢 完成' },
  info:    { icon: 'ℹ️', color: '#6a9eff', label: '🔵 通知' },
};

function mailToNotif(m: any): NotifItem {
  const typeMap: Record<string, NotifItem['type']> = {
    inform: 'info', task: 'info', alert: 'warning', error: 'error', done: 'success',
  };
  return {
    id: m.id,
    type: typeMap[m.type] || 'info',
    title: m.title || '(无标题)',
    message: `${m.from || '?'} → ${m.to || '?'}`,
    time: m.created_at || '',
    read: !!m.is_read,
    source: 'mail',
  };
}

export default function NotificationCenter({ onClose }: { onClose: () => void }) {
  const mails = useStore(s => s.mails);
  const loadMails = useStore(s => s.loadMails);
  const [sseEvents, setSseEvents] = useState<NotifItem[]>([]);
  const [expanded, setExpanded] = useState<string | null>(null);

  useEffect(() => { loadMails(); }, []);

  useEffect(() => {
    const es = new EventSource('/api/events');
    const importantTypes = ['task_completed', 'task_failed', 'review_result', 'agent_completed', 'task_updated'];
    const handler = (e: MessageEvent) => {
      try {
        const data = JSON.parse(e.data);
        const etype = (e as any).type || data.event_type || '';
        if (!importantTypes.includes(etype)) return;
        const ntype = etype === 'task_failed' ? 'error' : etype === 'task_completed' ? 'success' : etype === 'review_result' ? 'warning' : 'info';
        setSseEvents(prev => {
          const item: NotifItem = {
            id: data.id || `sse-${Date.now()}`,
            type: ntype,
            title: data.task_id ? `任务 ${data.task_id?.slice(0, 8)}...` : (data.event_type || etype),
            message: `${data.old_status || ''} → ${data.new_status || data.event_type || ''}`,
            time: data.timestamp || new Date().toISOString(),
            read: false,
            source: 'event',
            taskId: data.task_id,
            projectId: data.project_id,
          };
          return [item, ...prev].slice(0, 30);
        });
      } catch { /* ignore */ }
    };
    importantTypes.forEach(t => es.addEventListener(t, handler));
    es.onerror = () => { es.close(); };
    return () => { es.close(); };
  }, []);

  // 合并 + 分组
  const mailNotifs = (mails || []).slice(0, 20).map(mailToNotif);
  const allNotifs = [...sseEvents, ...mailNotifs];
  const unread = allNotifs.filter(n => !n.read).length;

  const grouped = LEVEL_ORDER.map(type => ({
    type,
    label: TYPE_STYLES[type].label,
    items: allNotifs.filter(n => n.type === type),
  })).filter(g => g.items.length > 0);

  const handleMarkRead = async (notif: NotifItem) => {
    if (notif.source === 'mail' && !notif.read) {
      await fetch(`/api/mail/${notif.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ is_read: true }),
      });
      loadMails();
    }
    if (notif.source === 'event') {
      setSseEvents(prev => prev.map(n => n.id === notif.id ? { ...n, read: true } : n));
    }
  };

  const handleMarkAllRead = async () => {
    // 标记所有邮件已读
    for (const n of allNotifs.filter(n => !n.read && n.source === 'mail')) {
      await fetch(`/api/mail/${n.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ is_read: true }),
      });
    }
    loadMails();
    setSseEvents(prev => prev.map(n => ({ ...n, read: true })));
  };

  const handleViewTask = (notif: NotifItem) => {
    if (notif.taskId) {
      useStore.getState().setModalTaskId(notif.taskId);
      if (notif.projectId) useStore.getState().setSelectedProjectId(notif.projectId);
      onClose();
    }
  };

  return (
    <div className="confirm-bg open" onClick={onClose}>
      <div className="confirm-box" style={{ maxWidth: 420, maxHeight: 520 }} onClick={e => e.stopPropagation()}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
          <span style={{ fontSize: 14, fontWeight: 700 }}>🔔 烽火台</span>
          <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
            {unread > 0 && (
              <>
                <span style={{ fontSize: 10, padding: '2px 8px', borderRadius: 10, background: '#ff5270', color: '#fff', fontWeight: 600 }}>{unread}</span>
                <button onClick={handleMarkAllRead} style={{ fontSize: 10, padding: '2px 8px', borderRadius: 6, border: '1px solid var(--line)', background: 'transparent', color: 'var(--muted)', cursor: 'pointer' }}>全部已读</button>
              </>
            )}
            <span style={{ fontSize: 13, color: 'var(--muted)', cursor: 'pointer' }} onClick={onClose}>✕</span>
          </div>
        </div>

        {allNotifs.length === 0 ? (
          <div style={{ textAlign: 'center', padding: '20px 0' }}>
            <div style={{ fontSize: 28, marginBottom: 8 }}>🔕</div>
            <div style={{ fontSize: 12, color: 'var(--muted)' }}>暂无烽火</div>
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, maxHeight: 400, overflow: 'auto' }}>
            {grouped.map(g => (
              <div key={g.type}>
                <div style={{ fontSize: 11, fontWeight: 600, color: TYPE_STYLES[g.type].color, marginBottom: 4 }}>{g.label} ({g.items.length})</div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                  {g.items.map(n => {
                    const s = TYPE_STYLES[n.type];
                    const isExpanded = expanded === n.id;
                    return (
                      <div key={n.id} style={{
                        padding: '8px 10px', borderRadius: 8,
                        background: 'var(--panel2)', border: `1px solid ${n.read ? 'var(--line)' : s.color + '44'}`,
                        opacity: n.read ? 0.5 : 1,
                      }}>
                        <div style={{ display: 'flex', gap: 6, alignItems: 'center', cursor: 'pointer' }} onClick={() => setExpanded(isExpanded ? null : n.id)}>
                          <span style={{ fontSize: 12 }}>{s.icon}</span>
                          <span style={{ fontSize: 11, fontWeight: 600, flex: 1 }}>{n.title}</span>
                          <span style={{ fontSize: 9, background: 'var(--panel)', padding: '1px 4px', borderRadius: 3, color: 'var(--muted)' }}>
                            {n.source === 'mail' ? '✉️' : '📡'}
                          </span>
                        </div>
                        <div style={{ fontSize: 10, color: 'var(--muted)', marginTop: 2 }}>{n.message}</div>
                        {isExpanded && (
                          <div style={{ display: 'flex', gap: 6, marginTop: 6 }}>
                            {n.taskId && (
                              <button onClick={() => handleViewTask(n)} style={{ fontSize: 10, padding: '2px 8px', borderRadius: 4, border: '1px solid var(--acc)', background: 'transparent', color: 'var(--acc)', cursor: 'pointer' }}>查看任务</button>
                            )}
                            {!n.read && (
                              <button onClick={() => handleMarkRead(n)} style={{ fontSize: 10, padding: '2px 8px', borderRadius: 4, border: '1px solid var(--line)', background: 'transparent', color: 'var(--muted)', cursor: 'pointer' }}>已读</button>
                            )}
                          </div>
                        )}
                      </div>
                    );
                  })}
                </div>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}
