/**
 * Rules Engine
 *
 * Wertet Community-Regeln aus und wendet automatische Aktionen an.
 * Wird beim Import neuer Interaktionen aufgerufen.
 */

import type { Payload } from 'payload'

interface RuleAction {
  action: string
  value?: string
  targetUser?: number | { id: number }
  targetTemplate?: number | { id: number }
}

interface RuleTrigger {
  type: string
  keywords?: { keyword: string; matchType: string }[]
  sentimentValues?: string[]
  influencerMinFollowers?: number
}

interface Rule {
  id: number
  name: string
  priority: number
  isActive: boolean
  platforms?: Array<{ id: number } | number>
  channel?: { id: number } | number
  trigger: RuleTrigger
  actions: RuleAction[]
  stats?: {
    timesTriggered?: number
    lastTriggeredAt?: string
  }
}

interface Interaction {
  id: number
  platform?: { id: number } | number
  message?: string
  author?: {
    name?: string
    subscriberCount?: number
    isSubscriber?: boolean
  }
  analysis?: {
    sentiment?: string
    suggestedTemplate?: number
  }
  flags?: {
    isMedicalQuestion?: boolean
    requiresEscalation?: boolean
    isSpam?: boolean
    isFromInfluencer?: boolean
  }
  priority?: string
  linkedContent?: { id: number } | number
}

interface EvaluationResult {
  appliedRules: string[]
  changes: Record<string, unknown>
}

export class RulesEngine {
  private payload: Payload

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

  /**
   * Wertet alle aktiven Regeln für eine Interaktion aus
   */
  async evaluateRules(interactionId: number): Promise<EvaluationResult> {
    const appliedRules: string[] = []
    const changes: Record<string, unknown> = {}

    // Interaktion laden
    const interaction = (await this.payload.findByID({
      collection: 'community-interactions',
      id: interactionId,
      depth: 2,
    })) as Interaction | null

    if (!interaction) {
      throw new Error('Interaction not found')
    }

    // Aktive Regeln nach Priorität sortiert laden
    const rules = await this.payload.find({
      collection: 'community-rules',
      where: {
        isActive: { equals: true },
      },
      sort: 'priority',
      limit: 100,
    })

    for (const doc of rules.docs) {
      const rule = doc as unknown as Rule

      // Platform-Filter prüfen
      if (rule.platforms && rule.platforms.length > 0) {
        const platformIds = rule.platforms.map((p) => (typeof p === 'object' ? p.id : p))
        const interactionPlatformId =
          typeof interaction.platform === 'object' ? interaction.platform.id : interaction.platform

        if (!platformIds.includes(interactionPlatformId as number)) {
          continue
        }
      }

      // Trigger prüfen
      const triggered = await this.checkTrigger(rule, interaction)

      if (triggered) {
        // Aktionen anwenden
        const ruleChanges = await this.applyActions(rule, interaction)
        Object.assign(changes, ruleChanges)
        appliedRules.push(rule.name)

        // Stats aktualisieren
        await this.payload.update({
          collection: 'community-rules',
          id: rule.id,
          data: {
            stats: {
              timesTriggered: (rule.stats?.timesTriggered || 0) + 1,
              lastTriggeredAt: new Date().toISOString(),
            },
          },
        })
      }
    }

    // Änderungen an der Interaktion speichern
    if (Object.keys(changes).length > 0) {
      await this.payload.update({
        collection: 'community-interactions',
        id: interactionId,
        data: changes,
      })
    }

    return { appliedRules, changes }
  }

  /**
   * Prüft ob ein Trigger zutrifft
   */
  private async checkTrigger(rule: Rule, interaction: Interaction): Promise<boolean> {
    const { trigger } = rule
    const message = interaction.message?.toLowerCase() || ''

    switch (trigger.type) {
      case 'keyword':
        if (!trigger.keywords?.length) return false
        return trigger.keywords.some(({ keyword, matchType }) => {
          const kw = keyword.toLowerCase()
          switch (matchType) {
            case 'exact':
              return message === kw
            case 'regex':
              try {
                return new RegExp(keyword, 'i').test(interaction.message || '')
              } catch {
                return false
              }
            case 'contains':
            default:
              return message.includes(kw)
          }
        })

      case 'sentiment':
        if (!trigger.sentimentValues?.length) return false
        return trigger.sentimentValues.includes(interaction.analysis?.sentiment || '')

      case 'influencer':
        const minFollowers = trigger.influencerMinFollowers || 10000
        return (interaction.author?.subscriberCount || 0) >= minFollowers

      case 'medical':
        return interaction.flags?.isMedicalQuestion === true

      case 'new_subscriber':
        return interaction.author?.isSubscriber === true

      case 'negative_sentiment':
        return interaction.analysis?.sentiment === 'negative'

      case 'positive_sentiment':
        return interaction.analysis?.sentiment === 'positive'

      case 'all':
        // Immer auslösen (für Default-Regeln)
        return true

      default:
        return false
    }
  }

  /**
   * Wendet die Aktionen einer Regel an
   */
  private async applyActions(
    rule: Rule,
    interaction: Interaction
  ): Promise<Record<string, unknown>> {
    const changes: Record<string, unknown> = {}

    for (const action of rule.actions) {
      switch (action.action) {
        case 'set_priority':
          if (action.value) {
            changes.priority = action.value
          }
          break

        case 'assign_to':
          const userId = typeof action.targetUser === 'object' ? action.targetUser.id : action.targetUser
          if (userId) {
            changes.assignedTo = userId
          }
          break

        case 'apply_template':
          const templateId =
            typeof action.targetTemplate === 'object' ? action.targetTemplate.id : action.targetTemplate
          if (templateId) {
            // Nested update für analysis.suggestedTemplate
            const currentAnalysis = interaction.analysis || {}
            changes.analysis = {
              ...currentAnalysis,
              suggestedTemplate: templateId,
            }
          }
          break

        case 'flag':
          // Flags werden als separate Objekte aktualisiert
          const currentFlags = interaction.flags || {}
          if (action.value === 'medical') {
            changes.flags = { ...currentFlags, isMedicalQuestion: true }
          } else if (action.value === 'escalation') {
            changes.flags = { ...currentFlags, requiresEscalation: true }
          } else if (action.value === 'spam') {
            changes.flags = { ...currentFlags, isSpam: true }
          } else if (action.value === 'influencer') {
            changes.flags = { ...currentFlags, isFromInfluencer: true }
          }
          break

        case 'set_status':
          if (action.value) {
            changes.status = action.value
          }
          break

        case 'notify':
          await this.sendNotification(action, interaction, rule)
          break

        case 'auto_reply':
          // Auto-Reply könnte hier implementiert werden
          // Für jetzt nur loggen
          console.log(`[RulesEngine] Auto-reply triggered for interaction ${interaction.id}`)
          break
      }
    }

    return changes
  }

  /**
   * Sendet eine Benachrichtigung
   */
  private async sendNotification(
    action: RuleAction,
    interaction: Interaction,
    rule: Rule
  ): Promise<void> {
    const userId = typeof action.targetUser === 'object' ? action.targetUser.id : action.targetUser

    if (!userId) return

    try {
      const relatedVideo =
        typeof interaction.linkedContent === 'object'
          ? interaction.linkedContent.id
          : interaction.linkedContent

      // Prüfen ob yt-notifications Collection existiert
      await this.payload.create({
        collection: 'yt-notifications',
        data: {
          recipient: userId,
          type: 'system',
          title: `🔔 Rule "${rule.name}" triggered`,
          message: `New interaction from ${interaction.author?.name || 'Unknown'}: "${(interaction.message || '').substring(0, 100)}..."`,
          relatedVideo,
          read: false,
        },
      })
    } catch (error) {
      // Collection existiert möglicherweise nicht - nur loggen, nicht crashen
      console.warn('[RulesEngine] Failed to create notification:', error)
    }
  }
}

/**
 * Singleton-Instanz für einfachen Zugriff
 */
let rulesEngineInstance: RulesEngine | null = null

export function getRulesEngine(payload: Payload): RulesEngine {
  if (!rulesEngineInstance) {
    rulesEngineInstance = new RulesEngine(payload)
  }
  return rulesEngineInstance
}
