import { isUserLoggedIn } from "../LoginComponent.js";

class OrderProcessingService {
  constructor(getContext, setState) {
    this.getContext = getContext;
    this.setState = setState;
    this.verifyTokenHandler = null;
    this.verifyTokenTimeout = null;
    this.socketHandler = null;
    this.paymentCompletionData = null;
  }

  // Clean up all event listeners and timeouts
  cleanup() {
    if (this.verifyTokenHandler) {
      window.removeEventListener('cart', this.verifyTokenHandler);
      this.verifyTokenHandler = null;
    }
    if (this.verifyTokenTimeout) {
      clearTimeout(this.verifyTokenTimeout);
      this.verifyTokenTimeout = null;
    }
    if (this.socketHandler) {
      window.removeEventListener('cart', this.socketHandler);
      this.socketHandler = null;
    }
  }

  // Handle payment completion from parent component
  handlePaymentCompletion(paymentCompletion, onClearPaymentCompletion) {
    // Store payment completion data before clearing
    this.paymentCompletionData = { ...paymentCompletion };
    
    // Clear payment completion data to prevent duplicates
    if (onClearPaymentCompletion) {
      onClearPaymentCompletion();
    }
    
    // Show payment confirmation immediately but wait for verifyToken to complete
    this.setState({ 
      showPaymentConfirmation: true,
      cartItems: [] // Clear UI cart immediately
    });
    
    // Wait for verifyToken to complete and populate window.cart, then process order
    this.waitForVerifyTokenAndProcessOrder();
  }

  waitForVerifyTokenAndProcessOrder() {
    // Check if window.cart is already populated (verifyToken already completed)
    if (Array.isArray(window.cart) && window.cart.length > 0) {
      if (this.paymentCompletionData && this.paymentCompletionData.paymentType === 'mollie') {
        this.processMollieOrderWithCart(window.cart);
      } else {
        this.processStripeOrderWithCart(window.cart);
      }
      return;
    }
    
    // Listen for cart event which is dispatched after verifyToken completes
    this.verifyTokenHandler = () => {
      if (Array.isArray(window.cart) && window.cart.length > 0) {
        const cartCopy = [...window.cart]; // Copy the cart
        
        // Clear window.cart after copying
        window.cart = [];
        window.dispatchEvent(new CustomEvent("cart"));
        
        // Process based on payment type
        if (this.paymentCompletionData && this.paymentCompletionData.paymentType === 'mollie') {
          this.processMollieOrderWithCart(cartCopy);
        } else {
          this.processStripeOrderWithCart(cartCopy);
        }
      } else {
        this.setState({ 
          completionError: "Cart is empty. Please add items to your cart before placing an order." 
        });
      }
      
      // Clean up listener
      if (this.verifyTokenHandler) {
        window.removeEventListener('cart', this.verifyTokenHandler);
        this.verifyTokenHandler = null;
      }
    };
    
    window.addEventListener('cart', this.verifyTokenHandler);
    
    // Set up a timeout as fallback (in case verifyToken fails)
    this.verifyTokenTimeout = setTimeout(() => {
      if (Array.isArray(window.cart) && window.cart.length > 0) {
        this.processStripeOrderWithCart([...window.cart]);
        window.cart = [];
        window.dispatchEvent(new CustomEvent("cart"));
      } else {
        this.setState({ 
          completionError: "Unable to load cart data. Please refresh the page and try again." 
        });
      }
      
      // Clean up
      if (this.verifyTokenHandler) {
        window.removeEventListener('cart', this.verifyTokenHandler);
        this.verifyTokenHandler = null;
      }
    }, 5000); // 5 second timeout
  }

  processStripeOrderWithCart(cartItems) {
    // Clear timeout if it exists
    if (this.verifyTokenTimeout) {
      clearTimeout(this.verifyTokenTimeout);
      this.verifyTokenTimeout = null;
    }
    
    // Store cart items in state and process order
    this.setState({ 
      originalCartItems: cartItems 
    }, () => {
      this.processStripeOrder();
    });
  }

  processMollieOrderWithCart(cartItems) {
    // Clear timeout if it exists
    if (this.verifyTokenTimeout) {
      clearTimeout(this.verifyTokenTimeout);
      this.verifyTokenTimeout = null;
    }
    
    // Store cart items in state and process order
    this.setState({ 
      originalCartItems: cartItems 
    }, () => {
      this.processMollieOrder();
    });
  }

  processStripeOrder() {
    // If no original cart items, don't process
    if (!this.getState().originalCartItems || this.getState().originalCartItems.length === 0) {
      this.setState({ completionError: "Cart is empty. Please add items to your cart before placing an order." });
      return;
    }

    // If socket is ready, process immediately

      const { isLoggedIn: isAuthenticated } = isUserLoggedIn();
      if (isAuthenticated) {
        this.sendStripeOrder();
        return;
      }


    // Wait for socket to be ready
    this.socketHandler = () => {

        const { isLoggedIn: isAuthenticated } = isUserLoggedIn();
        const state = this.getState();
        
        if (isAuthenticated && state.showPaymentConfirmation && !state.isCompletingOrder) {
          this.sendStripeOrder();
        }

      // Clean up
      if (this.socketHandler) {
        window.removeEventListener('cart', this.socketHandler);
        this.socketHandler = null;
      }
    };
    window.addEventListener('cart', this.socketHandler);
  }

  sendStripeOrder() {
    const state = this.getState();
    
    // Don't process if already processing or completed
    if (state.isCompletingOrder || state.orderCompleted) {
      return;
    }

    this.setState({ isCompletingOrder: true, completionError: null });

    const {
      deliveryMethod,
      invoiceAddress,
      deliveryAddress,
      useSameAddress,
      originalCartItems,
      note,
      saveAddressForFuture,
    } = state;

    const deliveryCost = this.getDeliveryCost();

    const orderData = {
      items: originalCartItems,
      invoiceAddress,
      deliveryAddress: useSameAddress ? invoiceAddress : deliveryAddress,
      deliveryMethod,
      paymentMethod: "stripe",
      deliveryCost,
      note,
      domain: window.location.origin,
      stripeData: this.paymentCompletionData ? {
        paymentIntent: this.paymentCompletionData.paymentIntent,
        paymentIntentClientSecret: this.paymentCompletionData.paymentIntentClientSecret,
        redirectStatus: this.paymentCompletionData.redirectStatus,
      } : null,
      saveAddressForFuture,
    };


    window.socketManager.emit("issueStripeOrder", orderData, (response) => {
      if (response.success) {
        this.setState({
          isCompletingOrder: false,
          orderCompleted: true,
          completionError: null,
        });
      } else {
        this.setState({
          isCompletingOrder: false,
          completionError: response.error || "Failed to complete order. Please try again.",
        });
      }
    });
  }

  processMollieOrder() {
    // For Mollie payments, the backend handles order creation automatically
    // when payment is successful. We just need to show success state.
    this.setState({
      isCompletingOrder: false,
      orderCompleted: true,
      completionError: null,
    });
    
    // Clear the cart since order was created by backend
    window.cart = [];
    window.dispatchEvent(new CustomEvent("cart"));
  }

  // Process regular (non-Stripe) orders
  processRegularOrder(orderData) {

      window.socketManager.emit("issueOrder", orderData, (response) => {
        if (response.success) {
          // Clear the cart
          window.cart = [];
          window.dispatchEvent(new CustomEvent("cart"));

          // Reset state and navigate to orders tab
          this.setState({
            isCheckingOut: false,
            cartItems: [],
            isCompletingOrder: false,
            completionError: null,
          });
          
          // Call success callback if provided
          if (this.onOrderSuccess) {
            this.onOrderSuccess();
          }
        } else {
          this.setState({
            isCompletingOrder: false,
            completionError: response.error || "Failed to complete order. Please try again.",
          });
        }
      });
  }

  // Create Stripe payment intent
  createStripeIntent(totalAmount, loadStripeComponent) {

      window.socketManager.emit(
        "createStripeIntent",
        { amount: totalAmount },
        (response) => {
          if (response.success) {
            loadStripeComponent(response.client_secret);
          } else {
            console.error("Error:", response.error);
            this.setState({
              isCompletingOrder: false,
              completionError: response.error || "Failed to create Stripe payment intent. Please try again.",
            });
          }
        }
      );
  };



  // Create Mollie payment intent
  createMollieIntent(mollieOrderData) {
      window.socketManager.emit(
        "createMollieIntent",
        mollieOrderData,
        (response) => {
          if (response.success) {
            // Store pending payment info and redirect
            localStorage.setItem('pendingPayment', JSON.stringify({
              paymentId: response.paymentId,
              amount: mollieOrderData.amount,
              timestamp: Date.now()
            }));
            window.location.href = response.checkoutUrl;
          } else {
            console.error("Error:", response.error);
            this.setState({
              isCompletingOrder: false,
              completionError: response.error || "Failed to create Mollie payment intent. Please try again.",
            });
          }
        }
      );
  }

  // Calculate delivery cost
  getDeliveryCost() {
    const { deliveryMethod, paymentMethod, cartItems } = this.getState();
    let cost = 0;

    switch (deliveryMethod) {
      case "DHL":
        cost = 6.99;
        break;
      case "DPD":
        cost = 4.9;
        break;
      case "Sperrgut":
        cost = 28.99;
        break;
      case "Abholung":
        cost = 0;
        break;
      default:
        cost = 6.99;
    }

    // Check for free shipping threshold (>= 100€ cart value)
    // Free shipping applies to DHL, DPD, and Sperrgut deliveries when cart value >= 100€
    if (cartItems && Array.isArray(cartItems) && deliveryMethod !== "Abholung") {
      const cartValue = cartItems.reduce((total, item) => total + item.price * item.quantity, 0);
      if (cartValue >= 100) {
        cost = 0; // Free shipping for orders >= 100€
      }
    }

    // Add onDelivery surcharge if selected (still applies even with free shipping)
    if (paymentMethod === "onDelivery") {
      cost += 8.99;
    }

    return cost;
  }

  // Helper method to get current state (to be overridden by component)
  getState() {
    throw new Error("getState method must be implemented by the component");
  }

  // Set callback for order success
  setOrderSuccessCallback(callback) {
    this.onOrderSuccess = callback;
  }
}

export default OrderProcessingService; 