/**
 * Community Export API
 *
 * Exportiert Community-Interaktionen in verschiedenen Formaten.
 * Unterstützt Excel, CSV und PDF.
 *
 * GET /api/community/export?format=excel&dateFrom=...&dateTo=...
 */

import { NextRequest, NextResponse } from 'next/server'
import { getPayload } from 'payload'
import config from '@payload-config'
import ExcelJS from 'exceljs'
import PDFDocument from 'pdfkit'
import { createSafeLogger } from '@/lib/security'
import { hasCommunityApiAccess } from '@/lib/communityAccess'

const logger = createSafeLogger('API:CommunityExport')

export async function GET(req: NextRequest) {
  try {
    const searchParams = req.nextUrl.searchParams
    const format = searchParams.get('format') || 'excel'
    const dateFrom = searchParams.get('dateFrom')
    const dateTo = searchParams.get('dateTo')
    const status = searchParams.get('status')?.split(',').filter(Boolean)
    const platform = searchParams.get('platform')?.split(',').filter(Boolean)
    const sentiment = searchParams.get('sentiment')?.split(',').filter(Boolean)
    const channel = searchParams.get('channel')?.split(',').filter(Boolean)

    const payload = await getPayload({ config })

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

    if (!user) {
      logger.warn('Unauthorized export attempt')
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    const typedUser = user as { id: number }

    // Community-Zugriff prüfen
    if (!hasCommunityApiAccess(user as any, 'viewer')) {
      logger.warn('Access denied for export', { userId: typedUser.id })
      return NextResponse.json({ error: 'Access denied' }, { status: 403 })
    }

    // Build query
    const where: any = {}

    if (dateFrom || dateTo) {
      where.publishedAt = {}
      if (dateFrom) (where.publishedAt as Record<string, string>).greater_than_equal = dateFrom
      if (dateTo) (where.publishedAt as Record<string, string>).less_than_equal = dateTo
    }

    if (status?.length) {
      where.status = { in: status }
    }

    if (platform?.length) {
      where['platform.slug'] = { in: platform }
    }

    if (sentiment?.length) {
      where['analysis.sentiment'] = { in: sentiment }
    }

    if (channel?.length) {
      where['socialAccount'] = { in: channel.map((c) => parseInt(c, 10)).filter((n) => !isNaN(n)) }
    }

    // Fetch interactions
    const interactions = await payload.find({
      collection: 'community-interactions',
      where,
      sort: '-publishedAt',
      limit: 1000,
      depth: 2,
    })

    logger.info('Export generated', {
      format,
      count: interactions.docs.length,
      userId: typedUser.id,
    })

    // Generate export based on format
    switch (format) {
      case 'excel':
        return generateExcel(interactions.docs)
      case 'csv':
        return generateCSV(interactions.docs)
      case 'pdf':
        return generatePDF(interactions.docs)
      default:
        return NextResponse.json({ error: 'Invalid format' }, { status: 400 })
    }
  } catch (error: unknown) {
    const errorMessage = error instanceof Error ? error.message : 'Unknown error'
    logger.error('Export error:', { error: errorMessage })
    return NextResponse.json({ error: errorMessage }, { status: 500 })
  }
}

// Excel Export
async function generateExcel(interactions: unknown[]): Promise<NextResponse> {
  const workbook = new ExcelJS.Workbook()
  workbook.creator = 'Community Hub'
  workbook.created = new Date()

  // Main Data Sheet
  const dataSheet = workbook.addWorksheet('Interactions', {
    views: [{ state: 'frozen', ySplit: 1 }],
  })

  dataSheet.columns = [
    { header: 'ID', key: 'id', width: 8 },
    { header: 'Datum', key: 'date', width: 12 },
    { header: 'Plattform', key: 'platform', width: 12 },
    { header: 'Kanal', key: 'channel', width: 20 },
    { header: 'Autor', key: 'author', width: 20 },
    { header: 'Follower', key: 'followers', width: 12 },
    { header: 'Nachricht', key: 'message', width: 50 },
    { header: 'Sentiment', key: 'sentiment', width: 12 },
    { header: 'Score', key: 'score', width: 8 },
    { header: 'Status', key: 'status', width: 12 },
    { header: 'Priorität', key: 'priority', width: 10 },
    { header: 'Medical', key: 'medical', width: 8 },
    { header: 'Eskalation', key: 'escalation', width: 10 },
    { header: 'Influencer', key: 'influencer', width: 10 },
    { header: 'Zugewiesen', key: 'assigned', width: 20 },
    { header: 'Beantwortet', key: 'repliedAt', width: 12 },
    { header: 'Antwort', key: 'response', width: 50 },
    { header: 'Likes', key: 'likes', width: 8 },
    { header: 'Replies', key: 'replies', width: 8 },
  ]

  // Style header row
  dataSheet.getRow(1).font = { bold: true, color: { argb: 'FFFFFFFF' } }
  dataSheet.getRow(1).fill = {
    type: 'pattern',
    pattern: 'solid',
    fgColor: { argb: 'FF3B82F6' },
  }

  // Add data rows
  for (const item of interactions) {
    const interaction = item as Record<string, unknown>
    const platform = interaction.platform as Record<string, unknown> | undefined
    const socialAccount = interaction.socialAccount as Record<string, unknown> | undefined
    const author = interaction.author as Record<string, unknown> | undefined
    const analysis = interaction.analysis as Record<string, unknown> | undefined
    const flags = interaction.flags as Record<string, unknown> | undefined
    const assignedTo = interaction.assignedTo as Record<string, unknown> | undefined
    const response = interaction.response as Record<string, unknown> | undefined
    const engagement = interaction.engagement as Record<string, unknown> | undefined

    dataSheet.addRow({
      id: interaction.id,
      date: new Date(interaction.publishedAt as string).toLocaleDateString('de-DE'),
      platform: platform?.name || '',
      channel: socialAccount?.displayName || '',
      author: author?.name || '',
      followers: author?.subscriberCount || 0,
      message: ((interaction.message as string) || '').substring(0, 500),
      sentiment: analysis?.sentiment || '',
      score: analysis?.sentimentScore || 0,
      status: getStatusLabel(interaction.status as string),
      priority: getPriorityLabel(interaction.priority as string),
      medical: flags?.isMedicalQuestion ? 'Ja' : '',
      escalation: flags?.requiresEscalation ? 'Ja' : '',
      influencer: flags?.isFromInfluencer ? 'Ja' : '',
      assigned: (assignedTo as Record<string, unknown>)?.email || '',
      repliedAt: response?.sentAt
        ? new Date(response.sentAt as string).toLocaleDateString('de-DE')
        : '',
      response: ((response?.text as string) || '').substring(0, 500),
      likes: engagement?.likes || 0,
      replies: engagement?.replies || 0,
    })
  }

  // Conditional formatting for priority
  dataSheet.eachRow((row, rowNumber) => {
    if (rowNumber > 1) {
      const item = interactions[rowNumber - 2] as Record<string, unknown>
      const priority = item?.priority
      if (priority === 'urgent') {
        row.fill = {
          type: 'pattern',
          pattern: 'solid',
          fgColor: { argb: 'FFFEF2F2' },
        }
      }
    }
  })

  // Summary Sheet
  const summarySheet = workbook.addWorksheet('Zusammenfassung')

  const sentimentCounts = {
    positive: interactions.filter(
      (i) => (i as Record<string, unknown>).analysis &&
        ((i as Record<string, unknown>).analysis as Record<string, unknown>)?.sentiment === 'positive'
    ).length,
    neutral: interactions.filter(
      (i) => (i as Record<string, unknown>).analysis &&
        ((i as Record<string, unknown>).analysis as Record<string, unknown>)?.sentiment === 'neutral'
    ).length,
    negative: interactions.filter(
      (i) => (i as Record<string, unknown>).analysis &&
        ((i as Record<string, unknown>).analysis as Record<string, unknown>)?.sentiment === 'negative'
    ).length,
    mixed: interactions.filter(
      (i) => (i as Record<string, unknown>).analysis &&
        ((i as Record<string, unknown>).analysis as Record<string, unknown>)?.sentiment === 'mixed'
    ).length,
  }

  const statusCounts = {
    new: interactions.filter((i) => (i as Record<string, unknown>).status === 'new').length,
    in_review: interactions.filter((i) => (i as Record<string, unknown>).status === 'in_review').length,
    waiting: interactions.filter((i) => (i as Record<string, unknown>).status === 'waiting').length,
    replied: interactions.filter((i) => (i as Record<string, unknown>).status === 'replied').length,
    resolved: interactions.filter((i) => (i as Record<string, unknown>).status === 'resolved').length,
    archived: interactions.filter((i) => (i as Record<string, unknown>).status === 'archived').length,
    spam: interactions.filter((i) => (i as Record<string, unknown>).status === 'spam').length,
  }

  summarySheet.addRow(['Community Report'])
  summarySheet.addRow(['Erstellt am', new Date().toLocaleString('de-DE')])
  if (interactions.length > 0) {
    const firstItem = interactions[0] as Record<string, unknown>
    const lastItem = interactions[interactions.length - 1] as Record<string, unknown>
    summarySheet.addRow([
      'Zeitraum',
      `${new Date(lastItem.publishedAt as string).toLocaleDateString('de-DE')} - ${new Date(firstItem.publishedAt as string).toLocaleDateString('de-DE')}`,
    ])
  } else {
    summarySheet.addRow(['Zeitraum', 'N/A'])
  }
  summarySheet.addRow([])
  summarySheet.addRow(['Gesamt Interaktionen', interactions.length])
  summarySheet.addRow([])
  summarySheet.addRow(['Sentiment Verteilung'])
  summarySheet.addRow(['Positiv', sentimentCounts.positive])
  summarySheet.addRow(['Neutral', sentimentCounts.neutral])
  summarySheet.addRow(['Negativ', sentimentCounts.negative])
  summarySheet.addRow(['Gemischt', sentimentCounts.mixed])
  summarySheet.addRow([])
  summarySheet.addRow(['Status Verteilung'])
  summarySheet.addRow(['Neu', statusCounts.new])
  summarySheet.addRow(['In Review', statusCounts.in_review])
  summarySheet.addRow(['Warten auf Info', statusCounts.waiting])
  summarySheet.addRow(['Beantwortet', statusCounts.replied])
  summarySheet.addRow(['Erledigt', statusCounts.resolved])
  summarySheet.addRow(['Archiviert', statusCounts.archived])
  summarySheet.addRow(['Spam', statusCounts.spam])
  summarySheet.addRow([])
  summarySheet.addRow(['Flags'])
  summarySheet.addRow([
    'Medizinische Fragen',
    interactions.filter(
      (i) => (i as Record<string, unknown>).flags &&
        ((i as Record<string, unknown>).flags as Record<string, unknown>)?.isMedicalQuestion
    ).length,
  ])
  summarySheet.addRow([
    'Eskalationen',
    interactions.filter(
      (i) => (i as Record<string, unknown>).flags &&
        ((i as Record<string, unknown>).flags as Record<string, unknown>)?.requiresEscalation
    ).length,
  ])
  summarySheet.addRow([
    'Influencer',
    interactions.filter(
      (i) => (i as Record<string, unknown>).flags &&
        ((i as Record<string, unknown>).flags as Record<string, unknown>)?.isFromInfluencer
    ).length,
  ])

  // Style summary
  summarySheet.getRow(1).font = { bold: true, size: 16 }
  summarySheet.getColumn(1).width = 25
  summarySheet.getColumn(2).width = 20

  // Generate buffer
  const buffer = await workbook.xlsx.writeBuffer()

  return new NextResponse(buffer, {
    headers: {
      'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'Content-Disposition': `attachment; filename="community-report-${new Date().toISOString().split('T')[0]}.xlsx"`,
    },
  })
}

// CSV Export
async function generateCSV(interactions: unknown[]): Promise<NextResponse> {
  const headers = [
    'ID',
    'Datum',
    'Plattform',
    'Kanal',
    'Autor',
    'Follower',
    'Nachricht',
    'Sentiment',
    'Score',
    'Status',
    'Priorität',
    'Medical',
    'Eskalation',
    'Influencer',
    'Zugewiesen',
    'Beantwortet',
    'Antwort',
    'Likes',
    'Replies',
  ]

  const rows = interactions.map((item) => {
    const interaction = item as Record<string, unknown>
    const platform = interaction.platform as Record<string, unknown> | undefined
    const socialAccount = interaction.socialAccount as Record<string, unknown> | undefined
    const author = interaction.author as Record<string, unknown> | undefined
    const analysis = interaction.analysis as Record<string, unknown> | undefined
    const flags = interaction.flags as Record<string, unknown> | undefined
    const assignedTo = interaction.assignedTo as Record<string, unknown> | undefined
    const response = interaction.response as Record<string, unknown> | undefined
    const engagement = interaction.engagement as Record<string, unknown> | undefined

    return [
      interaction.id,
      new Date(interaction.publishedAt as string).toISOString(),
      platform?.name || '',
      socialAccount?.displayName || '',
      author?.name || '',
      author?.subscriberCount || 0,
      `"${((interaction.message as string) || '').replace(/"/g, '""').substring(0, 500)}"`,
      analysis?.sentiment || '',
      analysis?.sentimentScore || 0,
      interaction.status,
      interaction.priority,
      flags?.isMedicalQuestion ? 'Ja' : '',
      flags?.requiresEscalation ? 'Ja' : '',
      flags?.isFromInfluencer ? 'Ja' : '',
      (assignedTo as Record<string, unknown>)?.email || '',
      response?.sentAt || '',
      `"${((response?.text as string) || '').replace(/"/g, '""').substring(0, 500)}"`,
      engagement?.likes || 0,
      engagement?.replies || 0,
    ]
  })

  const csv = [headers.join(';'), ...rows.map((row) => row.join(';'))].join('\n')

  // Add BOM for Excel compatibility with German characters
  const bom = '\uFEFF'

  return new NextResponse(bom + csv, {
    headers: {
      'Content-Type': 'text/csv; charset=utf-8',
      'Content-Disposition': `attachment; filename="community-report-${new Date().toISOString().split('T')[0]}.csv"`,
    },
  })
}

// PDF Export
async function generatePDF(interactions: unknown[]): Promise<NextResponse> {
  return new Promise((resolve, reject) => {
    try {
      const doc = new PDFDocument({
        margin: 50,
        size: 'A4',
      })

      const chunks: Buffer[] = []
      doc.on('data', (chunk: Buffer) => chunks.push(chunk))
      doc.on('end', () => {
        const buffer = Buffer.concat(chunks)
        resolve(
          new NextResponse(buffer, {
            headers: {
              'Content-Type': 'application/pdf',
              'Content-Disposition': `attachment; filename="community-report-${new Date().toISOString().split('T')[0]}.pdf"`,
            },
          })
        )
      })

      // Title
      doc.fontSize(24).text('Community Report', { align: 'center' })
      doc.moveDown()
      doc.fontSize(12).text(`Erstellt am: ${new Date().toLocaleString('de-DE')}`, { align: 'center' })
      doc.moveDown(2)

      // Summary Stats
      const sentimentCounts = {
        positive: interactions.filter(
          (i) => ((i as Record<string, unknown>).analysis as Record<string, unknown>)?.sentiment === 'positive'
        ).length,
        negative: interactions.filter(
          (i) => ((i as Record<string, unknown>).analysis as Record<string, unknown>)?.sentiment === 'negative'
        ).length,
        neutral: interactions.filter(
          (i) => ((i as Record<string, unknown>).analysis as Record<string, unknown>)?.sentiment === 'neutral'
        ).length,
      }

      const statusCounts = {
        new: interactions.filter((i) => (i as Record<string, unknown>).status === 'new').length,
        replied: interactions.filter((i) => (i as Record<string, unknown>).status === 'replied').length,
        resolved: interactions.filter((i) => (i as Record<string, unknown>).status === 'resolved').length,
      }

      doc.fontSize(16).text('Übersicht', { underline: true })
      doc.moveDown()
      doc.fontSize(12)
      doc.text(`Gesamt Interaktionen: ${interactions.length}`)
      doc.text(`Davon neu: ${statusCounts.new}`)
      doc.text(`Davon beantwortet: ${statusCounts.replied}`)
      doc.text(`Davon erledigt: ${statusCounts.resolved}`)
      doc.moveDown()

      doc.text(`Positives Sentiment: ${sentimentCounts.positive}`)
      doc.text(`Neutrales Sentiment: ${sentimentCounts.neutral}`)
      doc.text(`Negatives Sentiment: ${sentimentCounts.negative}`)
      doc.moveDown()

      // Flags
      const medicalCount = interactions.filter(
        (i) => ((i as Record<string, unknown>).flags as Record<string, unknown>)?.isMedicalQuestion
      ).length
      const escalationCount = interactions.filter(
        (i) => ((i as Record<string, unknown>).flags as Record<string, unknown>)?.requiresEscalation
      ).length
      const influencerCount = interactions.filter(
        (i) => ((i as Record<string, unknown>).flags as Record<string, unknown>)?.isFromInfluencer
      ).length

      doc.text(`Medizinische Fragen: ${medicalCount}`)
      doc.text(`Eskalationen: ${escalationCount}`)
      doc.text(`Von Influencern: ${influencerCount}`)
      doc.moveDown(2)

      // Recent interactions
      doc.fontSize(16).text('Letzte 20 Interaktionen', { underline: true })
      doc.moveDown()

      const recentInteractions = interactions.slice(0, 20)

      for (const item of recentInteractions) {
        const interaction = item as Record<string, unknown>
        const platform = interaction.platform as Record<string, unknown> | undefined
        const author = interaction.author as Record<string, unknown> | undefined
        const analysis = interaction.analysis as Record<string, unknown> | undefined
        const flags = interaction.flags as Record<string, unknown> | undefined

        // Check if we need a new page
        if (doc.y > 700) {
          doc.addPage()
        }

        doc
          .fontSize(10)
          .fillColor('#6b7280')
          .text(
            `${new Date(interaction.publishedAt as string).toLocaleDateString('de-DE')} | ${platform?.name || 'Unknown'} | ${author?.name || 'Unknown'}`,
            { continued: false }
          )

        const message = (interaction.message as string) || ''
        doc
          .fontSize(11)
          .fillColor('#000000')
          .text(message.substring(0, 200) + (message.length > 200 ? '...' : ''), { continued: false })

        const badges: string[] = []
        if (analysis?.sentiment) badges.push(analysis.sentiment as string)
        if (flags?.isMedicalQuestion) badges.push('Medical')
        if (flags?.requiresEscalation) badges.push('Eskalation')

        doc
          .fontSize(9)
          .fillColor('#3b82f6')
          .text(`Status: ${getStatusLabel(interaction.status as string)} | ${badges.join(' | ')}`)

        doc.moveDown()
      }

      // Footer
      const pageCount = doc.bufferedPageRange().count
      for (let i = 0; i < pageCount; i++) {
        doc.switchToPage(i)
        doc
          .fontSize(8)
          .fillColor('#9ca3af')
          .text(`Seite ${i + 1} von ${pageCount} | Community Hub Report`, 50, doc.page.height - 50, {
            align: 'center',
          })
      }

      doc.end()
    } catch (error) {
      reject(error)
    }
  })
}

// Helper functions
function getStatusLabel(status: string): string {
  const labels: Record<string, string> = {
    new: 'Neu',
    in_review: 'In Review',
    waiting: 'Warten',
    replied: 'Beantwortet',
    resolved: 'Erledigt',
    archived: 'Archiviert',
    spam: 'Spam',
  }
  return labels[status] || status
}

function getPriorityLabel(priority: string): string {
  const labels: Record<string, string> = {
    urgent: 'Dringend',
    high: 'Hoch',
    normal: 'Normal',
    low: 'Niedrig',
  }
  return labels[priority] || priority
}
