/**
 * Community Analytics Top Content API
 *
 * Liefert Top-Videos/Content nach Engagement.
 *
 * GET /api/community/analytics/top-content
 * Query: period (7d|30d|90d), channel (all|id), sortBy (comments|sentiment|medical), 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:TopContent')

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 sortBy = searchParams.get('sortBy') || 'comments'
    const limit = parseInt(searchParams.get('limit') || '10')

    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() },
      linkedContent: { exists: true },
    }

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

    // Fetch interactions with linked content
    const interactions = await payload.find({
      collection: 'community-interactions',
      where: baseWhere,
      limit: 10000,
      depth: 2, // Include linkedContent and socialAccount
    })

    // Group by content
    const contentMap: Map<
      number,
      {
        content: {
          id: number
          videoId?: string
          title?: string
          thumbnailUrl?: string
          publishedAt?: string
        }
        channelName: string
        interactions: typeof interactions.docs
      }
    > = new Map()

    interactions.docs.forEach((i) => {
      const linkedContent = i.linkedContent as {
        id: number
        videoId?: string
        title?: string
        thumbnailUrl?: string
        publishedAt?: string
      } | null

      if (!linkedContent) return

      const contentId = linkedContent.id
      if (!contentMap.has(contentId)) {
        const socialAccount = i.socialAccount as { displayName?: string } | null
        contentMap.set(contentId, {
          content: linkedContent,
          channelName: socialAccount?.displayName || 'Unknown',
          interactions: [],
        })
      }
      contentMap.get(contentId)!.interactions.push(i)
    })

    // Calculate metrics per content
    const contentMetrics = Array.from(contentMap.entries()).map(([contentId, data]) => {
      const { content, channelName, interactions: contentInteractions } = data

      const commentCount = contentInteractions.length

      const sentimentScores = contentInteractions
        .filter((i) => i.analysis?.sentimentScore != null)
        .map((i) => i.analysis!.sentimentScore as number)

      const avgSentiment =
        sentimentScores.length > 0
          ? sentimentScores.reduce((a, b) => a + b, 0) / sentimentScores.length
          : 0

      const medicalQuestions = contentInteractions.filter(
        (i) => i.flags?.isMedicalQuestion,
      ).length

      // Top topics
      const topicCounts: Record<string, number> = {}
      contentInteractions.forEach((i) => {
        if (i.analysis?.topics && Array.isArray(i.analysis.topics)) {
          i.analysis.topics.forEach((t: { topic?: string | null }) => {
            if (t.topic) {
              topicCounts[t.topic] = (topicCounts[t.topic] || 0) + 1
            }
          })
        }
      })

      const topTopics = Object.entries(topicCounts)
        .sort(([, a], [, b]) => b - a)
        .slice(0, 5)
        .map(([topic]) => topic)

      return {
        contentId,
        videoId: content.videoId || '',
        title: content.title || 'Untitled',
        channelName,
        thumbnailUrl: content.thumbnailUrl || '',
        commentCount,
        avgSentiment,
        medicalQuestions,
        topTopics,
        publishedAt: content.publishedAt || '',
      }
    })

    // Sort based on sortBy parameter
    contentMetrics.sort((a, b) => {
      switch (sortBy) {
        case 'sentiment':
          return b.avgSentiment - a.avgSentiment
        case 'medical':
          return b.medicalQuestions - a.medicalQuestions
        default: // comments
          return b.commentCount - a.commentCount
      }
    })

    return NextResponse.json({ content: contentMetrics.slice(0, limit) })
  } catch (error: unknown) {
    const errorMessage = error instanceof Error ? error.message : 'Unknown error'
    logger.error('Top content error:', { error: errorMessage })
    return NextResponse.json({ error: 'Failed to fetch top content' }, { status: 500 })
  }
}

export const dynamic = 'force-dynamic'
