/**
 * TriggerHandler - Smart Proactive Messages
 * 
 * Listens to user behavior and fires proactive messages:
 * - Exit Intent: When user moves mouse to close tab
 * - Scroll Depth: When user scrolls X% of page
 * - Time on Page: After X seconds on page
 * - Returning Visitor: When visitor returns to site
 * - Cart Abandoned: WooCommerce - items in cart but leaving
 */

import { useChatStore } from '@/store/chatStore';
import type { TriggerConfig, TriggerType } from '@/types';
import { getDefaultTriggers } from '@/types';
import { getStorageKey } from '@/utils/locale';

export class TriggerHandler {
  private config: TriggerConfig;
  private cleanupFunctions: Array<() => void> = [];
  private isInitialized = false;
  
  constructor(config?: Partial<TriggerConfig>) {
    // Merge with defaults
    this.config = {
      ...getDefaultTriggers(),
      ...config
    };
  }
  
  /**
   * Initialize all trigger listeners
   */
  init() {
    if (this.isInitialized) {
      return;
    }
    
    this.setupExitIntent();
    this.setupScrollDepth();
    this.setupTimeOnPage();
    this.setupReturningVisitor();
    this.setupCartAbandoned();
    
    this.isInitialized = true;
  }
  
  /**
   * Exit Intent - fires when mouse moves to top of window
   */
  private setupExitIntent() {
    const cfg = this.config.exit_intent;
    if (!cfg?.enabled) return;
    
    const handler = (e: MouseEvent) => {
      // Only fire if mouse is leaving from the top
      if (e.clientY < 0) {
        this.fire('exit_intent', cfg.message);
      }
    };
    
    document.addEventListener('mouseout', handler);
    this.cleanupFunctions.push(() => document.removeEventListener('mouseout', handler));
  }
  
  /**
   * Scroll Depth - fires when user scrolls past X%
   */
  private setupScrollDepth() {
    const cfg = this.config.scroll_depth;
    if (!cfg?.enabled) return;
    
    let fired = false;
    
    const handler = () => {
      if (fired) return;
      
      // Calculate scroll percentage
      const scrollTop = window.scrollY;
      const docHeight = document.documentElement.scrollHeight - window.innerHeight;
      const scrollPercent = (scrollTop / docHeight) * 100;
      
      if (scrollPercent >= cfg.threshold) {
        fired = true;
        this.fire('scroll_depth', cfg.message);
      }
    };
    
    // Throttle scroll events
    let ticking = false;
    const throttledHandler = () => {
      if (!ticking) {
        window.requestAnimationFrame(() => {
          handler();
          ticking = false;
        });
        ticking = true;
      }
    };
    
    window.addEventListener('scroll', throttledHandler, { passive: true });
    this.cleanupFunctions.push(() => window.removeEventListener('scroll', throttledHandler));
  }
  
  /**
   * Time on Page - fires after X seconds
   */
  private setupTimeOnPage() {
    const cfg = this.config.time_on_page;
    if (!cfg?.enabled) return;
    
    const seconds = cfg.seconds || cfg.threshold || 30;
    
    const timer = setTimeout(() => {
      this.fire('time_on_page', cfg.message);
    }, seconds * 1000);
    
    this.cleanupFunctions.push(() => clearTimeout(timer));
  }
  
  /**
   * Returning Visitor - fires if visitor has been here before
   */
  private setupReturningVisitor() {
    const cfg = this.config.returning_visitor;
    if (!cfg?.enabled) return;
    
    const VISIT_KEY = getStorageKey('boostbot_visit_count');
    const visitCount = parseInt(localStorage.getItem(VISIT_KEY) || '0', 10);
    
    // Increment visit count (language-scoped)
    localStorage.setItem(VISIT_KEY, String(visitCount + 1));
    
    // If returning visitor, show message after short delay
    if (visitCount > 0) {
      const timer = setTimeout(() => {
        this.fire('returning_visitor', cfg.message);
      }, 3000); // 3 second delay
      
      this.cleanupFunctions.push(() => clearTimeout(timer));
    }
  }
  
  /**
   * Cart Abandoned - WooCommerce: fires on exit intent if cart has items
   */
  private setupCartAbandoned() {
    const cfg = this.config.cart_abandoned;
    if (!cfg?.enabled) return;
    
    const handler = (e: MouseEvent) => {
      // Only on exit intent
      if (e.clientY >= 0) return;
      
      // Check if WooCommerce cart has items
      const cartCount = this.getWooCommerceCartCount();
      if (cartCount > 0) {
        this.fire('cart_abandoned', cfg.message);
      }
    };
    
    document.addEventListener('mouseout', handler);
    this.cleanupFunctions.push(() => document.removeEventListener('mouseout', handler));
  }
  
  /**
   * Get WooCommerce cart item count
   */
  private getWooCommerceCartCount(): number {
    // Try to get from WooCommerce global
    const wc = (window as any).wc_cart_fragments_params;
    if (wc?.cart_hash) {
      const cartData = localStorage.getItem('wc_fragments_' + wc.cart_hash);
      if (cartData) {
        try {
          const parsed = JSON.parse(cartData);
          const countHtml = parsed['div.cart-count'] || parsed['.cart-contents-count'];
          if (countHtml) {
            const match = countHtml.match(/(\d+)/);
            return match ? parseInt(match[1], 10) : 0;
          }
        } catch {
          // Ignore parsing errors
        }
      }
    }
    
    // Fallback: look for cart count in DOM
    const countEl = document.querySelector('.cart-contents-count, .cart-count, .woocommerce-cart-count');
    if (countEl) {
      const count = parseInt(countEl.textContent || '0', 10);
      return isNaN(count) ? 0 : count;
    }
    
    return 0;
  }
  
  /**
   * Fire a trigger - opens chat with proactive message
   */
  private fire(triggerId: TriggerType, message: string) {
    const store = useChatStore.getState();
    
    // Check if already fired
    if (store.hasTriggerFired(triggerId)) {
      return;
    }
    
    // Check if chat is already open
    if (store.isOpen) {
      return;
    }
    
    // Open chat with the proactive message
    store.openWithMessage(message, triggerId);
  }
  
  /**
   * Update trigger configuration
   */
  updateConfig(newConfig: Partial<TriggerConfig>) {
    this.config = {
      ...this.config,
      ...newConfig
    };
  }
  
  /**
   * Cleanup all listeners
   */
  destroy() {
    this.cleanupFunctions.forEach(fn => fn());
    this.cleanupFunctions = [];
    this.isInitialized = false;
  }
}

// Create and export singleton instance
let triggerHandlerInstance: TriggerHandler | null = null;

export function initTriggers(config?: Partial<TriggerConfig>): TriggerHandler {
  if (!triggerHandlerInstance) {
    triggerHandlerInstance = new TriggerHandler(config);
  }
  triggerHandlerInstance.init();
  return triggerHandlerInstance;
}

export function destroyTriggers() {
  if (triggerHandlerInstance) {
    triggerHandlerInstance.destroy();
    triggerHandlerInstance = null;
  }
}

export function getTriggerHandler(): TriggerHandler | null {
  return triggerHandlerInstance;
}
