import { useEffect, type CSSProperties } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import DOMPurify from 'dompurify';
import { Sidebar } from '../components/Sidebar';
import { useNotificationStore } from '../store/notification';
import type { AppNotification, NotificationType } from '../types';

// 每条通知顶部标签 — 4 色一目了然
const TYPE_CHIP: Record<NotificationType, { text: string; color: string; bg: string }> = {
  announcement: { text: '公告', color: 'var(--color-primary)', bg: 'var(--color-primary-bg, rgba(0,184,230,0.12))' },
  anomaly_disabled_user: { text: '安全', color: 'var(--color-danger)', bg: 'rgba(231,76,60,0.12)' },
  anomaly_disabled_team: { text: '安全', color: 'var(--color-danger)', bg: 'rgba(231,76,60,0.12)' },
  quota_warning: { text: '额度', color: '#faad14', bg: 'rgba(250,173,20,0.12)' },
  system: { text: '系统', color: 'var(--color-text-tertiary)', bg: 'var(--color-bg-elevated)' },
};

function formatRelative(iso: string): string {
  const ts = new Date(iso).getTime();
  if (Number.isNaN(ts)) return '';
  const ms = Date.now() - ts;
  if (ms < 0) return '刚刚';
  const sec = Math.floor(ms / 1000);
  if (sec < 60) return '刚刚';
  if (sec < 3600) return `${Math.floor(sec / 60)} 分钟前`;
  if (sec < 86400) return `${Math.floor(sec / 3600)} 小时前`;
  if (sec < 86400 * 7) return `${Math.floor(sec / 86400)} 天前`;
  return new Date(iso).toLocaleDateString('zh-CN');
}

const styles: Record<string, CSSProperties> = {
  layout: {
    display: 'flex',
    height: '100%',
    position: 'relative',
    zIndex: 2,
  },
  main: {
    flex: 1,
    overflowY: 'auto',
    padding: '24px 32px 60px',
    background: 'var(--color-bg-page)',
  },
  container: {
    maxWidth: 800,
    margin: '0 auto',
  },
  header: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginBottom: 20,
  },
  title: {
    fontSize: 20,
    fontWeight: 600,
    color: 'var(--color-text-primary)',
    margin: 0,
  },
  markAllBtn: {
    padding: '6px 14px',
    background: 'transparent',
    border: '1px solid var(--color-border-card)',
    borderRadius: 'var(--radius-btn, 6px)',
    color: 'var(--color-text-secondary)',
    fontSize: 13,
    cursor: 'pointer',
    transition: 'background 0.15s, color 0.15s',
  },
  list: {
    background: 'var(--color-bg-card)',
    border: '1px solid var(--color-border-modal-soft)',
    borderRadius: 8,
    overflow: 'hidden',
  },
  row: {
    display: 'flex',
    gap: 12,
    padding: '14px 18px',
    borderBottom: '1px solid var(--color-border-modal-soft)',
    cursor: 'pointer',
    transition: 'background 0.15s',
    position: 'relative',
  },
  rowLast: {
    borderBottom: 'none',
  },
  unreadDot: {
    width: 8,
    height: 8,
    borderRadius: '50%',
    background: 'var(--color-primary)',
    flexShrink: 0,
    marginTop: 7,
  },
  dotPlaceholder: {
    width: 8,
    height: 8,
    flexShrink: 0,
  },
  rowContent: {
    flex: 1,
    minWidth: 0,
  },
  rowHead: {
    display: 'flex',
    alignItems: 'baseline',
    justifyContent: 'space-between',
    gap: 12,
    marginBottom: 4,
  },
  rowTitle: {
    fontSize: 14,
    fontWeight: 600,
    color: 'var(--color-text-primary)',
    overflow: 'hidden',
    textOverflow: 'ellipsis',
    whiteSpace: 'nowrap',
  },
  rowTitleRead: {
    fontWeight: 500,
    color: 'var(--color-text-light)',
  },
  rowTime: {
    fontSize: 12,
    color: 'var(--color-text-tertiary)',
    flexShrink: 0,
    whiteSpace: 'nowrap',
  },
  rowBody: {
    fontSize: 13,
    color: 'var(--color-text-secondary)',
    lineHeight: 1.5,
    wordBreak: 'break-word',
  },
  empty: {
    padding: '80px 0',
    textAlign: 'center',
    color: 'var(--color-text-tertiary)',
    fontSize: 14,
  },
  loading: {
    padding: '60px 0',
    textAlign: 'center',
    color: 'var(--color-text-secondary)',
    fontSize: 14,
  },
  pagination: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: 16,
    marginTop: 20,
    color: 'var(--color-text-secondary)',
    fontSize: 13,
  },
  pageBtn: {
    width: 28,
    height: 28,
    display: 'inline-flex',
    alignItems: 'center',
    justifyContent: 'center',
    border: '1px solid var(--color-border-card)',
    background: 'transparent',
    borderRadius: 6,
    cursor: 'pointer',
    color: 'var(--color-text-secondary)',
    padding: 0,
  },
  pageBtnDisabled: {
    cursor: 'not-allowed',
    opacity: 0.4,
  },
  backBtn: {
    display: 'inline-flex',
    alignItems: 'center',
    gap: 6,
    padding: '6px 14px',
    background: 'transparent',
    border: '1px solid var(--color-border-card)',
    borderRadius: 'var(--radius-btn, 6px)',
    color: 'var(--color-text-secondary)',
    fontSize: 13,
    cursor: 'pointer',
    marginRight: 12,
  },
};

interface NotificationRowProps {
  item: AppNotification;
  isLast: boolean;
  onClick: (item: AppNotification) => void;
}

function NotificationRow({ item, isLast, onClick }: NotificationRowProps) {
  const rowStyle: CSSProperties = {
    ...styles.row,
    ...(isLast ? styles.rowLast : {}),
    background: item.is_read ? 'transparent' : 'var(--color-primary-bg, transparent)',
  };
  const titleStyle: CSSProperties = {
    ...styles.rowTitle,
    ...(item.is_read ? styles.rowTitleRead : {}),
  };
  const chip = TYPE_CHIP[item.type] || TYPE_CHIP.system;
  const isAnnouncement = item.type === 'announcement';
  return (
    <div
      style={rowStyle}
      onClick={() => onClick(item)}
      onMouseEnter={(e) => {
        e.currentTarget.style.background = 'var(--color-bg-hover)';
      }}
      onMouseLeave={(e) => {
        e.currentTarget.style.background = item.is_read
          ? 'transparent'
          : 'var(--color-primary-bg, transparent)';
      }}
    >
      {item.is_read ? (
        <div style={styles.dotPlaceholder} />
      ) : (
        <div style={styles.unreadDot} aria-label="未读" />
      )}
      <div style={styles.rowContent}>
        <div style={styles.rowHead}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0, flex: 1 }}>
            <span style={{
              padding: '1px 7px', borderRadius: 4, fontSize: 11, fontWeight: 500,
              color: chip.color, background: chip.bg, flexShrink: 0,
            }}>
              {chip.text}
            </span>
            <span style={titleStyle}>{item.title}</span>
          </div>
          <span style={styles.rowTime} title={new Date(item.created_at).toLocaleString('zh-CN')}>
            {formatRelative(item.created_at)}
          </span>
        </div>
        {isAnnouncement ? (
          <div
            style={styles.rowBody}
            dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(item.content) }}
          />
        ) : (
          <div style={styles.rowBody}>{item.content}</div>
        )}
      </div>
    </div>
  );
}

export function NotificationsPage() {
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const unreadOnly = searchParams.get('unread_only') === 'true';

  const list = useNotificationStore((s) => s.list);
  const total = useNotificationStore((s) => s.total);
  const page = useNotificationStore((s) => s.page);
  const pageSize = useNotificationStore((s) => s.pageSize);
  const unreadCount = useNotificationStore((s) => s.unreadCount);
  const loading = useNotificationStore((s) => s.loading);
  const fetchList = useNotificationStore((s) => s.fetchList);
  const markRead = useNotificationStore((s) => s.markRead);
  const markAllRead = useNotificationStore((s) => s.markAllRead);

  // 首次加载 + URL 切换时拉第一页
  useEffect(() => {
    fetchList({ page: 1, unread_only: unreadOnly });
  }, [fetchList, unreadOnly]);

  const totalPages = Math.max(1, Math.ceil(total / Math.max(1, pageSize)));

  const goPage = (p: number) => {
    if (p < 1 || p > totalPages || p === page) return;
    fetchList({ page: p, unread_only: unreadOnly });
  };

  const handleRowClick = async (item: AppNotification) => {
    if (!item.is_read) {
      markRead(item.id);
    }
    if (item.link_url) {
      navigate(item.link_url);
    }
  };

  return (
    <div style={styles.layout}>
      <Sidebar />
      <main style={styles.main}>
        <div style={styles.container}>
          <div style={styles.header}>
            <div style={{ display: 'flex', alignItems: 'center' }}>
              <button
                style={styles.backBtn}
                onClick={() => navigate(-1)}
                title="返回上一页"
              >
                <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
                  <path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" />
                </svg>
                返回
              </button>
              <h1 style={styles.title}>消息中心</h1>
            </div>
            {unreadCount > 0 && (
              <button
                style={styles.markAllBtn}
                onClick={() => markAllRead()}
                onMouseEnter={(e) => {
                  e.currentTarget.style.background = 'var(--color-bg-hover)';
                  e.currentTarget.style.color = 'var(--color-text-primary)';
                }}
                onMouseLeave={(e) => {
                  e.currentTarget.style.background = 'transparent';
                  e.currentTarget.style.color = 'var(--color-text-secondary)';
                }}
              >
                全部标记已读
              </button>
            )}
          </div>

          {loading && list.length === 0 ? (
            <div style={styles.loading}>加载中...</div>
          ) : list.length === 0 ? (
            <div style={styles.empty}>暂无消息</div>
          ) : (
            <>
              <div style={styles.list}>
                {list.map((item, idx) => (
                  <NotificationRow
                    key={item.id}
                    item={item}
                    isLast={idx === list.length - 1}
                    onClick={handleRowClick}
                  />
                ))}
              </div>

              {totalPages > 1 && (
                <div style={styles.pagination}>
                  <button
                    style={{
                      ...styles.pageBtn,
                      ...(page <= 1 ? styles.pageBtnDisabled : {}),
                    }}
                    onClick={() => goPage(page - 1)}
                    disabled={page <= 1}
                    aria-label="上一页"
                  >
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                      <polyline points="15 18 9 12 15 6" />
                    </svg>
                  </button>
                  <span>第 {page} / {totalPages} 页</span>
                  <button
                    style={{
                      ...styles.pageBtn,
                      ...(page >= totalPages ? styles.pageBtnDisabled : {}),
                    }}
                    onClick={() => goPage(page + 1)}
                    disabled={page >= totalPages}
                    aria-label="下一页"
                  >
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                      <polyline points="9 18 15 12 9 6" />
                    </svg>
                  </button>
                </div>
              )}
            </>
          )}
        </div>
      </main>
    </div>
  );
}
