import { useCallback, useEffect, useState } from "react"
import { useNavigate } from "react-router-dom"
import {
  Badge,
  Button,
  Card,
  Checkbox,
  Empty,
  Modal,
  Pagination,
  Segmented,
  Select,
  Space,
  Spin,
  Tabs,
  Tag,
  Typography,
  message,
} from "antd"
import { CheckOutlined, DeleteOutlined, ReloadOutlined } from "@ant-design/icons"
import {
  batchArchiveNotifications,
  batchDeleteNotifications,
  batchHandleNotifications,
  batchMarkNotificationsRead,
  deleteNotification,
  getUnreadCount,
  listAnnouncements,
  listNotifications,
  markAllNotificationsRead,
  markAnnouncementRead,
  markNotificationRead,
  type AnnouncementItem,
  type NotificationItem,
} from "../api/notifications"
import RichTextContent from "../components/RichTextContent"

const { Text, Title, Paragraph } = Typography

const PAGE_SIZE = 10

const CATEGORY_META: Record<string, { label: string; color: string }> = {
  order: { label: "订单", color: "blue" },
  instance: { label: "服务器", color: "green" },
  finance: { label: "财务", color: "orange" },
  ticket: { label: "工单", color: "purple" },
  promotion: { label: "推广", color: "magenta" },
  membership: { label: "会员", color: "cyan" },
  system: { label: "系统", color: "default" },
  announcement: { label: "公告", color: "gold" },
}

const LEVEL_META: Record<string, { label: string; color: string }> = {
  info: { label: "普通", color: "default" },
  success: { label: "成功", color: "success" },
  warning: { label: "提醒", color: "warning" },
  error: { label: "异常", color: "error" },
  urgent: { label: "紧急", color: "red" },
}

const CATEGORY_OPTIONS = Object.entries(CATEGORY_META)
  .filter(([value]) => value !== "announcement")
  .map(([value, meta]) => ({ value, label: meta.label }))

const LEVEL_OPTIONS = Object.entries(LEVEL_META).map(([value, meta]) => ({ value, label: meta.label }))

function categoryTag(category: string) {
  const meta = CATEGORY_META[category] ?? CATEGORY_META.system
  return <Tag color={meta.color}>{meta.label}</Tag>
}

function levelTag(level: string) {
  const meta = LEVEL_META[level] ?? LEVEL_META.info
  return <Tag color={meta.color}>{meta.label}</Tag>
}

function formatTime(value: string | null) {
  if (!value) return "-"
  return new Date(value).toLocaleString("zh-CN", {
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
    hour12: false,
  })
}

function senderName(item: { sender_name?: string; source_label?: string }) {
  return item.sender_name || item.source_label || "系统通知"
}

function actionOf(item: NotificationItem) {
  const url = item.action?.url || item.action_url || item.link
  const label = item.action?.label || item.action_label || "前往处理"
  return url ? { label, url } : null
}

export default function Notifications() {
  const navigate = useNavigate()
  const [activeTab, setActiveTab] = useState("messages")

  // 消息
  const [notifications, setNotifications] = useState<NotificationItem[]>([])
  const [notifTotal, setNotifTotal] = useState(0)
  const [notifPage, setNotifPage] = useState(1)
  const [notifFilter, setNotifFilter] = useState<"all" | "unread">("all")
  const [notifBox, setNotifBox] = useState<"active" | "archived">("active")
  const [categoryFilter, setCategoryFilter] = useState<string | undefined>()
  const [levelFilter, setLevelFilter] = useState<string | undefined>()
  const [importantOnly, setImportantOnly] = useState(false)
  const [handledState, setHandledState] = useState<"all" | "handled" | "unhandled">("all")
  const [selectedIds, setSelectedIds] = useState<number[]>([])
  const [notifLoading, setNotifLoading] = useState(false)

  // 公告
  const [announcements, setAnnouncements] = useState<AnnouncementItem[]>([])
  const [annTotal, setAnnTotal] = useState(0)
  const [annPage, setAnnPage] = useState(1)
  const [annLoading, setAnnLoading] = useState(false)
  const [viewingNotification, setViewingNotification] = useState<NotificationItem | null>(null)
  const [viewing, setViewing] = useState<AnnouncementItem | null>(null)

  const [unread, setUnread] = useState({ notifications: 0, announcements: 0, total: 0 })

  const refreshUnread = useCallback(async () => {
    try {
      setUnread(await getUnreadCount())
    } catch {
      // ignore
    }
  }, [])

  const loadNotifications = useCallback(async () => {
    setNotifLoading(true)
    try {
      const data = await listNotifications({
        category: categoryFilter,
        level: levelFilter,
        unread_only: notifFilter === "unread",
        important_only: importantOnly,
        archived_only: notifBox === "archived",
        handled_state: handledState === "all" ? undefined : handledState,
        limit: PAGE_SIZE,
        offset: (notifPage - 1) * PAGE_SIZE,
      })
      setNotifications(data.items)
      setNotifTotal(data.total)
    } catch {
      message.error("加载消息失败")
    } finally {
      setNotifLoading(false)
    }
  }, [categoryFilter, handledState, importantOnly, levelFilter, notifBox, notifFilter, notifPage])

  const loadAnnouncements = useCallback(async () => {
    setAnnLoading(true)
    try {
      const data = await listAnnouncements({
        limit: PAGE_SIZE,
        offset: (annPage - 1) * PAGE_SIZE,
      })
      setAnnouncements(data.items)
      setAnnTotal(data.total)
    } catch {
      message.error("加载公告失败")
    } finally {
      setAnnLoading(false)
    }
  }, [annPage])

  useEffect(() => {
    void loadNotifications()
  }, [loadNotifications])

  useEffect(() => {
    void loadAnnouncements()
  }, [loadAnnouncements])

  useEffect(() => {
    void refreshUnread()
  }, [refreshUnread])

  useEffect(() => {
    setSelectedIds([])
  }, [categoryFilter, handledState, importantOnly, levelFilter, notifBox, notifFilter, notifPage])

  const handleClickNotification = async (item: NotificationItem) => {
    const readItem = item.is_read
      ? item
      : { ...item, is_read: true, read_at: item.read_at ?? new Date().toISOString() }

    setViewingNotification(readItem)

    if (!item.is_read) {
      try {
        setNotifications((items) => items.map((current) => (current.id === item.id ? readItem : current)))
        await markNotificationRead(item.id)
        await loadNotifications()
        await refreshUnread()
      } catch {
        // ignore
      }
    }
  }

  const handleMarkAll = async () => {
    try {
      const res = await markAllNotificationsRead()
      message.success(`已标记 ${res.count} 条为已读`)
      await loadNotifications()
      await refreshUnread()
    } catch {
      message.error("操作失败")
    }
  }

  const handleDelete = async (item: NotificationItem) => {
    try {
      await deleteNotification(item.id)
      await loadNotifications()
      await refreshUnread()
    } catch {
      message.error("删除失败")
    }
  }

  const toggleSelected = (id: number, checked: boolean) => {
    setSelectedIds((ids) => checked ? Array.from(new Set([...ids, id])) : ids.filter((item) => item !== id))
  }

  const runBatch = async (action: "read" | "handled" | "archive" | "restore" | "delete") => {
    if (selectedIds.length === 0) return
    const finish = async (text: string) => {
      message.success(text)
      setSelectedIds([])
      await loadNotifications()
      await refreshUnread()
    }
    try {
      if (action === "read") {
        const res = await batchMarkNotificationsRead(selectedIds)
        await finish(`已标记 ${res.count} 条为已读`)
      } else if (action === "handled") {
        const res = await batchHandleNotifications(selectedIds, true)
        await finish(`已标记 ${res.count} 条为已处理`)
      } else if (action === "archive" || action === "restore") {
        const archived = action === "archive"
        const res = await batchArchiveNotifications(selectedIds, archived)
        await finish(archived ? `已归档 ${res.count} 条消息` : `已恢复 ${res.count} 条消息`)
      } else {
        Modal.confirm({
          title: "删除选中的消息？",
          content: `将永久删除 ${selectedIds.length} 条站内信。`,
          okText: "删除",
          okButtonProps: { danger: true },
          cancelText: "取消",
          onOk: async () => {
            const res = await batchDeleteNotifications(selectedIds)
            await finish(`已删除 ${res.count} 条消息`)
          },
        })
      }
    } catch {
      message.error("操作失败")
    }
  }

  const handleViewAnnouncement = async (item: AnnouncementItem) => {
    const readItem = item.is_read ? item : { ...item, is_read: true }
    setViewing(readItem)
    if (!item.is_read) {
      try {
        setAnnouncements((items) => items.map((current) => (current.id === item.id ? readItem : current)))
        await markAnnouncementRead(item.id)
        await loadAnnouncements()
        await refreshUnread()
      } catch {
        // ignore
      }
    }
  }

  const messagesTab = (
    <Space direction="vertical" size={12} style={{ width: "100%" }}>
      <Space wrap style={{ justifyContent: "space-between", width: "100%", gap: 12 }} align="start">
        <Space wrap>
          <Segmented
            value={notifBox}
            onChange={(v) => {
              setNotifBox(v as "active" | "archived")
              setNotifPage(1)
            }}
            options={[
              { label: "收件箱", value: "active" },
              { label: "归档箱", value: "archived" },
            ]}
          />
          <Segmented
            value={notifFilter}
            onChange={(v) => {
              setNotifFilter(v as "all" | "unread")
              setNotifPage(1)
            }}
            options={[
              { label: "全部", value: "all" },
              { label: "未读", value: "unread" },
            ]}
          />
          <Select
            allowClear
            placeholder="分类"
            options={CATEGORY_OPTIONS}
            value={categoryFilter}
            onChange={(value) => { setCategoryFilter(value); setNotifPage(1) }}
            style={{ width: 112 }}
          />
          <Select
            allowClear
            placeholder="等级"
            options={LEVEL_OPTIONS}
            value={levelFilter}
            onChange={(value) => { setLevelFilter(value); setNotifPage(1) }}
            style={{ width: 112 }}
          />
          <Select
            value={handledState}
            onChange={(value) => { setHandledState(value); setNotifPage(1) }}
            options={[
              { value: "all", label: "处理状态" },
              { value: "unhandled", label: "未处理" },
              { value: "handled", label: "已处理" },
            ]}
            style={{ width: 120 }}
          />
          <Checkbox checked={importantOnly} onChange={(e) => { setImportantOnly(e.target.checked); setNotifPage(1) }}>
            重要
          </Checkbox>
        </Space>
        <Space wrap>
          <Button icon={<ReloadOutlined />} onClick={() => void loadNotifications()}>刷新</Button>
          <Button icon={<CheckOutlined />} onClick={handleMarkAll} disabled={unread.notifications === 0 || notifBox === "archived"}>
            全部已读
          </Button>
        </Space>
      </Space>

      {selectedIds.length > 0 && (
        <Space wrap style={{ padding: "8px 12px", borderRadius: 6, background: "#f5f7fa", width: "100%" }}>
          <Text type="secondary">已选 {selectedIds.length} 条</Text>
          <Button size="small" onClick={() => void runBatch("read")}>标记已读</Button>
          <Button size="small" onClick={() => void runBatch("handled")}>标记已处理</Button>
          <Button size="small" onClick={() => void runBatch(notifBox === "archived" ? "restore" : "archive")}>
            {notifBox === "archived" ? "恢复" : "归档"}
          </Button>
          <Button size="small" danger onClick={() => void runBatch("delete")}>删除</Button>
        </Space>
      )}

      {notifLoading ? (
        <div style={{ padding: 60, textAlign: "center" }}><Spin /></div>
      ) : notifications.length === 0 ? (
        <Empty description="暂无消息" style={{ padding: 40 }} />
      ) : (
        <Space direction="vertical" size={8} style={{ width: "100%" }}>
          {notifications.map((item) => (
            <Card
              key={item.id}
              size="small"
              variant="outlined"
              style={{
                background: item.is_read ? "#fff" : "#f0f7ff",
                cursor: "pointer",
              }}
              styles={{ body: { padding: "10px 14px" } }}
              onClick={() => void handleClickNotification(item)}
            >
              <div style={{ display: "flex", alignItems: "flex-start", gap: 10 }}>
                <Checkbox
                  checked={selectedIds.includes(item.id)}
                  onClick={(event) => event.stopPropagation()}
                  onChange={(event) => toggleSelected(item.id, event.target.checked)}
                />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <Space size={8} wrap>
                    {!item.is_read && <Badge status="processing" />}
                    {categoryTag(item.category)}
                    {levelTag(item.level)}
                    {item.handled_at ? <Tag color="green">已处理</Tag> : <Tag>未处理</Tag>}
                    {item.archived_at && <Tag color="default">已归档</Tag>}
                    <Text strong={!item.is_read}>{item.title}</Text>
                  </Space>
                  <Paragraph type="secondary" style={{ margin: "4px 0 0", fontSize: 13 }}>
                    {item.content}
                  </Paragraph>
                  <Text type="secondary" style={{ fontSize: 12 }}>
                    {senderName(item)} · {formatTime(item.created_at)}
                  </Text>
                </div>
                <Button
                  size="small"
                  type="text"
                  danger
                  icon={<DeleteOutlined />}
                  onClick={(e) => {
                    e.stopPropagation()
                    void handleDelete(item)
                  }}
                />
              </div>
            </Card>
          ))}
        </Space>
      )}

      {notifTotal > PAGE_SIZE && (
        <div style={{ textAlign: "right" }}>
          <Pagination
            current={notifPage}
            pageSize={PAGE_SIZE}
            total={notifTotal}
            showSizeChanger={false}
            onChange={setNotifPage}
          />
        </div>
      )}
    </Space>
  )

  const announcementsTab = (
    <Space direction="vertical" size={12} style={{ width: "100%" }}>
      <div style={{ textAlign: "right" }}>
        <Button icon={<ReloadOutlined />} onClick={() => void loadAnnouncements()}>刷新</Button>
      </div>
      {annLoading ? (
        <div style={{ padding: 60, textAlign: "center" }}><Spin /></div>
      ) : announcements.length === 0 ? (
        <Empty description="暂无公告" style={{ padding: 40 }} />
      ) : (
        <Space direction="vertical" size={8} style={{ width: "100%" }}>
          {announcements.map((item) => (
            <Card
              key={item.id}
              size="small"
              variant="outlined"
              style={{ background: item.is_read ? "#fff" : "#fffbe6", cursor: "pointer" }}
              styles={{ body: { padding: "10px 14px" } }}
              onClick={() => void handleViewAnnouncement(item)}
            >
              <Space size={8}>
                {!item.is_read && <Badge status="warning" />}
                {categoryTag(item.category)}
                <Text strong={!item.is_read}>{item.title}</Text>
              </Space>
              <div style={{ marginTop: 4 }}>
                <Text type="secondary" style={{ fontSize: 12 }}>
                  {senderName(item)} · {formatTime(item.published_at || item.created_at)}
                </Text>
              </div>
            </Card>
          ))}
        </Space>
      )}
      {annTotal > PAGE_SIZE && (
        <div style={{ textAlign: "right" }}>
          <Pagination
            current={annPage}
            pageSize={PAGE_SIZE}
            total={annTotal}
            showSizeChanger={false}
            onChange={setAnnPage}
          />
        </div>
      )}
    </Space>
  )

  return (
    <Space direction="vertical" size={20} style={{ width: "100%" }}>
      <div>
        <Title level={3} style={{ marginBottom: 4 }}>消息通知</Title>
        <Paragraph type="secondary" style={{ marginBottom: 0 }}>
          查看系统消息和平台公告。
        </Paragraph>
      </div>

      <Card variant="outlined">
        <Tabs
          activeKey={activeTab}
          onChange={setActiveTab}
          items={[
            {
              key: "messages",
              label: (
                <Badge count={unread.notifications} size="small" offset={[8, 0]}>
                  <span>我的消息</span>
                </Badge>
              ),
              children: messagesTab,
            },
            {
              key: "announcements",
              label: (
                <Badge count={unread.announcements} size="small" offset={[8, 0]}>
                  <span>系统公告</span>
                </Badge>
              ),
              children: announcementsTab,
            },
          ]}
        />
      </Card>

      <Modal
        open={!!viewingNotification}
        title={viewingNotification?.title}
        footer={
          <Space>
            {viewingNotification && (
              <Button
                onClick={async () => {
                  const nextHandled = !viewingNotification.handled_at
                  try {
                    await batchHandleNotifications([viewingNotification.id], nextHandled)
                    const updated = {
                      ...viewingNotification,
                      handled_at: nextHandled ? new Date().toISOString() : null,
                    }
                    setViewingNotification(updated)
                    setNotifications((items) => items.map((item) => item.id === updated.id ? updated : item))
                    message.success(nextHandled ? "已标记为已处理" : "已标记为未处理")
                  } catch {
                    message.error("操作失败")
                  }
                }}
              >
                {viewingNotification.handled_at ? "标记未处理" : "标记已处理"}
              </Button>
            )}
            {viewingNotification && actionOf(viewingNotification) && (
              <Button
                type="primary"
                onClick={() => {
                  const action = actionOf(viewingNotification)
                  setViewingNotification(null)
                  if (action?.url) navigate(action.url)
                }}
              >
                {actionOf(viewingNotification)?.label}
              </Button>
            )}
            <Button onClick={() => setViewingNotification(null)}>关闭</Button>
          </Space>
        }
        onCancel={() => setViewingNotification(null)}
        width={640}
        style={{ maxWidth: "92vw" }}
        destroyOnHidden
      >
        {viewingNotification && (
          <>
            <Text type="secondary" style={{ display: "block", marginBottom: 14, fontSize: 13 }}>
              {senderName(viewingNotification)} · {formatTime(viewingNotification.created_at)}
            </Text>
            <Paragraph style={{ marginBottom: 0, whiteSpace: "pre-wrap", wordBreak: "break-word" }}>
              {viewingNotification.content || "暂无内容"}
            </Paragraph>
          </>
        )}
      </Modal>

      <Modal
        open={!!viewing}
        title={viewing?.title}
        footer={<Button type="primary" onClick={() => setViewing(null)}>关闭</Button>}
        onCancel={() => setViewing(null)}
        width={720}
        style={{ maxWidth: "92vw" }}
        destroyOnHidden
      >
        {viewing && (
          <>
            <Text type="secondary" style={{ display: "block", marginBottom: 14, fontSize: 13 }}>
              {senderName(viewing)} · {formatTime(viewing.published_at || viewing.created_at)}
            </Text>
            <RichTextContent value={viewing.content} />
          </>
        )}
      </Modal>
    </Space>
  )
}
