/**
 * 🤖 ENHANCED AI CHATBOT WITH TREE INTEGRATION
 * 
 * This is the upgraded chatbot that works seamlessly with the
 * Tree-Based Reminder System, providing contextual, intelligent
 * responses based on where the user is in their journey.
 */

import { prisma } from "./db";
import { sendMessage, sendButtons, type WaButton } from "./waha";
import { ReminderTreeEngine } from "./reminder-tree-engine";

// ═══════════════════════════════════════════════════════════════════
// 🧠 ENHANCED INTENT DETECTION WITH CONTEXT AWARENESS
// ═══════════════════════════════════════════════════════════════════

interface EnhancedIntent {
  primary: string;
  confidence: number;
  context?: 'booking' | 'reminder' | 'support' | 'feedback';
  entities?: Record<string, any>;
  sentiment?: 'positive' | 'neutral' | 'negative';
}

class EnhancedIntentDetector {
  private static readonly INTENT_PATTERNS = {
    // Booking intents
    book_appointment: {
      patterns: [/\b(book|schedule|appointment|reserve|make.*appointment)\b/i],
      keywords: ['book', 'appointment', 'schedule', 'حجز', 'موعد'],
      context: 'booking'
    },
    confirm_appointment: {
      patterns: [/\b(yes|confirm|confirmed|ok|ready|set)\b/i],
      keywords: ['yes', 'confirm', 'ok', 'نعم', 'تأكيد'],
      context: 'booking'
    },
    cancel_appointment: {
      patterns: [/\b(cancel|cancelled|don'?t want|remove)\b/i],
      keywords: ['cancel', 'remove', 'إلغاء', 'الغي'],
      context: 'booking'
    },
    reschedule_appointment: {
      patterns: [/\b(reschedule|change|move|different.*time)\b/i],
      keywords: ['reschedule', 'change', 'move', 'تغيير', 'إعادة جدولة'],
      context: 'booking'
    },

    // Information intents
    ask_hours: {
      patterns: [/\b(hours|open|close|working.*hours|when.*open)\b/i],
      keywords: ['hours', 'open', 'close', 'أوقات', 'ساعات'],
      context: 'support'
    },
    ask_location: {
      patterns: [/\b(where|location|address|directions|map)\b/i],
      keywords: ['where', 'location', 'address', 'وين', 'موقع'],
      context: 'support'
    },
    ask_price: {
      patterns: [/\b(price|cost|how much|fees|pricing)\b/i],
      keywords: ['price', 'cost', 'much', 'سعر', 'كم'],
      context: 'support'
    },

    // Emotional intents
    gratitude: {
      patterns: [/\b(thank|thanks|appreciate|grateful)\b/i],
      keywords: ['thank', 'thanks', 'شكرا', 'مشكور'],
      context: 'support'
    },
    complaint: {
      patterns: [/\b(problem|issue|wrong|bad|terrible|disappointed)\b/i],
      keywords: ['problem', 'issue', 'bad', 'مشكلة', 'سيء'],
      context: 'feedback'
    },
    compliment: {
      patterns: [/\b(great|excellent|amazing|wonderful|perfect|love)\b/i],
      keywords: ['great', 'excellent', 'perfect', 'ممتاز', 'رائع'],
      context: 'feedback'
    },

    // Support intents
    need_help: {
      patterns: [/\b(help|support|assistance|confused)\b/i],
      keywords: ['help', 'support', 'مساعدة', 'ساعدني'],
      context: 'support'
    },
    speak_human: {
      patterns: [/\b(human|person|agent|staff|talk.*someone)\b/i],
      keywords: ['human', 'person', 'agent', 'شخص', 'موظف'],
      context: 'support'
    }
  };

  static detect(text: string, conversationContext?: any): EnhancedIntent {
    const normalizedText = text.toLowerCase().trim();
    let bestMatch: { intent: string; confidence: number; context: string | undefined } = { intent: 'unknown', confidence: 0, context: undefined };

    // Check each intent pattern
    for (const [intentName, config] of Object.entries(this.INTENT_PATTERNS)) {
      let confidence = 0;

      // Pattern matching
      for (const pattern of config.patterns) {
        if (pattern.test(normalizedText)) {
          confidence += 0.4;
        }
      }

      // Keyword matching
      for (const keyword of config.keywords) {
        if (normalizedText.includes(keyword)) {
          confidence += 0.2;
        }
      }

      // Context bonus
      if (conversationContext?.expectedIntent === intentName) {
        confidence += 0.3;
      }

      if (confidence > bestMatch.confidence) {
        bestMatch = {
          intent: intentName,
          confidence,
          context: config.context
        };
      }
    }

    // Sentiment analysis
    const sentiment = this.analyzeSentiment(normalizedText);

    return {
      primary: bestMatch.intent,
      confidence: bestMatch.confidence,
      context: bestMatch.context as any,
      sentiment,
      entities: this.extractEntities(text)
    };
  }

  private static analyzeSentiment(text: string): 'positive' | 'neutral' | 'negative' {
    const positiveWords = ['good', 'great', 'excellent', 'perfect', 'love', 'yes', 'ok', 'thanks', 'ممتاز', 'رائع', 'شكرا'];
    const negativeWords = ['bad', 'terrible', 'hate', 'no', 'cancel', 'problem', 'issue', 'سيء', 'مشكلة', 'لا'];

    const posCount = positiveWords.filter(word => text.includes(word)).length;
    const negCount = negativeWords.filter(word => text.includes(word)).length;

    if (posCount > negCount) return 'positive';
    if (negCount > posCount) return 'negative';
    return 'neutral';
  }

  private static extractEntities(text: string): Record<string, any> {
    const entities: Record<string, any> = {};

    // Extract time references
    const timePatterns = [
      /\b(today|tomorrow|yesterday|اليوم|بكرا|غدا)\b/i,
      /\b(\d{1,2}:\d{2})\b/i,
      /\b(\d{1,2})\s*(am|pm)\b/i,
      /\b(morning|afternoon|evening|night|صباح|مساء|ليل)\b/i
    ];

    for (const pattern of timePatterns) {
      const match = text.match(pattern);
      if (match) {
        entities.timeReference = match[0];
        break;
      }
    }

    // Extract numbers
    const numbers = text.match(/\b\d+\b/g);
    if (numbers) {
      entities.numbers = numbers;
    }

    return entities;
  }
}

// ═══════════════════════════════════════════════════════════════════
// 🎯 CONTEXT-AWARE CONVERSATION MANAGER
// ═══════════════════════════════════════════════════════════════════

interface ConversationState {
  phase: 'greeting' | 'journey_active' | 'support' | 'feedback' | 'escalated';
  journeyId?: string;
  nodeId?: string;
  expectedIntent?: string;
  collectedData?: Record<string, any>;
  emotionalState?: 'calm' | 'frustrated' | 'excited' | 'confused';
  urgencyLevel?: 'low' | 'medium' | 'high' | 'critical';
}

class ConversationManager {
  private static conversationStates = new Map<string, ConversationState>();

  static getState(phone: string): ConversationState {
    return this.conversationStates.get(phone) || {
      phase: 'greeting',
      emotionalState: 'calm',
      urgencyLevel: 'low'
    };
  }

  static updateState(phone: string, updates: Partial<ConversationState>): void {
    const current = this.getState(phone);
    this.conversationStates.set(phone, { ...current, ...updates });
  }

  static async determineResponseStrategy(
    intent: EnhancedIntent,
    state: ConversationState,
    userContext: any
  ): Promise<'immediate' | 'journey' | 'escalate' | 'collect_info'> {
    // Critical issues need immediate handling
    if (intent.sentiment === 'negative' && intent.confidence > 0.6) {
      return 'escalate';
    }

    // If in active journey, let tree handle it
    if (state.journeyId && state.phase === 'journey_active') {
      return 'journey';
    }

    // Information requests
    if (intent.context === 'support' && ['ask_hours', 'ask_location', 'ask_price'].includes(intent.primary)) {
      return 'immediate';
    }

    // Booking requests start a journey
    if (intent.context === 'booking') {
      return 'journey';
    }

    // Default to immediate handling
    return 'immediate';
  }
}

// ═══════════════════════════════════════════════════════════════════
// 🚀 ENHANCED CHATBOT ENGINE
// ═══════════════════════════════════════════════════════════════════

export class EnhancedChatbot {
  /**
   * Main entry point for handling incoming messages
   */
  static async handleMessage(
    clinicId: string,
    phone: string,
    message: string
  ): Promise<void> {
    try {
      console.log(`🤖 Enhanced chatbot processing: ${phone} -> "${message.slice(0, 50)}..."`);

      // Get conversation context
      const conversationState = ConversationManager.getState(phone);
      
      // Get user context (appointment, profile, etc.)
      const userContext = await this.getUserContext(clinicId, phone);
      
      // Detect intent with enhanced analysis
      const intent = EnhancedIntentDetector.detect(message, conversationState);
      
      console.log(`🎯 Intent: ${intent.primary} (${Math.round(intent.confidence * 100)}% confidence, ${intent.sentiment} sentiment)`);

      // Update emotional state based on sentiment
      if (intent.sentiment === 'negative') {
        ConversationManager.updateState(phone, { 
          emotionalState: 'frustrated',
          urgencyLevel: intent.confidence > 0.7 ? 'high' : 'medium'
        });
      }

      // Determine response strategy
      const strategy = await ConversationManager.determineResponseStrategy(intent, conversationState, userContext);
      
      switch (strategy) {
        case 'journey':
          await this.handleJourneyResponse(clinicId, phone, message, intent, userContext, conversationState);
          break;
          
        case 'immediate':
          await this.handleImmediateResponse(clinicId, phone, message, intent, userContext);
          break;
          
        case 'escalate':
          await this.handleEscalation(clinicId, phone, message, intent, userContext);
          break;
          
        case 'collect_info':
          await this.handleInfoCollection(clinicId, phone, message, intent, conversationState);
          break;
      }

    } catch (error) {
      console.error(`❌ Enhanced chatbot error for ${phone}:`, error);
      await this.handleError(clinicId, phone, error);
    }
  }

  /**
   * Handle responses when user is in an active journey
   */
  private static async handleJourneyResponse(
    clinicId: string,
    phone: string,
    message: string,
    intent: EnhancedIntent,
    userContext: any,
    state: ConversationState
  ): Promise<void> {
    // Check if user wants to interrupt the journey
    if (['cancel_appointment', 'speak_human', 'complaint'].includes(intent.primary)) {
      await this.interruptJourney(clinicId, phone, intent, userContext);
      return;
    }

    // If user has an active journey, let the tree engine handle it
    if (userContext.activeJourney) {
      await ReminderTreeEngine.handleUserResponse(userContext.activeJourney.appointmentId, message);
      ConversationManager.updateState(phone, { phase: 'journey_active' });
      return;
    }

    // Start a new journey based on intent
    await this.handleImmediateResponse(clinicId, phone, message, intent, userContext);
  }

  /**
   * Handle immediate responses (info requests, simple questions)
   */
  private static async handleImmediateResponse(
    clinicId: string,
    phone: string,
    message: string,
    intent: EnhancedIntent,
    userContext: any
  ): Promise<void> {
    const clinic = userContext.clinic;
    const isArabic = /[\u0600-\u06FF]/.test(message);

    switch (intent.primary) {
      case 'ask_hours':
        await this.sendHours(phone, clinic, isArabic);
        break;
        
      case 'ask_location':
        await this.sendLocation(phone, clinic, isArabic);
        break;
        
      case 'ask_price':
        await this.sendPricing(phone, clinic, isArabic);
        break;
        
      case 'gratitude':
        await this.sendGratitudeResponse(phone, isArabic);
        break;
        
      case 'book_appointment':
        await this.startBookingJourney(clinicId, phone, userContext);
        break;
        
      default:
        await this.sendGenericHelp(phone, clinic, intent, isArabic);
    }
  }

  /**
   * Handle escalations (complaints, urgent issues)
   */
  private static async handleEscalation(
    clinicId: string,
    phone: string,
    message: string,
    intent: EnhancedIntent,
    userContext: any
  ): Promise<void> {
    const isArabic = /[\u0600-\u06FF]/.test(message);
    
    // Immediate empathetic response
    const escalationMessage = isArabic
      ? `أعتذر بصدق عن أي إزعاج، وأهتم كثيراً بحل مشكلتك.\n\nسيتواصل معك أحد المختصين خلال دقائق.\n\nفي هذه الأثناء، هل يمكنك إخباري بالتفاصيل؟`
      : `I sincerely apologize for any inconvenience, and I care deeply about resolving your concern.\n\nA specialist will contact you within minutes.\n\nMeanwhile, could you please share more details?`;

    await sendMessage(phone, escalationMessage);

    // Flag for immediate human attention
    if (userContext.lead) {
      const currentNotes = userContext.lead.notes || '';
      await prisma.lead.update({
        where: { id: userContext.lead.id },
        data: {
          notes: `${currentNotes}\n🚨 [${new Date().toISOString()}] URGENT: ${intent.primary} - Sentiment: ${intent.sentiment}\nMessage: "${message}"`,
          status: 'contacted'
        }
      });
    }

    ConversationManager.updateState(phone, {
      phase: 'escalated',
      urgencyLevel: 'critical',
      emotionalState: 'frustrated'
    });

    console.log(`🚨 ESCALATION: ${phone} - ${intent.primary} (${intent.sentiment})`);
  }

  /**
   * Start a new booking journey
   */
  private static async startBookingJourney(
    clinicId: string,
    phone: string,
    userContext: any
  ): Promise<void> {
    // Find or create a booking tree
    let bookingTree = await prisma.reminderTree.findFirst({
      where: {
        clinicId,
        triggerType: 'booking_created',
        isActive: true
      }
    });

    if (!bookingTree) {
      // Create default booking tree if none exists
      const { TreeBuilder } = await import('./reminder-tree-engine');
      bookingTree = await TreeBuilder.createStandardBookingTree(clinicId);
    }

    // If user has an upcoming appointment, start journey for it
    if (userContext.upcomingAppointment) {
      const journey = await ReminderTreeEngine.startJourney(
        userContext.upcomingAppointment.id,
        bookingTree.id,
        'booking_created'
      );

      ConversationManager.updateState(phone, {
        phase: 'journey_active',
        journeyId: journey.id
      });
    } else {
      // Send booking link and options
      const bookingLink = `${process.env.NEXT_PUBLIC_APP_URL}/book/${userContext.clinic.slug}`;
      
      await sendButtons(phone, 
        `Perfect! Let's get you booked! 📅✨\n\n🔗 Book instantly here:\n${bookingLink}\n\nOr choose an option below:`,
        [
          { id: 'book_online', text: '🌐 Book Online' },
          { id: 'call_me', text: '📞 Call Me' },
          { id: 'view_prices', text: '💰 View Prices' }
        ]
      );
    }
  }

  /**
   * Interrupt an active journey for urgent matters
   */
  private static async interruptJourney(
    clinicId: string,
    phone: string,
    intent: EnhancedIntent,
    userContext: any
  ): Promise<void> {
    // Pause the current journey
    if (userContext.activeJourney) {
      await prisma.userJourney.update({
        where: { id: userContext.activeJourney.id },
        data: { status: 'paused' }
      });
    }

    // Handle the interruption
    switch (intent.primary) {
      case 'cancel_appointment':
        await this.handleCancellationRequest(phone, userContext);
        break;
        
      case 'speak_human':
        await this.handleHumanRequest(phone, userContext);
        break;
        
      case 'complaint':
        await this.handleEscalation(clinicId, phone, '', intent, userContext);
        break;
    }

    ConversationManager.updateState(phone, { phase: 'support' });
  }

  // ─── Specialized Response Handlers ───────────────────────────────

  private static async sendHours(phone: string, clinic: any, isArabic: boolean): Promise<void> {
    const formatHour = (h: number) => {
      const ampm = h >= 12 ? "PM" : "AM";
      const hour12 = h % 12 || 12;
      return `${hour12}:00 ${ampm}`;
    };

    const message = isArabic
      ? `🕐 *أوقات العمل - ${clinic.name}:*\n\nالإثنين - السبت\n${formatHour(clinic.quietHoursEnd)} - ${formatHour(clinic.quietHoursStart)}\n\nالأحد: مغلق\n\n📞 اتصل الآن: ${clinic.phone || 'هذه المحادثة'}`
      : `🕐 *${clinic.name} Hours:*\n\nMonday - Saturday\n${formatHour(clinic.quietHoursEnd)} - ${formatHour(clinic.quietHoursStart)}\n\nSunday: Closed\n\n📞 Call us: ${clinic.phone || 'this chat'}`;

    await sendButtons(phone, message, [
      { id: 'book', text: isArabic ? '📅 حجز موعد' : '📅 Book Now' },
      { id: 'location', text: isArabic ? '📍 الموقع' : '📍 Location' },
      { id: 'prices', text: isArabic ? '💰 الأسعار' : '💰 Prices' }
    ]);
  }

  private static async sendLocation(phone: string, clinic: any, isArabic: boolean): Promise<void> {
    const message = isArabic
      ? `📍 *موقع ${clinic.name}*\n\nللحصول على الاتجاهات التفصيلية:\n📞 ${clinic.phone || 'تواصل معنا هنا'}\n\nأو احجز موعداً وسنرسل لك الموقع!`
      : `📍 *${clinic.name} Location*\n\nFor detailed directions:\n📞 ${clinic.phone || 'contact us here'}\n\nOr book an appointment and we'll send you the location!`;

    await sendButtons(phone, message, [
      { id: 'book', text: isArabic ? '📅 حجز موعد' : '📅 Book Appointment' },
      { id: 'call', text: isArabic ? '📞 اتصل بنا' : '📞 Call Us' },
      { id: 'hours', text: isArabic ? '🕐 الأوقات' : '🕐 Hours' }
    ]);
  }

  private static async sendPricing(phone: string, clinic: any, isArabic: boolean): Promise<void> {
    const treatments = await prisma.treatment.findMany({
      where: { clinicId: clinic.id, isActive: true },
      orderBy: { name: 'asc' }
    });

    let priceText = isArabic
      ? `💰 *أسعار ${clinic.name}:*\n\n`
      : `💰 *${clinic.name} Pricing:*\n\n`;

    for (const treatment of treatments) {
      const price = treatment.price 
        ? `$${treatment.price}` 
        : (isArabic ? 'تواصل معنا' : 'Contact us');
      priceText += `• *${treatment.name}*\n   ${price} (${treatment.duration} ${isArabic ? 'دقيقة' : 'min'})\n\n`;
    }

    await sendButtons(phone, priceText, [
      { id: 'book', text: isArabic ? '📅 احجز الآن' : '📅 Book Now' },
      { id: 'details', text: isArabic ? 'ℹ️ تفاصيل العلاجات' : 'ℹ️ Treatment Details' },
      { id: 'consultation', text: isArabic ? '💬 استشارة مجانية' : '💬 Free Consultation' }
    ]);
  }

  private static async sendGratitudeResponse(phone: string, isArabic: boolean): Promise<void> {
    const responses = isArabic
      ? [
          'العفو! سعداء لخدمتك 😊',
          'أهلاً وسهلاً! نحن هنا دائماً 💙',
          'شكراً لك! تقديرك يعني لنا الكثير ✨'
        ]
      : [
          'You\'re so welcome! Happy to help 😊',
          'My pleasure! We\'re always here for you 💙',
          'Thank you! Your appreciation means everything ✨'
        ];

    const randomResponse = responses[Math.floor(Math.random() * responses.length)];
    await sendMessage(phone, randomResponse);
  }

  private static async sendGenericHelp(
    phone: string, 
    clinic: any, 
    intent: EnhancedIntent, 
    isArabic: boolean
  ): Promise<void> {
    const message = isArabic
      ? `مرحباً بك في ${clinic.name}! 😊\n\nكيف يمكنني مساعدتك اليوم؟`
      : `Welcome to ${clinic.name}! 😊\n\nHow can I help you today?`;

    await sendButtons(phone, message, [
      { id: 'book', text: isArabic ? '📅 حجز موعد' : '📅 Book Appointment' },
      { id: 'hours', text: isArabic ? '🕐 أوقات العمل' : '🕐 Hours' },
      { id: 'prices', text: isArabic ? '💰 الأسعار' : '💰 Prices' },
      { id: 'location', text: isArabic ? '📍 الموقع' : '📍 Location' },
      { id: 'human', text: isArabic ? '🧑 تكلم مع شخص' : '🧑 Talk to Someone' }
    ]);
  }

  // ─── Helper Methods ──────────────────────────────────────────────

  private static async getUserContext(clinicId: string, phone: string): Promise<any> {
    const clinic = await prisma.clinic.findUnique({ where: { id: clinicId } });
    
    const lead = await prisma.lead.findFirst({
      where: {
        clinicId,
        phone: { contains: phone.slice(-8) }
      }
    });

    let upcomingAppointment = null;
    let activeJourney = null;

    if (lead) {
      upcomingAppointment = await prisma.appointment.findFirst({
        where: {
          leadId: lead.id,
          status: { in: ['scheduled', 'confirmed', 'booked'] },
          dateTime: { gte: new Date() }
        },
        include: { treatment: true },
        orderBy: { dateTime: 'asc' }
      });

      if (upcomingAppointment) {
        activeJourney = await prisma.userJourney.findFirst({
          where: {
            appointmentId: upcomingAppointment.id,
            status: 'active'
          }
        });
      }
    }

    return {
      clinic,
      lead,
      upcomingAppointment,
      activeJourney
    };
  }

  private static async handleCancellationRequest(phone: string, userContext: any): Promise<void> {
    if (!userContext.upcomingAppointment) {
      await sendMessage(phone, "You don't have any upcoming appointments to cancel.");
      return;
    }

    const appointment = userContext.upcomingAppointment;
    await sendButtons(phone,
      `Are you sure you want to cancel your ${appointment.treatment.name} appointment?\n\n📅 ${new Date(appointment.dateTime).toLocaleDateString()}\n🕐 ${new Date(appointment.dateTime).toLocaleTimeString()}`,
      [
        { id: 'confirm_cancel', text: '✅ Yes, Cancel' },
        { id: 'keep_appointment', text: '❌ No, Keep It' },
        { id: 'reschedule_instead', text: '📅 Reschedule Instead' }
      ]
    );
  }

  private static async handleHumanRequest(phone: string, userContext: any): Promise<void> {
    await sendMessage(phone,
      `Of course! Our team will contact you shortly.\n\nIf it's urgent, call us at:\n📞 ${userContext.clinic?.phone || 'this chat'}\n\n🏷️ You've been flagged for priority human response.`
    );

    // Flag for human attention
    if (userContext.lead) {
      await prisma.lead.update({
        where: { id: userContext.lead.id },
        data: {
          notes: `${userContext.lead.notes || ''}\n🧑 [${new Date().toISOString()}] Requested human contact`,
          status: 'contacted'
        }
      });
    }
  }

  private static async handleError(clinicId: string, phone: string, error: any): Promise<void> {
    console.error('Chatbot error:', error);
    
    await sendMessage(phone,
      `I apologize, but I encountered a technical issue. Our team has been notified and will assist you shortly.\n\nFor immediate help, please try again or contact us directly.`
    );
  }

  private static async handleInfoCollection(
    clinicId: string,
    phone: string,
    message: string,
    intent: EnhancedIntent,
    state: ConversationState
  ): Promise<void> {
    // Store collected information
    const collectedData = state.collectedData || {};
    collectedData[`response_${Date.now()}`] = {
      message,
      intent: intent.primary,
      timestamp: new Date()
    };

    ConversationManager.updateState(phone, {
      collectedData,
      phase: 'support'
    });

    await sendMessage(phone, 
      `Thank you for the information. Our team will review this and respond shortly.`
    );
  }
}