// src/app/(payload)/api/community/stream/route.ts
// Server-Sent Events Endpoint für Real-time Community Updates

import { NextRequest } from 'next/server'
import { getPayload } from 'payload'
import config from '@payload-config'

// Polling-Intervall in Millisekunden
const POLL_INTERVAL = 5000 // 5 Sekunden

// Maximale Verbindungsdauer (Vercel Limit)
const MAX_DURATION = 25000 // 25 Sekunden (Vercel max ist 30s)

/**
 * GET /api/community/stream
 * Server-Sent Events Endpoint für Live-Updates
 *
 * Query Parameters:
 * - since: ISO Timestamp - nur Updates seit diesem Zeitpunkt
 * - channels: Komma-separierte Channel-IDs für Filterung
 */
export async function GET(request: NextRequest) {
  const payload = await getPayload({ config })

  // Authentifizierung prüfen
  const { user } = await payload.auth({ headers: request.headers })

  if (!user) {
    return new Response('Unauthorized', { status: 401 })
  }

  // Query-Parameter
  const searchParams = request.nextUrl.searchParams
  const sinceParam = searchParams.get('since')
  const channelsParam = searchParams.get('channels')

  let lastCheckTime = sinceParam ? new Date(sinceParam) : new Date()
  const channelIds = channelsParam
    ? channelsParam.split(',').map((id) => parseInt(id, 10)).filter((id) => !isNaN(id))
    : []

  // Response-Stream erstellen
  const encoder = new TextEncoder()
  const stream = new ReadableStream({
    async start(controller) {
      const startTime = Date.now()

      // Initiale Nachricht senden
      const initMessage = JSON.stringify({
        type: 'connected',
        timestamp: new Date().toISOString(),
        message: 'Connected to community stream',
      })
      controller.enqueue(encoder.encode(`data: ${initMessage}\n\n`))

      // Polling-Loop
      while (Date.now() - startTime < MAX_DURATION) {
        try {
          const updates = await fetchUpdates(payload, lastCheckTime, channelIds)

          if (updates.length > 0) {
            const data = JSON.stringify({
              type: 'updates',
              updates,
              timestamp: new Date().toISOString(),
            })
            controller.enqueue(encoder.encode(`data: ${data}\n\n`))

            // Letzten Zeitstempel aktualisieren
            lastCheckTime = new Date()
          }

          // Heartbeat senden (verhindert Timeout)
          if (updates.length === 0) {
            const heartbeat = JSON.stringify({
              type: 'heartbeat',
              timestamp: new Date().toISOString(),
            })
            controller.enqueue(encoder.encode(`data: ${heartbeat}\n\n`))
          }

          // Warten bis zum nächsten Poll
          await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL))
        } catch (error) {
          console.error('[SSE] Error fetching updates:', error)

          const errorData = JSON.stringify({
            type: 'error',
            message: 'Error fetching updates',
            timestamp: new Date().toISOString(),
          })
          controller.enqueue(encoder.encode(`data: ${errorData}\n\n`))
        }
      }

      // Verbindung beenden (Client sollte reconnecten)
      const closeMessage = JSON.stringify({
        type: 'reconnect',
        timestamp: new Date().toISOString(),
        message: 'Connection timeout, please reconnect',
      })
      controller.enqueue(encoder.encode(`data: ${closeMessage}\n\n`))
      controller.close()
    },
  })

  return new Response(stream, {
    headers: {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache, no-transform',
      Connection: 'keep-alive',
      'X-Accel-Buffering': 'no', // Für Nginx
    },
  })
}

/**
 * Holt neue Updates seit dem letzten Check
 */
async function fetchUpdates(
  payload: any,
  since: Date,
  channelIds: number[]
): Promise<CommunityUpdate[]> {
  const updates: CommunityUpdate[] = []

  // Neue Interaktionen
  const whereInteractions: any = {
    createdAt: { greater_than: since.toISOString() },
  }

  if (channelIds.length > 0) {
    whereInteractions.socialAccount = { in: channelIds }
  }

  const newInteractions = await payload.find({
    collection: 'community-interactions',
    where: whereInteractions,
    limit: 50,
    sort: '-createdAt',
  })

  for (const interaction of newInteractions.docs) {
    updates.push({
      type: 'new_interaction',
      data: {
        id: interaction.id,
        platform: interaction.platform,
        authorName: interaction.authorName,
        content: (interaction.content as string)?.substring(0, 100),
        sentiment: (interaction.aiAnalysis as any)?.sentiment,
        sourceTitle: interaction.sourceTitle,
        createdAt: interaction.createdAt,
      },
      timestamp: interaction.createdAt as string,
    })
  }

  // Status-Änderungen (aktualisierte Interaktionen)
  const updatedInteractions = await payload.find({
    collection: 'community-interactions',
    where: {
      and: [
        { updatedAt: { greater_than: since.toISOString() } },
        { createdAt: { less_than: since.toISOString() } }, // Nicht neu erstellt
        ...(channelIds.length > 0 ? [{ socialAccount: { in: channelIds } }] : []),
      ],
    },
    limit: 50,
    sort: '-updatedAt',
  })

  for (const interaction of updatedInteractions.docs) {
    updates.push({
      type: 'status_change',
      data: {
        id: interaction.id,
        status: interaction.status,
        platform: interaction.platform,
        authorName: interaction.authorName,
        updatedAt: interaction.updatedAt,
      },
      timestamp: interaction.updatedAt as string,
    })
  }

  // Neue Antworten (kürzlich beantwortet)
  const newReplies = await payload.find({
    collection: 'community-interactions',
    where: {
      and: [
        { repliedAt: { greater_than: since.toISOString() } },
        { status: { equals: 'replied' } },
        ...(channelIds.length > 0 ? [{ socialAccount: { in: channelIds } }] : []),
      ],
    },
    limit: 50,
    sort: '-repliedAt',
  })

  for (const interaction of newReplies.docs) {
    // Nicht doppelt hinzufügen wenn schon als status_change
    if (!updates.some((u) => u.type === 'status_change' && u.data.id === interaction.id)) {
      updates.push({
        type: 'new_reply',
        data: {
          id: interaction.id,
          platform: interaction.platform,
          authorName: interaction.authorName,
          ourReply: (interaction.ourReply as string)?.substring(0, 100),
          repliedAt: interaction.repliedAt,
        },
        timestamp: interaction.repliedAt as string,
      })
    }
  }

  // Nach Timestamp sortieren
  updates.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())

  return updates.slice(0, 50) // Max 50 Updates pro Request
}

interface CommunityUpdate {
  type: 'new_interaction' | 'status_change' | 'new_reply'
  data: {
    id: number
    platform?: string
    authorName?: string
    content?: string
    sentiment?: string
    sourceTitle?: string
    status?: string
    ourReply?: string
    createdAt?: string
    updatedAt?: string
    repliedAt?: string
  }
  timestamp: string
}

export const dynamic = 'force-dynamic'
export const maxDuration = 30 // Maximum für Vercel
