/**
 * YouTube OAuth Callback
 *
 * Verarbeitet den OAuth Callback von Google und speichert die Tokens.
 *
 * GET /api/youtube/callback?code=...&state=...
 */

import { NextRequest, NextResponse } from 'next/server'
import { getPayload } from 'payload'
import config from '@payload-config'
import { getTokensFromCode, getAuthenticatedChannel } from '@/lib/integrations/youtube/oauth'
import { createSafeLogger } from '@/lib/security'

const logger = createSafeLogger('API:YouTubeCallback')

interface StatePayload {
  socialAccountId: string
  userId: number
  timestamp: number
}

export async function GET(req: NextRequest) {
  const searchParams = req.nextUrl.searchParams
  const code = searchParams.get('code')
  const state = searchParams.get('state')
  const error = searchParams.get('error')
  const errorDescription = searchParams.get('error_description')

  const baseUrl = process.env.NEXT_PUBLIC_SERVER_URL || ''

  // Fehler von Google
  if (error) {
    logger.error('OAuth error from Google:', { error, errorDescription })
    return NextResponse.redirect(
      `${baseUrl}/admin/collections/social-accounts?error=${encodeURIComponent(errorDescription || error)}`
    )
  }

  // Fehlende Parameter
  if (!code || !state) {
    logger.warn('Missing OAuth parameters')
    return NextResponse.redirect(
      `${baseUrl}/admin/collections/social-accounts?error=missing_params`
    )
  }

  try {
    // State decodieren
    let statePayload: StatePayload
    try {
      statePayload = JSON.parse(Buffer.from(state, 'base64').toString())
    } catch {
      logger.error('Invalid state parameter')
      return NextResponse.redirect(
        `${baseUrl}/admin/collections/social-accounts?error=invalid_state`
      )
    }

    const { socialAccountId } = statePayload

    // State-Alter prüfen (max 10 Minuten)
    const stateAge = Date.now() - statePayload.timestamp
    if (stateAge > 10 * 60 * 1000) {
      logger.warn('State expired', { age: stateAge })
      return NextResponse.redirect(
        `${baseUrl}/admin/collections/social-accounts?error=state_expired`
      )
    }

    // Tokens von Google abrufen
    const tokens = await getTokensFromCode(code)

    if (!tokens.access_token) {
      throw new Error('No access token received from Google')
    }

    // Kanal-Informationen abrufen
    const channel = await getAuthenticatedChannel(tokens.access_token)

    if (!channel) {
      throw new Error('Could not retrieve channel information')
    }

    const payload = await getPayload({ config })

    // Social Account aktualisieren
    await payload.update({
      collection: 'social-accounts',
      id: parseInt(socialAccountId, 10),
      data: {
        externalId: channel.id,
        accountHandle: channel.snippet?.customUrl || `@${channel.snippet?.title}`,
        accountUrl: `https://www.youtube.com/channel/${channel.id}`,
        credentials: {
          accessToken: tokens.access_token,
          refreshToken: tokens.refresh_token || undefined,
          tokenExpiresAt: tokens.expiry_date
            ? new Date(tokens.expiry_date).toISOString()
            : undefined,
        },
        stats: {
          followers: parseInt(channel.statistics?.subscriberCount || '0', 10),
          totalPosts: parseInt(channel.statistics?.videoCount || '0', 10),
          lastSyncedAt: new Date().toISOString(),
        },
      },
    })

    logger.info('YouTube OAuth completed', {
      socialAccountId,
      channelId: channel.id,
      channelTitle: channel.snippet?.title,
    })

    return NextResponse.redirect(
      `${baseUrl}/admin/collections/social-accounts/${socialAccountId}?success=connected`
    )
  } catch (err: unknown) {
    const errorMessage = err instanceof Error ? err.message : 'Unknown error'
    logger.error('OAuth callback error:', { error: errorMessage })

    return NextResponse.redirect(
      `${baseUrl}/admin/collections/social-accounts?error=${encodeURIComponent(errorMessage)}`
    )
  }
}
