import { NextRequest } from "next/server"

import { PermissionDeniedError, requirePermission } from "@/shared/lib/auth-guard"
import { Permissions } from "@/shared/types/permissions"
import { getUnreadNotificationCount, getNotifications } from "@/modules/notifications/data-access"
import { getUnreadMessageCount } from "@/modules/messaging/data-access"

/**
 * 通知 + 消息实时推送 SSE 端点
 *
 * 使用 Server-Sent Events 向客户端推送通知和消息更新，
 * 替代原有的 30/60 秒轮询模式，降低延迟和服务器压力。
 *
 * 推送策略：
 * - 连接建立时立即推送一次当前状态（通知未读数 + 消息未读数 + 最新通知列表）
 * - 之后每 15 秒推送一次更新（作为 SSE 心跳 + 数据刷新）
 * - 客户端断开连接时清理定时器
 *
 * P1-5: payload 新增 unreadMessageCount 字段，UnreadMessageBadge 可直接订阅
 *
 * 安全：
 * - requirePermission(MESSAGE_READ) 权限校验
 * - 连接超时 5 分钟自动关闭（防止僵尸连接）
 */

const FORMAT_EVENT = (data: unknown): string => `data: ${JSON.stringify(data)}\n\n`
const FORMAT_DONE = "data: [DONE]\n\n"

/** SSE 推送间隔（毫秒） */
const SSE_PUSH_INTERVAL_MS = 15_000

/** SSE 连接最大存活时间（毫秒） */
const SSE_MAX_LIFETIME_MS = 5 * 60_000

export async function GET(_request: NextRequest): Promise<Response> {
  const encoder = new TextEncoder()

  try {
    const ctx = await requirePermission(Permissions.MESSAGE_READ)

    let intervalTimer: ReturnType<typeof setInterval> | null = null
    let lifetimeTimer: ReturnType<typeof setTimeout> | null = null
    let closed = false

    const stream = new ReadableStream<Uint8Array>({
      async start(controller) {
        const safeEnqueue = (data: string): void => {
          if (closed) return
          try {
            controller.enqueue(encoder.encode(data))
          } catch {
            closed = true
          }
        }

        const pushUpdate = async (): Promise<void> => {
          if (closed) return
          try {
            const [unreadCount, notificationsResult, unreadMessageCount] = await Promise.all([
              getUnreadNotificationCount(ctx.userId),
              getNotifications(ctx.userId, { page: 1, pageSize: 10 }),
              getUnreadMessageCount(ctx.userId),
            ])
            safeEnqueue(FORMAT_EVENT({
              type: "update",
              unreadCount,
              unreadMessageCount,
              notifications: notificationsResult.items,
            }))
          } catch {
            // 查询失败不关闭连接，等待下次重试
          }
        }

        // 连接建立时立即推送一次
        await pushUpdate()

        // 定时推送
        intervalTimer = setInterval(() => {
          void pushUpdate()
        }, SSE_PUSH_INTERVAL_MS)

        // 连接超时清理（5 分钟后自动关闭）
        lifetimeTimer = setTimeout(() => {
          safeEnqueue(FORMAT_DONE)
          if (intervalTimer) clearInterval(intervalTimer)
          if (!closed) {
            closed = true
            try {
              controller.close()
            } catch {
              // 已关闭
            }
          }
        }, SSE_MAX_LIFETIME_MS)
      },
      cancel() {
        if (intervalTimer) clearInterval(intervalTimer)
        if (lifetimeTimer) clearTimeout(lifetimeTimer)
        closed = true
      },
    })

    return new Response(stream, {
      headers: {
        "Content-Type": "text/event-stream",
        "Cache-Control": "no-cache, no-transform",
        Connection: "keep-alive",
      },
    })
  } catch (error) {
    if (error instanceof PermissionDeniedError) {
      return new Response(FORMAT_EVENT({ type: "error", message: "Permission denied" }), {
        status: 403,
        headers: { "Content-Type": "text/event-stream" },
      })
    }
    return new Response(FORMAT_EVENT({ type: "error", message: "Internal error" }), {
      status: 500,
      headers: { "Content-Type": "text/event-stream" },
    })
  }
}
