/**
 * Community Analytics Response Metrics API
 *
 * Liefert Response-Zeit und Workflow-Metriken.
 *
 * GET /api/community/analytics/response-metrics
 * Query: period (7d|30d|90d), channel (all|id)
 */

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

const logger = createSafeLogger('API:ResponseMetrics')

function median(arr: number[]): number {
  if (arr.length === 0) return 0
  const sorted = [...arr].sort((a, b) => a - b)
  const mid = Math.floor(sorted.length / 2)
  return sorted.length % 2 !== 0 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2
}

function percentile(arr: number[], p: number): number {
  if (arr.length === 0) return 0
  const sorted = [...arr].sort((a, b) => a - b)
  const index = Math.ceil((p / 100) * sorted.length) - 1
  return sorted[Math.max(0, index)]
}

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 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 ranges
    const now = new Date()
    const days = period === '7d' ? 7 : period === '90d' ? 90 : 30
    const periodStart = subDays(now, days)
    const prevPeriodStart = subDays(now, days * 2)
    const prevPeriodEnd = periodStart

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

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

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

    const docs = interactions.docs
    const total = docs.length

    // Calculate response times
    const responseTimes = docs
      .filter((i) => i.response?.sentAt && i.publishedAt)
      .map((i) =>
        differenceInHours(
          new Date(i.response!.sentAt as string),
          new Date(i.publishedAt as string),
        ),
      )

    const medianTime = median(responseTimes)
    const p90Time = percentile(responseTimes, 90)

    // Fetch previous period for trend
    const prevWhere: any = {
      publishedAt: {
        greater_than_equal: prevPeriodStart.toISOString(),
        less_than: prevPeriodEnd.toISOString(),
      },
    }

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

    const prevInteractions = await payload.find({
      collection: 'community-interactions',
      where: prevWhere,
      limit: 10000,
    })

    const prevResponseTimes = prevInteractions.docs
      .filter((i) => i.response?.sentAt && i.publishedAt)
      .map((i) =>
        differenceInHours(
          new Date(i.response!.sentAt as string),
          new Date(i.publishedAt as string),
        ),
      )

    const prevMedian = median(prevResponseTimes)
    const trend = prevMedian > 0 ? ((medianTime - prevMedian) / prevMedian) * 100 : 0

    // Resolution rate (resolved / total)
    const resolvedCount = docs.filter((i) => i.status === 'resolved').length
    const resolutionRate = total > 0 ? (resolvedCount / total) * 100 : 0

    // Escalation rate
    const escalatedCount = docs.filter((i) => i.flags?.requiresEscalation).length
    const escalationRate = total > 0 ? (escalatedCount / total) * 100 : 0

    // Template usage rate (among responded)
    const respondedDocs = docs.filter((i) => i.response?.text)
    const templateUsedCount = respondedDocs.filter((i) => i.response?.usedTemplate).length
    const templateUsageRate =
      respondedDocs.length > 0 ? (templateUsedCount / respondedDocs.length) * 100 : 0

    // By priority
    const priorities = ['urgent', 'high', 'normal', 'low'] as const
    const byPriority: Record<string, { count: number; avgResponseTime: number }> = {}

    for (const priority of priorities) {
      const priorityDocs = docs.filter((i) => i.priority === priority)
      const priorityTimes = priorityDocs
        .filter((i) => i.response?.sentAt && i.publishedAt)
        .map((i) =>
          differenceInHours(
            new Date(i.response!.sentAt as string),
            new Date(i.publishedAt as string),
          ),
        )

      byPriority[priority] = {
        count: priorityDocs.length,
        avgResponseTime:
          priorityTimes.length > 0
            ? priorityTimes.reduce((a, b) => a + b, 0) / priorityTimes.length
            : 0,
      }
    }

    // By status
    const statuses = ['new', 'in_review', 'waiting', 'replied', 'resolved', 'archived', 'spam'] as const
    const byStatus: Record<string, number> = {}

    for (const status of statuses) {
      byStatus[status] = docs.filter((i) => i.status === status).length
    }

    return NextResponse.json({
      firstResponseTime: {
        median: medianTime,
        p90: p90Time,
        trend,
      },
      resolutionRate,
      escalationRate,
      templateUsageRate,
      byPriority,
      byStatus,
    })
  } catch (error: unknown) {
    const errorMessage = error instanceof Error ? error.message : 'Unknown error'
    logger.error('Response metrics error:', { error: errorMessage })
    return NextResponse.json({ error: 'Failed to fetch response metrics' }, { status: 500 })
  }
}

export const dynamic = 'force-dynamic'
