/**
 * Community Analytics Topic Cloud API
 *
 * Liefert aggregierte Themen für Tag-Cloud.
 *
 * GET /api/community/analytics/topic-cloud
 * Query: period (7d|30d|90d), channel (all|id), limit
 */

import { NextRequest, NextResponse } from 'next/server'
import { getPayload } from 'payload'
import config from '@payload-config'
import { subDays } from 'date-fns'
import { createSafeLogger } from '@/lib/security'
import { hasCommunityApiAccess } from '@/lib/communityAccess'

const logger = createSafeLogger('API:TopicCloud')

export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url)
    const period = searchParams.get('period') || '30d'
    const channelId = searchParams.get('channel') || 'all'
    const limit = parseInt(searchParams.get('limit') || '30')

    const payload = await getPayload({ config })

    // Auth check
    const { user } = await payload.auth({ headers: request.headers })
    if (!user) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    if (!hasCommunityApiAccess(user as any, 'viewer')) {
      return NextResponse.json({ error: 'Access denied' }, { status: 403 })
    }

    // Calculate date range
    const now = new Date()
    const days = period === '7d' ? 7 : period === '90d' ? 90 : 30
    const periodStart = subDays(now, days)

    // Build where clause
    const baseWhere: any = {
      publishedAt: { greater_than_equal: periodStart.toISOString() },
    }

    if (channelId !== 'all') {
      baseWhere.socialAccount = { equals: parseInt(channelId, 10) }
    }

    // Fetch interactions
    const interactions = await payload.find({
      collection: 'community-interactions',
      where: baseWhere,
      limit: 10000,
      depth: 1,
    })

    // Aggregate topics
    const topicData: Map<
      string,
      {
        count: number
        sentimentScores: number[]
        channels: Set<string>
      }
    > = new Map()

    interactions.docs.forEach((i) => {
      if (!i.analysis?.topics || !Array.isArray(i.analysis.topics)) return

      const channelName =
        typeof i.socialAccount === 'object'
          ? (i.socialAccount as { displayName?: string })?.displayName || 'Unknown'
          : 'Unknown'

      const sentimentScore = i.analysis?.sentimentScore as number | undefined

      i.analysis.topics.forEach((t: { topic?: string | null }) => {
        if (!t.topic) return

        const topic = t.topic.toLowerCase().trim()
        if (!topicData.has(topic)) {
          topicData.set(topic, {
            count: 0,
            sentimentScores: [],
            channels: new Set(),
          })
        }

        const data = topicData.get(topic)!
        data.count++
        data.channels.add(channelName)
        if (sentimentScore != null) {
          data.sentimentScores.push(sentimentScore)
        }
      })
    })

    // Convert to array and calculate averages
    const topics = Array.from(topicData.entries())
      .map(([topic, data]) => ({
        topic,
        count: data.count,
        avgSentiment:
          data.sentimentScores.length > 0
            ? data.sentimentScores.reduce((a, b) => a + b, 0) / data.sentimentScores.length
            : 0,
        channels: Array.from(data.channels),
      }))
      .sort((a, b) => b.count - a.count)
      .slice(0, limit)

    return NextResponse.json({ topics })
  } catch (error: unknown) {
    const errorMessage = error instanceof Error ? error.message : 'Unknown error'
    logger.error('Topic cloud error:', { error: errorMessage })
    return NextResponse.json({ error: 'Failed to fetch topic cloud' }, { status: 500 })
  }
}

export const dynamic = 'force-dynamic'
