// src/lib/integrations/meta/FacebookSyncService.ts
// Facebook Comments Sync Service

import type { Payload } from 'payload'
import { FacebookClient } from './FacebookClient'
import { ClaudeAnalysisService } from '../claude/ClaudeAnalysisService'
import type { FacebookPost, FacebookComment, MetaSyncResult, MetaSyncOptions } from '@/types/meta'

// =============================================================================
// Types
// =============================================================================

interface FacebookSyncOptions extends MetaSyncOptions {
  /** Sync auch Kommentar-Replies */
  syncReplies?: boolean
  /** Maximale Posts pro Sync */
  maxPosts?: number
}

interface ProcessedComment {
  isNew: boolean
  interactionId: number
}

// =============================================================================
// Facebook Sync Service
// =============================================================================

export class FacebookSyncService {
  private payload: Payload
  private claudeService: ClaudeAnalysisService
  private platformId: number | null = null

  constructor(payload: Payload) {
    this.payload = payload
    this.claudeService = new ClaudeAnalysisService()
  }

  /**
   * Holt die Platform ID für Facebook
   */
  private async getPlatformId(): Promise<number | null> {
    if (this.platformId) return this.platformId

    const platform = await this.payload.find({
      collection: 'social-platforms',
      where: {
        or: [
          { slug: { equals: 'facebook' } },
          { 'apiConfig.apiType': { equals: 'facebook_graph' } },
          { 'apiConfig.apiType': { equals: 'meta_graph' } },
        ],
      },
      limit: 1,
    })

    if (platform.docs[0]) {
      this.platformId = platform.docs[0].id as number
    }

    return this.platformId
  }

  /**
   * Hauptmethode: Synchronisiert Kommentare für einen Facebook Social Account
   */
  async syncComments(options: FacebookSyncOptions): Promise<MetaSyncResult> {
    const {
      socialAccountId,
      sinceDate,
      maxItems = 100,
      maxPosts = 25,
      syncComments = true,
      syncReplies = true,
      analyzeWithAI = true,
    } = options

    const startTime = Date.now()
    const result: MetaSyncResult = {
      accountId: socialAccountId,
      accountName: '',
      platform: 'facebook',
      postsProcessed: 0,
      newComments: 0,
      updatedComments: 0,
      newMessages: 0,
      errors: [],
      duration: 0,
    }

    try {
      // 1. Social Account laden
      const account = await this.payload.findByID({
        collection: 'social-accounts',
        id: socialAccountId,
        depth: 2,
      })

      if (!account) {
        result.errors.push('Social Account nicht gefunden')
        return this.finalizeResult(result, startTime)
      }

      result.accountName = (account.displayName as string) || `Account ${socialAccountId}`

      // 2. Platform prüfen
      const platform = account.platform as { slug?: string; apiConfig?: { apiType?: string } }
      const isMetaPlatform =
        platform?.slug === 'facebook' ||
        platform?.apiConfig?.apiType === 'facebook_graph' ||
        platform?.apiConfig?.apiType === 'meta_graph'

      if (!isMetaPlatform) {
        result.errors.push('Account ist kein Facebook-Account')
        return this.finalizeResult(result, startTime)
      }

      // 3. Credentials prüfen
      const credentials = account.credentials as {
        accessToken?: string
        pageAccessToken?: string
      }

      if (!credentials?.accessToken) {
        result.errors.push('Keine gültigen API-Credentials')
        return this.finalizeResult(result, startTime)
      }

      // 4. Facebook Client initialisieren
      const pageId = account.externalId as string
      if (!pageId) {
        result.errors.push('Keine Page ID gefunden')
        return this.finalizeResult(result, startTime)
      }

      const facebookClient = new FacebookClient({
        userAccessToken: credentials.accessToken,
        pageId,
        pageAccessToken: credentials.pageAccessToken,
      })

      // 5. Posts abrufen
      const posts = await facebookClient.getPosts({
        limit: maxPosts,
        since: sinceDate,
      })

      console.log(`[FacebookSync] Found ${posts.length} posts for account ${socialAccountId}`)

      // 6. Für jeden Post: Kommentare synchronisieren
      if (syncComments) {
        for (const post of posts) {
          try {
            const postResult = await this.syncPostComments({
              facebookClient,
              post,
              account,
              maxComments: Math.ceil(maxItems / posts.length),
              syncReplies,
              analyzeWithAI,
            })

            result.postsProcessed++
            result.newComments += postResult.newComments
            result.updatedComments += postResult.updatedComments
          } catch (error) {
            const errorMsg = error instanceof Error ? error.message : String(error)
            result.errors.push(`Post ${post.id}: ${errorMsg}`)
          }

          // Rate Limiting zwischen Posts
          await this.sleep(200)
        }
      }

      // 7. Account-Stats aktualisieren
      await this.payload.update({
        collection: 'social-accounts',
        id: socialAccountId,
        data: {
          stats: {
            lastSyncedAt: new Date().toISOString(),
            totalPosts: posts.length,
          },
        },
      })

      console.log(
        `[FacebookSync] Completed: ${result.newComments} new, ${result.updatedComments} updated`
      )
    } catch (error) {
      const errorMsg = error instanceof Error ? error.message : String(error)
      result.errors.push(`Sync-Fehler: ${errorMsg}`)
      console.error('[FacebookSync] Error:', error)
    }

    return this.finalizeResult(result, startTime)
  }

  /**
   * Synchronisiert Kommentare eines einzelnen Posts
   */
  private async syncPostComments(options: {
    facebookClient: FacebookClient
    post: FacebookPost
    account: any
    maxComments: number
    syncReplies: boolean
    analyzeWithAI: boolean
  }): Promise<{ newComments: number; updatedComments: number }> {
    const { facebookClient, post, account, maxComments, syncReplies, analyzeWithAI } = options

    let newComments = 0
    let updatedComments = 0

    // Kommentare abrufen
    const comments = await facebookClient.getPostComments(post.id, {
      limit: maxComments,
      filter: syncReplies ? 'stream' : 'toplevel',
      order: 'reverse_time',
    })

    for (const comment of comments) {
      try {
        const processResult = await this.processComment({
          comment,
          post,
          account,
          analyzeWithAI,
        })

        if (processResult.isNew) {
          newComments++
        } else {
          updatedComments++
        }
      } catch (error) {
        console.error(`[FacebookSync] Error processing comment ${comment.id}:`, error)
      }

      // Rate Limiting
      await this.sleep(50)
    }

    return { newComments, updatedComments }
  }

  /**
   * Verarbeitet einen einzelnen Kommentar
   */
  private async processComment(options: {
    comment: FacebookComment
    post: FacebookPost
    account: any
    analyzeWithAI: boolean
  }): Promise<ProcessedComment> {
    const { comment, post, account, analyzeWithAI } = options

    // Prüfen ob Kommentar bereits existiert
    const existing = await this.payload.find({
      collection: 'community-interactions',
      where: {
        externalId: { equals: comment.id },
      },
      limit: 1,
    })

    const isNew = existing.totalDocs === 0

    // AI-Analyse durchführen
    let analysis = null
    if (analyzeWithAI && isNew) {
      try {
        analysis = await this.claudeService.analyzeComment(comment.message)
      } catch (error) {
        console.warn('[FacebookSync] AI analysis failed:', error)
      }
    }

    // Platform ID holen
    const platformId = await this.getPlatformId()
    if (platformId === null) {
      throw new Error('Facebook platform not configured')
    }

    // Interaction-Typ bestimmen (comment oder reply)
    const interactionType = comment.parent?.id ? 'reply' : 'comment'

    // Parent-Interaction finden (falls Reply)
    let parentInteractionId = null
    if (comment.parent?.id) {
      const parent = await this.payload.find({
        collection: 'community-interactions',
        where: {
          externalId: { equals: comment.parent.id },
        },
        limit: 1,
      })
      if (parent.docs[0]) {
        parentInteractionId = parent.docs[0].id
      }
    }

    // Interaction-Daten zusammenstellen
    const interactionData = {
      platform: platformId,
      socialAccount: account.id,
      type: interactionType as 'comment' | 'reply',
      externalId: comment.id,
      parentInteraction: parentInteractionId,
      author: {
        name: comment.from?.name || 'Unknown',
        handle: comment.from?.id,
        profileUrl: comment.from?.id
          ? `https://facebook.com/${comment.from.id}`
          : undefined,
        isVerified: false,
        isSubscriber: false,
        isMember: false,
      },
      message: comment.message,
      publishedAt: new Date(comment.created_time).toISOString(),
      engagement: {
        likes: comment.like_count || 0,
        replies: comment.comment_count || 0,
        isHearted: false,
        isPinned: false,
      },
      // Attachment wenn vorhanden
      ...(comment.attachment && {
        attachments: [
          {
            type:
              comment.attachment.type === 'photo'
                ? 'image'
                : comment.attachment.type === 'video'
                  ? 'video'
                  : 'link' as 'image' | 'video' | 'link',
            url: comment.attachment.url || comment.attachment.media?.image?.src,
          },
        ],
      }),
      // AI-Analyse wenn verfügbar
      ...(analysis && {
        analysis: {
          sentiment: analysis.sentiment,
          sentimentScore: analysis.sentimentScore,
          confidence: analysis.confidence,
          topics: analysis.topics.map((t: string) => ({ topic: t })),
          language: analysis.language,
          suggestedReply: analysis.suggestedReply,
          analyzedAt: new Date().toISOString(),
        },
        flags: {
          isMedicalQuestion: analysis.isMedicalQuestion,
          requiresEscalation: analysis.requiresEscalation,
          isSpam: analysis.isSpam,
          isFromInfluencer: false,
        },
      }),
      // Interne Notizen mit Post-Kontext
      internalNotes: `Facebook Post: ${post.permalink_url || post.id}`,
      status: 'new' as const,
      priority: 'normal' as const,
    }

    let interactionId: number

    if (isNew) {
      const created = await this.payload.create({
        collection: 'community-interactions',
        draft: false,
        data: interactionData,
      })
      interactionId = created.id as number
    } else {
      // Update: Behalte existierende Workflow-Daten
      const existingDoc = existing.docs[0]
      await this.payload.update({
        collection: 'community-interactions',
        id: existingDoc.id,
        data: {
          ...interactionData,
          // Behalte Workflow-Status
          status: existingDoc.status,
          priority: existingDoc.priority,
          assignedTo: existingDoc.assignedTo,
          response: existingDoc.response,
          internalNotes: existingDoc.internalNotes,
        },
      })
      interactionId = existingDoc.id as number
    }

    return { isNew, interactionId }
  }

  /**
   * Finalisiert das Ergebnis mit Zeitdauer
   */
  private finalizeResult(result: MetaSyncResult, startTime: number): MetaSyncResult {
    result.duration = Date.now() - startTime
    return result
  }

  /**
   * Hilfsmethode: Sleep
   */
  private sleep(ms: number): Promise<void> {
    return new Promise((resolve) => setTimeout(resolve, ms))
  }
}

export default FacebookSyncService
