// src/lib/integrations/meta/InstagramSyncService.ts
// Instagram Comments & Mentions Sync Service

import type { Payload } from 'payload'
import { InstagramClient } from './InstagramClient'
import { ClaudeAnalysisService } from '../claude/ClaudeAnalysisService'
import type {
  InstagramMedia,
  InstagramComment,
  InstagramMention,
  MetaSyncResult,
  MetaSyncOptions,
} from '@/types/meta'

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

interface InstagramSyncOptions extends MetaSyncOptions {
  /** Sync auch Mentions (wo Account getaggt wurde) */
  syncMentions?: boolean
  /** Maximale Media pro Sync */
  maxMedia?: number
}

interface ProcessedComment {
  isNew: boolean
  interactionId: number
}

// =============================================================================
// Instagram Sync Service
// =============================================================================

export class InstagramSyncService {
  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 Instagram
   */
  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: 'instagram' } },
          { 'apiConfig.apiType': { equals: 'instagram_graph' } },
        ],
      },
      limit: 1,
    })

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

    return this.platformId
  }

  /**
   * Hauptmethode: Synchronisiert Kommentare für einen Instagram Account
   */
  async syncComments(options: InstagramSyncOptions): Promise<MetaSyncResult> {
    const {
      socialAccountId,
      sinceDate,
      maxItems = 100,
      maxMedia = 25,
      syncComments = true,
      syncMentions = true,
      analyzeWithAI = true,
    } = options

    const startTime = Date.now()
    const result: MetaSyncResult = {
      accountId: socialAccountId,
      accountName: '',
      platform: 'instagram',
      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 isInstagramPlatform =
        platform?.slug === 'instagram' ||
        platform?.apiConfig?.apiType === 'instagram_graph'

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

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

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

      // 4. Instagram Account ID prüfen
      const instagramAccountId = account.externalId as string
      if (!instagramAccountId) {
        result.errors.push('Keine Instagram Account ID gefunden')
        return this.finalizeResult(result, startTime)
      }

      // 5. Instagram Client initialisieren
      const instagramClient = new InstagramClient({
        pageAccessToken: credentials.accessToken,
        instagramAccountId,
      })

      // 6. Media (Posts) abrufen
      const media = await instagramClient.getMedia({ limit: maxMedia })
      console.log(`[InstagramSync] Found ${media.length} media for account ${socialAccountId}`)

      // 7. Für jedes Media: Kommentare synchronisieren
      if (syncComments) {
        for (const mediaItem of media) {
          // Filter nach Datum wenn angegeben
          if (sinceDate && new Date(mediaItem.timestamp) < sinceDate) {
            continue
          }

          try {
            const mediaResult = await this.syncMediaComments({
              instagramClient,
              media: mediaItem,
              account,
              maxComments: Math.ceil(maxItems / media.length),
              analyzeWithAI,
            })

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

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

      // 8. Mentions synchronisieren
      if (syncMentions) {
        try {
          const mentionsResult = await this.syncMentions({
            instagramClient,
            account,
            analyzeWithAI,
          })
          result.newComments += mentionsResult.newMentions
        } catch (error) {
          const errorMsg = error instanceof Error ? error.message : String(error)
          result.errors.push(`Mentions: ${errorMsg}`)
        }
      }

      // 9. Account-Stats aktualisieren
      try {
        const stats = await instagramClient.getAccountStats()
        await this.payload.update({
          collection: 'social-accounts',
          id: socialAccountId,
          data: {
            stats: {
              followers: stats.followers,
              totalPosts: stats.mediaCount,
              lastSyncedAt: new Date().toISOString(),
            },
          },
        })
      } catch (error) {
        console.warn('[InstagramSync] Could not update stats:', error)
      }

      console.log(
        `[InstagramSync] 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('[InstagramSync] Error:', error)
    }

    return this.finalizeResult(result, startTime)
  }

  /**
   * Synchronisiert Kommentare eines einzelnen Media
   */
  private async syncMediaComments(options: {
    instagramClient: InstagramClient
    media: InstagramMedia
    account: any
    maxComments: number
    analyzeWithAI: boolean
  }): Promise<{ newComments: number; updatedComments: number }> {
    const { instagramClient, media, account, maxComments, analyzeWithAI } = options

    let newComments = 0
    let updatedComments = 0

    // Kommentare abrufen
    const comments = await instagramClient.getMediaComments(media.id, {
      limit: maxComments,
    })

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

        if (processResult.isNew) {
          newComments++
        } else {
          updatedComments++
        }

        // Auch Replies verarbeiten
        if (comment.replies?.data) {
          for (const reply of comment.replies.data) {
            try {
              const replyResult = await this.processComment({
                comment: reply,
                media,
                account,
                analyzeWithAI,
                parentCommentId: comment.id,
              })

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

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

    return { newComments, updatedComments }
  }

  /**
   * Verarbeitet einen einzelnen Kommentar
   */
  private async processComment(options: {
    comment: InstagramComment
    media: InstagramMedia
    account: any
    analyzeWithAI: boolean
    parentCommentId?: string
  }): Promise<ProcessedComment> {
    const { comment, media, account, analyzeWithAI, parentCommentId } = 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.text)
      } catch (error) {
        console.warn('[InstagramSync] AI analysis failed:', error)
      }
    }

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

    // Interaction-Typ bestimmen
    const interactionType = parentCommentId ? 'reply' : 'comment'

    // Parent-Interaction finden (falls Reply)
    let parentInteractionId = null
    if (parentCommentId) {
      const parent = await this.payload.find({
        collection: 'community-interactions',
        where: {
          externalId: { equals: parentCommentId },
        },
        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.username,
        handle: `@${comment.username}`,
        profileUrl: `https://instagram.com/${comment.username}`,
        isVerified: false,
        isSubscriber: false,
        isMember: false,
      },
      message: comment.text,
      publishedAt: new Date(comment.timestamp).toISOString(),
      engagement: {
        likes: comment.like_count || 0,
        replies: comment.replies?.data?.length || 0,
        isHearted: false,
        isPinned: false,
      },
      // 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 Media-Kontext
      internalNotes: `Instagram Post: ${media.permalink}`,
      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 }
  }

  /**
   * Synchronisiert Mentions (Posts wo Account getaggt wurde)
   */
  private async syncMentions(options: {
    instagramClient: InstagramClient
    account: any
    analyzeWithAI: boolean
  }): Promise<{ newMentions: number }> {
    const { instagramClient, account, analyzeWithAI } = options

    let newMentions = 0

    try {
      const mentions = await instagramClient.getMentions(25)

      for (const mention of mentions) {
        try {
          const result = await this.processMention({
            mention,
            account,
            analyzeWithAI,
          })

          if (result.isNew) {
            newMentions++
          }
        } catch (error) {
          console.error(`[InstagramSync] Error processing mention ${mention.id}:`, error)
        }

        await this.sleep(100)
      }
    } catch (error) {
      console.warn('[InstagramSync] Could not sync mentions:', error)
    }

    return { newMentions }
  }

  /**
   * Verarbeitet eine Mention
   */
  private async processMention(options: {
    mention: InstagramMention
    account: any
    analyzeWithAI: boolean
  }): Promise<{ isNew: boolean }> {
    const { mention, account, analyzeWithAI } = options

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

    const isNew = existing.totalDocs === 0

    if (!isNew) {
      return { isNew: false }
    }

    // AI-Analyse für Caption
    let analysis = null
    if (analyzeWithAI && mention.caption) {
      try {
        analysis = await this.claudeService.analyzeComment(mention.caption)
      } catch (error) {
        console.warn('[InstagramSync] AI analysis failed:', error)
      }
    }

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

    // Mention als Interaction speichern
    const interactionData = {
      platform: platformId,
      socialAccount: account.id,
      type: 'mention' as const,
      externalId: `mention_${mention.id}`,
      author: {
        name: mention.username,
        handle: `@${mention.username}`,
        profileUrl: `https://instagram.com/${mention.username}`,
        isVerified: false,
        isSubscriber: false,
        isMember: false,
      },
      message: mention.caption || `[Erwähnung in ${mention.media_type}]`,
      publishedAt: new Date(mention.timestamp).toISOString(),
      engagement: {
        likes: mention.like_count || 0,
        replies: mention.comments_count || 0,
        isHearted: false,
        isPinned: false,
      },
      ...(analysis && {
        analysis: {
          sentiment: analysis.sentiment,
          sentimentScore: analysis.sentimentScore,
          confidence: analysis.confidence,
          topics: analysis.topics.map((t: string) => ({ topic: t })),
          language: analysis.language,
          analyzedAt: new Date().toISOString(),
        },
      }),
      internalNotes: `Instagram Mention: ${mention.permalink}`,
      status: 'new' as const,
      priority: 'normal' as const,
    }

    await this.payload.create({
      collection: 'community-interactions',
      draft: false,
      data: interactionData,
    })

    return { isNew: true }
  }

  /**
   * 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 InstagramSyncService
