// src/lib/integrations/youtube/ChannelMetricsSyncService.ts

import type { Payload } from 'payload'

import { YouTubeClient } from './YouTubeClient'

interface ChannelMetricsSyncResult {
  success: boolean
  channelsSynced: number
  errors: string[]
}

/**
 * Syncs channel-level statistics from YouTube API to YouTubeChannels.currentMetrics fields.
 *
 * For each active YouTube channel, fetches subscriber count, video count, and total views
 * via the YouTube Data API and persists them in the database.
 */
export class ChannelMetricsSyncService {
  private payload: Payload

  constructor(payload: Payload) {
    this.payload = payload
  }

  /**
   * Sync metrics for all active YouTube channels.
   *
   * Finds every channel with status "active", resolves its linked social account
   * for API credentials, calls getChannelStats, and updates currentMetrics.
   */
  async syncAllChannels(): Promise<ChannelMetricsSyncResult> {
    const result: ChannelMetricsSyncResult = {
      success: false,
      channelsSynced: 0,
      errors: [],
    }

    try {
      // 1. Find all active YouTube channels
      const channels = await this.payload.find({
        collection: 'youtube-channels',
        where: {
          status: { equals: 'active' },
        },
        limit: 0,
        depth: 0,
      })

      if (channels.docs.length === 0) {
        result.success = true
        return result
      }

      // 2. Process each channel
      for (const channel of channels.docs) {
        const channelName = (channel as any).name ?? `ID ${channel.id}`
        const youtubeChannelId = (channel as any).youtubeChannelId as string | undefined

        if (!youtubeChannelId) {
          result.errors.push(`Channel "${channelName}" has no youtubeChannelId, skipping`)
          continue
        }

        try {
          await this.syncSingleChannel(channel, youtubeChannelId)
          result.channelsSynced++
        } catch (error) {
          result.errors.push(`Failed to sync channel "${channelName}": ${error}`)
        }
      }

      result.success = result.errors.length === 0
    } catch (error) {
      result.errors.push(`Sync error: ${error}`)
    }

    return result
  }

  /**
   * Sync metrics for a single YouTube channel.
   */
  private async syncSingleChannel(
    channel: { id: number | string },
    youtubeChannelId: string,
  ): Promise<void> {
    // 1. Find the social account linked to this channel
    const socialAccounts = await this.payload.find({
      collection: 'social-accounts',
      where: {
        linkedChannel: { equals: channel.id },
        isActive: { equals: true },
      },
      limit: 1,
    })

    const account = socialAccounts.docs[0]
    if (!account) {
      throw new Error(`No active social account found for channel ${channel.id}`)
    }

    // 2. Validate credentials
    const credentials = account.credentials as {
      accessToken?: string
      refreshToken?: string
    } | undefined

    if (!credentials?.accessToken || !credentials?.refreshToken) {
      throw new Error('No valid API credentials on social account')
    }

    // 3. Initialize YouTube client
    const youtubeClient = new YouTubeClient(
      {
        clientId: process.env.GOOGLE_CLIENT_ID!,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
        accessToken: credentials.accessToken,
        refreshToken: credentials.refreshToken,
      },
      this.payload,
    )

    // 4. Fetch channel statistics from YouTube
    const stats = await youtubeClient.getChannelStats(youtubeChannelId)

    // 5. Update currentMetrics fields
    await this.payload.update({
      collection: 'youtube-channels',
      id: channel.id,
      data: {
        currentMetrics: {
          subscriberCount: stats.subscriberCount,
          totalViews: stats.viewCount,
          videoCount: stats.videoCount,
          lastSyncedAt: new Date().toISOString(),
        },
      },
    })
  }
}

export type { ChannelMetricsSyncResult }
