/**
 * YouTube OAuth Service
 *
 * Verwaltet die OAuth 2.0 Authentifizierung für YouTube API.
 */

import { google } from 'googleapis'

const SCOPES = [
  'https://www.googleapis.com/auth/youtube.readonly',
  'https://www.googleapis.com/auth/youtube.force-ssl',
  'https://www.googleapis.com/auth/youtube',
  'https://www.googleapis.com/auth/youtube.upload',
  'https://www.googleapis.com/auth/yt-analytics.readonly',
]

/**
 * Erstellt einen konfigurierten OAuth2 Client
 */
export function getOAuth2Client() {
  const clientId = process.env.YOUTUBE_CLIENT_ID
  const clientSecret = process.env.YOUTUBE_CLIENT_SECRET
  const redirectUri =
    process.env.YOUTUBE_REDIRECT_URI ||
    `${process.env.NEXT_PUBLIC_SERVER_URL}/api/youtube/callback`

  if (!clientId || !clientSecret) {
    throw new Error('YouTube OAuth credentials not configured. Set YOUTUBE_CLIENT_ID and YOUTUBE_CLIENT_SECRET.')
  }

  return new google.auth.OAuth2(clientId, clientSecret, redirectUri)
}

/**
 * Generiert die OAuth Autorisierungs-URL
 */
export function getAuthUrl(state?: string): string {
  const oauth2Client = getOAuth2Client()

  return oauth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: SCOPES,
    prompt: 'consent', // Immer Consent anfordern für Refresh Token
    state: state,
  })
}

/**
 * Tauscht den Authorization Code gegen Tokens
 */
export async function getTokensFromCode(code: string) {
  const oauth2Client = getOAuth2Client()
  const { tokens } = await oauth2Client.getToken(code)
  return tokens
}

/**
 * Erneuert den Access Token mit dem Refresh Token
 */
export async function refreshAccessToken(refreshToken: string) {
  const oauth2Client = getOAuth2Client()
  oauth2Client.setCredentials({ refresh_token: refreshToken })

  const { credentials } = await oauth2Client.refreshAccessToken()
  return credentials
}

/**
 * Validiert ob ein Token noch gültig ist
 */
export function isTokenExpired(expiresAt: string | Date | null | undefined): boolean {
  if (!expiresAt) return true

  const expiry = typeof expiresAt === 'string' ? new Date(expiresAt) : expiresAt
  // Token als abgelaufen markieren 5 Minuten bevor er tatsächlich abläuft
  const bufferMs = 5 * 60 * 1000
  return expiry.getTime() - bufferMs < Date.now()
}

/**
 * Holt die Kanal-Informationen des authentifizierten Users
 */
export async function getAuthenticatedChannel(accessToken: string) {
  const oauth2Client = getOAuth2Client()
  oauth2Client.setCredentials({ access_token: accessToken })

  const youtube = google.youtube({ version: 'v3', auth: oauth2Client })

  const response = await youtube.channels.list({
    part: ['snippet', 'statistics', 'contentDetails'],
    mine: true,
  })

  return response.data.items?.[0]
}
