import {
  BellOutlined,
  CheckCircleOutlined,
  CloseCircleOutlined,
  DeleteOutlined,
  DislikeOutlined,
  ExclamationCircleOutlined,
  LikeOutlined,
  LockOutlined,
} from "@ant-design/icons";
import { useEffect, useRef, useState } from "react";
import type { WebNotification, WebNotificationType, WebViewKey } from "../types";
import { AnimatedPanel } from "./AnimatedPanel";

const NOTIFICATION_ICONS: Record<WebNotificationType, React.ReactNode> = {
  task_completed: <CheckCircleOutlined style={{ color: "#10b981" }} />,
  task_failed: <CloseCircleOutlined style={{ color: "#ef4444" }} />,
  review_pending: <ExclamationCircleOutlined style={{ color: "#f59e0b" }} />,
  review_passed: <LikeOutlined style={{ color: "#10b981" }} />,
  review_rejected: <DislikeOutlined style={{ color: "#f59e0b" }} />,
  credits_low: <ExclamationCircleOutlined style={{ color: "#f59e0b" }} />,
  session_expired: <LockOutlined style={{ color: "#ef4444" }} />,
  info: <BellOutlined style={{ color: "#2563eb" }} />,
};

function parseTimestamp(dateStr: string): number {
  if (!dateStr) return Date.now();
  let ts = new Date(dateStr).getTime();
  if (Number.isNaN(ts)) {
    ts = new Date(dateStr.replace(" ", "T") + "Z").getTime();
  }
  if (Number.isNaN(ts)) return Date.now();
  return ts;
}

function timeAgo(dateStr: string, now: number): string {
  const ts = parseTimestamp(dateStr);
  const diff = now - ts;
  if (diff < 0) return "刚刚";
  const seconds = Math.floor(diff / 1000);
  if (seconds < 60) return "刚刚";
  const minutes = Math.floor(seconds / 60);
  if (minutes < 60) return `${minutes}分钟前`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours}小时前`;
  const days = Math.floor(hours / 24);
  if (days < 30) return `${days}天前`;
  const date = new Date(ts);
  return `${date.getMonth() + 1}月${date.getDate()}日`;
}

interface NotificationCenterProps {
  items?: WebNotification[];
  onNavigate: (view: WebViewKey, targetId?: string) => void;
  onMarkRead?: (id: string, isRead?: boolean) => void;
  onMarkAllRead?: () => void;
  onClear?: () => void;
}

function NotificationCenter({ items, onNavigate, onMarkRead, onMarkAllRead, onClear }: NotificationCenterProps) {
  const [readIds, setReadIds] = useState<string[]>([]);
  const [open, setOpen] = useState(false);
  const [now, setNow] = useState(Date.now);
  const containerRef = useRef<HTMLDivElement>(null);
  const notifications = items ?? [];
  const unreadCount = notifications.filter((n) => !readIds.includes(n.id) && !n.isRead).length;

  useEffect(() => {
    if (!open) return;
    const timer = setInterval(() => setNow(Date.now()), 30_000);
    return () => clearInterval(timer);
  }, [open]);

  useEffect(() => {
    if (items && items.length === 0) {
      setReadIds([]);
    }
  }, [items]);

  useEffect(() => {
    if (!open) return;
    const handlePointerDown = (e: PointerEvent) => {
      if (!containerRef.current?.contains(e.target as Node)) {
        setOpen(false);
      }
    };
    document.addEventListener("pointerdown", handlePointerDown);
    return () => document.removeEventListener("pointerdown", handlePointerDown);
  }, [open]);

  const markAllRead = () => {
    setReadIds((prev) => Array.from(new Set([...prev, ...notifications.map((n) => n.id)])));
    onMarkAllRead?.();
  };

  const handleClickNotification = (n: WebNotification) => {
    setReadIds((prev) => (prev.includes(n.id) ? prev : [...prev, n.id]));
    onMarkRead?.(n.id, true);
    setOpen(false);
    if (n.targetView) {
      onNavigate(n.targetView, n.targetId);
    }
  };

  return (
    <div className="notification-center" ref={containerRef}>
      <button
        className="notification-center__bell"
        type="button"
        title="通知中心"
        aria-label={`通知中心${unreadCount > 0 ? `，${unreadCount}条未读` : ""}`}
        onClick={() => { setOpen((v) => !v); setNow(Date.now()); }}
      >
        <BellOutlined />
        {unreadCount > 0 && (
          <span className="notification-center__badge">{unreadCount > 99 ? "99+" : unreadCount}</span>
        )}
      </button>
      <AnimatedPanel open={open} className="notification-center__panel" exitDuration={140}>
          <div className="notification-center__header">
            <span className="notification-center__title">通知中心</span>
            <div className="notification-center__header-actions">
              {unreadCount > 0 && (
                <button className="notification-center__mark-read" type="button" onClick={markAllRead}>
                  全部已读
                </button>
              )}
              {notifications.length > 0 && onClear && (
                <button className="notification-center__clear" type="button" onClick={() => { onClear(); setOpen(false); }}>
                  <DeleteOutlined /> 清空
                </button>
              )}
            </div>
          </div>
          <div className="notification-center__list">
            {notifications.length === 0 ? (
              <div className="notification-center__empty">
                <BellOutlined style={{ fontSize: 28, opacity: 0.3 }} />
                <span>暂无通知</span>
              </div>
            ) : (
              notifications.map((n) => (
                <button
                  key={n.id}
                  type="button"
                  className={`notification-center__item${n.isRead || readIds.includes(n.id) ? "" : " is-unread"}`}
                  onClick={() => handleClickNotification(n)}
                >
                  <span className="notification-center__item-icon">
                    {NOTIFICATION_ICONS[n.type]}
                  </span>
                  <div className="notification-center__item-body">
                    <span className="notification-center__item-title">{n.title}</span>
                    <span className="notification-center__item-desc">{n.description}</span>
                  </div>
                  <span className="notification-center__item-time">{timeAgo(n.createdAt, now)}</span>
                </button>
              ))
            )}
          </div>
        </AnimatedPanel>
    </div>
  );
}

export default NotificationCenter;
