import React, { Component } from "react";
import { Box, Typography, Button } from "@mui/material";
import CartDropdown from "../CartDropdown.js";
import CheckoutForm from "./CheckoutForm.js";
import PaymentConfirmationDialog from "./PaymentConfirmationDialog.js";
import OrderProcessingService from "./OrderProcessingService.js";
import CheckoutValidation from "./CheckoutValidation.js";
import { withI18n } from "../../i18n/index.js";

class CartTab extends Component {
  normalizeDeliveryMethod = (deliveryMethod) => (deliveryMethod === "DPD" ? "DHL" : deliveryMethod);

  constructor(props) {
    super(props);
    
    const initialCartItems = Array.isArray(window.cart) ? window.cart : [];
    const initialDeliveryMethod = CheckoutValidation.shouldForcePickupDelivery(initialCartItems) ? "Abholung" : "DHL";
    const optimalPaymentMethod = CheckoutValidation.getOptimalPaymentMethod(initialDeliveryMethod, initialCartItems, 0);
    
    this.state = {
      isCheckingOut: false,
      cartItems: initialCartItems,
      deliveryMethod: initialDeliveryMethod,
      paymentMethod: optimalPaymentMethod,
      invoiceAddress: {
        firstName: "",
        lastName: "",
        addressAddition: "",
        street: "",
        houseNumber: "",
        postalCode: "",
        city: "",
        country: "Deutschland",
      },
      deliveryAddress: {
        firstName: "",
        lastName: "",
        addressAddition: "",
        street: "",
        houseNumber: "",
        postalCode: "",
        city: "",
        country: "Deutschland",
      },
      useSameAddress: true,
      saveAddressForFuture: true,
      addressFormErrors: {},
      termsAccepted: false,
      isCompletingOrder: false,
      completionError: null,
      note: "",
      stripeClientSecret: null,
      showStripePayment: false,
      StripeComponent: null,
      isLoadingStripe: false,
      showPaymentConfirmation: false,
      orderCompleted: false,
      originalCartItems: []
    };

    // Initialize order processing service
    this.orderService = new OrderProcessingService(
      () => this.context,
      this.setState.bind(this)
    );
    this.orderService.getState = () => this.state;
    this.orderService.setOrderSuccessCallback(this.props.onOrderSuccess);
  }

  // @note Add method to fetch and apply order template prefill data
  fetchOrderTemplate = () => {
      window.socketManager.emit('getOrderTemplate', (response) => {
        if (response.success && response.orderTemplate) {
          const template = response.orderTemplate;
          
          // Map the template fields to our state structure
          const invoiceAddress = {
            firstName: template.invoice_address_name ? template.invoice_address_name.split(' ')[0] || "" : "",
            lastName: template.invoice_address_name ? template.invoice_address_name.split(' ').slice(1).join(' ') || "" : "",
            addressAddition: template.invoice_address_line2 || "",
            street: template.invoice_address_street || "",
            houseNumber: template.invoice_address_house_number || "",
            postalCode: template.invoice_address_postal_code || "",
            city: template.invoice_address_city || "",
            country: template.invoice_address_country || "Deutschland",
          };

          const deliveryAddress = {
            firstName: template.shipping_address_name ? template.shipping_address_name.split(' ')[0] || "" : "",
            lastName: template.shipping_address_name ? template.shipping_address_name.split(' ').slice(1).join(' ') || "" : "",
            addressAddition: template.shipping_address_line2 || "",
            street: template.shipping_address_street || "",
            houseNumber: template.shipping_address_house_number || "",
            postalCode: template.shipping_address_postal_code || "",
            city: template.shipping_address_city || "",
            country: template.shipping_address_country || "Deutschland",
          };

          // Get current cart state to check constraints
          const currentCartItems = Array.isArray(window.cart) ? window.cart : [];
          const { isPickupOnly, hasStecklinge } = CheckoutValidation.getCartItemFlags(currentCartItems);
          
          // Determine delivery method - respect cart constraints
          let prefillDeliveryMethod = template.delivery_method || "DHL";
          if (isPickupOnly || hasStecklinge) {
            prefillDeliveryMethod = "Abholung";
          }
          
          // Map delivery method values if needed
          const deliveryMethodMap = {
            "standard": "DHL",
            "express": "DHL",
            "pickup": "Abholung"
          };
          prefillDeliveryMethod = this.normalizeDeliveryMethod(
            deliveryMethodMap[prefillDeliveryMethod] || prefillDeliveryMethod
          );

          // Determine payment method - respect constraints
          let prefillPaymentMethod = template.payment_method || "wire";
          const paymentMethodMap = {
            "credit_card": "mollie",/*stripe*/
            "bank_transfer": "wire",
            "cash_on_delivery": "onDelivery",
            "cash": "cash"
          };
          prefillPaymentMethod = paymentMethodMap[prefillPaymentMethod] || prefillPaymentMethod;
          
          // Validate payment method against delivery method constraints
          prefillPaymentMethod = CheckoutValidation.validatePaymentMethodForDelivery(
            prefillDeliveryMethod,
            prefillPaymentMethod,
            currentCartItems,
            0 // Use 0 for delivery cost during prefill
          );

          // Apply prefill data to state
          this.setState({
            invoiceAddress,
            deliveryAddress,
            deliveryMethod: prefillDeliveryMethod,
            paymentMethod: prefillPaymentMethod,
            saveAddressForFuture: template.save_address_for_future === 1,
            useSameAddress: true // Default to same address, user can change if needed
          });

          console.log("Order template applied successfully");
        } else {
          console.log("No order template available or failed to fetch");
        }
      });
  };

  componentDidMount() {
    // Handle payment completion if detected
    if (this.props.paymentCompletion) {
      this.orderService.handlePaymentCompletion(
        this.props.paymentCompletion,
        this.props.onClearPaymentCompletion
      );
    }

    // @note Fetch order template for prefill when component mounts
    this.fetchOrderTemplate();

    this.cart = () => {
      // @note Don't update cart if we're showing payment confirmation - keep it empty
      if (this.state.showPaymentConfirmation) {
        return;
      }
      
      const cartItems = Array.isArray(window.cart) ? window.cart : [];
      const shouldForcePickup = CheckoutValidation.shouldForcePickupDelivery(cartItems);
      
      const newDeliveryMethod = shouldForcePickup
        ? "Abholung"
        : this.normalizeDeliveryMethod(this.state.deliveryMethod);
      const deliveryCost = this.orderService.getDeliveryCost();
      
      // Get optimal payment method for the current state
      const optimalPaymentMethod = CheckoutValidation.getOptimalPaymentMethod(
        newDeliveryMethod, 
        cartItems, 
        deliveryCost
      );
      
      // Use optimal payment method if current one is invalid, otherwise keep current
      const validatedPaymentMethod = CheckoutValidation.validatePaymentMethodForDelivery(
        newDeliveryMethod,
        this.state.paymentMethod,
        cartItems,
        deliveryCost
      );
      
      const newPaymentMethod = validatedPaymentMethod !== this.state.paymentMethod 
        ? optimalPaymentMethod 
        : this.state.paymentMethod;
      
      this.setState({
        cartItems,
        deliveryMethod: newDeliveryMethod,
        paymentMethod: newPaymentMethod,
      });
    };
    
    window.addEventListener("cart", this.cart);
    this.cart(); // Initial check
  }

  componentWillUnmount() {
    window.removeEventListener("cart", this.cart);
    this.orderService.cleanup();
  }

  handleCheckout = () => {
    this.setState({ isCheckingOut: true });
  };

  handleContinueShopping = () => {
    this.setState({ isCheckingOut: false });
  };

  handleDeliveryMethodChange = (event) => {
    const newDeliveryMethod = this.normalizeDeliveryMethod(event.target.value);
    const deliveryCost = this.orderService.getDeliveryCost();

    // Pickup should default to in-store payment.
    if (newDeliveryMethod === "Abholung") {
      this.setState({
        deliveryMethod: newDeliveryMethod,
        paymentMethod: "cash",
      });
      return;
    }
    
    // Get optimal payment method for the new delivery method
    const optimalPaymentMethod = CheckoutValidation.getOptimalPaymentMethod(
      newDeliveryMethod,
      this.state.cartItems,
      deliveryCost
    );
    
    // Use optimal payment method if current one becomes invalid, otherwise keep current
    const validatedPaymentMethod = CheckoutValidation.validatePaymentMethodForDelivery(
      newDeliveryMethod,
      this.state.paymentMethod,
      this.state.cartItems,
      deliveryCost
    );
    
    const newPaymentMethod = validatedPaymentMethod !== this.state.paymentMethod 
      ? optimalPaymentMethod 
      : this.state.paymentMethod;

    this.setState({
      deliveryMethod: newDeliveryMethod,
      paymentMethod: newPaymentMethod,
    });
  };

  handlePaymentMethodChange = (event) => {
    this.setState({ paymentMethod: event.target.value });
  };

  handleInvoiceAddressChange = (e) => {
    const { name, value } = e.target;
    this.setState((prevState) => ({
      invoiceAddress: {
        ...prevState.invoiceAddress,
        [name]: value,
      },
    }));
  };

  handleDeliveryAddressChange = (e) => {
    const { name, value } = e.target;
    this.setState((prevState) => ({
      deliveryAddress: {
        ...prevState.deliveryAddress,
        [name]: value,
      },
    }));
  };

  handleUseSameAddressChange = (e) => {
    const useSameAddress = e.target.checked;
    this.setState({
      useSameAddress,
      deliveryAddress: useSameAddress
        ? this.state.invoiceAddress
        : this.state.deliveryAddress,
    });
  };

  handleTermsAcceptedChange = (e) => {
    this.setState({ termsAccepted: e.target.checked });
  };

  handleNoteChange = (e) => {
    this.setState({ note: e.target.value });
  };

  handleSaveAddressForFutureChange = (e) => {
    this.setState({ saveAddressForFuture: e.target.checked });
  };

  validateAddressForm = () => {
    const errors = CheckoutValidation.validateAddressForm(this.state, this.props.t);
    this.setState({ addressFormErrors: errors });
    return Object.keys(errors).length === 0;
  };

  loadStripeComponent = async (clientSecret) => {
    this.setState({ isLoadingStripe: true });
    
    try {
      const { default: Stripe } = await import("../Stripe.js");
      this.setState({
        StripeComponent: Stripe,
        stripeClientSecret: clientSecret,
        showStripePayment: true,
        isCompletingOrder: false,
        isLoadingStripe: false,
      });
    } catch (error) {
      console.error("Failed to load Stripe component:", error);
      this.setState({
        isCompletingOrder: false,
        isLoadingStripe: false,
        completionError: "Failed to load payment component. Please try again.",
      });
    }
  };

  handleCompleteOrder = () => {
    this.setState({ completionError: null }); // Clear previous errors

    const validationError = CheckoutValidation.getValidationErrorMessage(this.state, false, this.props.t);
    if (validationError) {
      this.setState({ completionError: validationError });
      this.validateAddressForm(); // To show field-specific errors
      return;
    }

    this.setState({ isCompletingOrder: true });

    const {
      deliveryMethod,
      paymentMethod,
      invoiceAddress,
      deliveryAddress,
      useSameAddress,
      cartItems,
      note,
      saveAddressForFuture,
    } = this.state;

    const deliveryCost = this.orderService.getDeliveryCost();

    // Handle Stripe payment differently
    if (paymentMethod === "stripe") {
      // Store the cart items used for Stripe payment in sessionStorage for later reference
      try {
        sessionStorage.setItem('stripePaymentCart', JSON.stringify(cartItems));
      } catch (error) {
        console.error("Failed to store Stripe payment cart:", error);
      }
      
      // Calculate total amount for Stripe
      const subtotal = cartItems.reduce(
        (total, item) => total + item.price * item.quantity,
        0
      );
      const totalAmount = Math.round((subtotal + deliveryCost) * 100); // Convert to cents
      
      this.orderService.createStripeIntent(totalAmount, this.loadStripeComponent);
      return;
    }
    // Handle molllie payment differently
    if (paymentMethod === "mollie") {
      // Store the cart items used for mollie payment in sessionStorage for later reference
      try {
        sessionStorage.setItem('molliePaymentCart', JSON.stringify(cartItems));
      } catch (error) {
        console.error("Failed to store mollie payment cart:", error);
      }
      
      // Calculate total amount for mollie
      const subtotal = cartItems.reduce(
        (total, item) => total + item.price * item.quantity,
        0
      );
      const totalAmount = Math.round((subtotal + deliveryCost) * 100) / 100;
      
      // Prepare complete order data for Mollie intent creation
      const mollieOrderData = {
        amount: totalAmount,
        items: cartItems,
        invoiceAddress,
        deliveryAddress: useSameAddress ? invoiceAddress : deliveryAddress,
        deliveryMethod,
        paymentMethod: "mollie",
        deliveryCost,
        note,
        domain: window.location.origin,
        saveAddressForFuture,
      };
      
      this.orderService.createMollieIntent(mollieOrderData);

      return;
    }

    // Handle regular orders
    const orderData = {
      items: cartItems,
      invoiceAddress,
      deliveryAddress: useSameAddress ? invoiceAddress : deliveryAddress,
      deliveryMethod,
      paymentMethod,
      deliveryCost,
      note,
      domain: window.location.origin,
      saveAddressForFuture,
    };

    this.orderService.processRegularOrder(orderData);
  };

  render() {
    const {
      cartItems,
      deliveryMethod,
      paymentMethod,
      invoiceAddress,
      deliveryAddress,
      useSameAddress,
      saveAddressForFuture,
      addressFormErrors,
      termsAccepted,
      isCompletingOrder,
      completionError,
      note,
      stripeClientSecret,
      showStripePayment,
      StripeComponent,
      isLoadingStripe,
      showPaymentConfirmation,
      orderCompleted,
    } = this.state;

    const deliveryCost = this.orderService.getDeliveryCost();
    const { isPickupOnly, hasStecklinge } = CheckoutValidation.getCartItemFlags(cartItems);

    const preSubmitError = CheckoutValidation.getValidationErrorMessage(this.state, false, this.props.t);
    const displayError = completionError || preSubmitError;

    return (
              <Box sx={{ p: { xs: 1, sm: 3 } }}>
        {/* Payment Confirmation */}
        {showPaymentConfirmation && (
          <PaymentConfirmationDialog
            paymentCompletionData={this.orderService.paymentCompletionData}
            isCompletingOrder={isCompletingOrder}
            completionError={completionError}
            orderCompleted={orderCompleted}
            onContinueShopping={() => {
                    this.setState({ showPaymentConfirmation: false });
                  }}
            onViewOrders={() => {
                    if (this.props.onOrderSuccess) {
                      this.props.onOrderSuccess();
                    }
                    this.setState({ showPaymentConfirmation: false });
                  }}
          />
        )}

        {/* @note Hide CartDropdown when showing payment confirmation */}
        {!showPaymentConfirmation && (
          <CartDropdown 
            cartItems={cartItems} 
            showDetailedSummary={showStripePayment}
            deliveryMethod={deliveryMethod}
            deliveryCost={deliveryCost}
          />
        )}

        {cartItems.length > 0 && (
          <Box sx={{ mt: 3 }}>
            {isLoadingStripe ? (
              <Box sx={{ textAlign: 'center', py: 4 }}>
                <Typography variant="body1">
                  {this.props.t ? this.props.t('payment.loadingPaymentComponent') : 'Zahlungskomponente wird geladen...'}
                </Typography>
              </Box>
            ) : showStripePayment && StripeComponent ? (
              <>
                <Box sx={{ mb: 2 }}>
                  <Button
                    variant="outlined"
                    onClick={() => this.setState({ showStripePayment: false, stripeClientSecret: null })}
                    sx={{ 
                      color: '#2e7d32', 
                      borderColor: '#2e7d32',
                      '&:hover': {
                        backgroundColor: 'rgba(46, 125, 50, 0.04)',
                        borderColor: '#1b5e20'
                      }
                    }}
                  >
                    {this.props.t ? this.props.t('cart.backToOrder') : '← Zurück zur Bestellung'}
                  </Button>
                </Box>
                <StripeComponent clientSecret={stripeClientSecret} />
              </>
            ) : (
              <CheckoutForm
                  paymentMethod={paymentMethod}
                invoiceAddress={invoiceAddress}
                deliveryAddress={deliveryAddress}
                useSameAddress={useSameAddress}
                saveAddressForFuture={saveAddressForFuture}
                addressFormErrors={addressFormErrors}
                termsAccepted={termsAccepted}
                note={note}
                  deliveryMethod={deliveryMethod}
                hasStecklinge={hasStecklinge}
                isPickupOnly={isPickupOnly}
                deliveryCost={deliveryCost}
                cartItems={cartItems}
                displayError={displayError}
                isCompletingOrder={isCompletingOrder}
                preSubmitError={preSubmitError}
                onInvoiceAddressChange={this.handleInvoiceAddressChange}
                onDeliveryAddressChange={this.handleDeliveryAddressChange}
                onUseSameAddressChange={this.handleUseSameAddressChange}
                onSaveAddressForFutureChange={this.handleSaveAddressForFutureChange}
                onTermsAcceptedChange={this.handleTermsAcceptedChange}
                onNoteChange={this.handleNoteChange}
                onDeliveryMethodChange={this.handleDeliveryMethodChange}
                onPaymentMethodChange={this.handlePaymentMethodChange}
                onCompleteOrder={this.handleCompleteOrder}
              />
            )}
          </Box>
        )}
      </Box>
    );
  }
}

export default withI18n()(CartTab);
