import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { useCartStore } from '@/lib/cart/store';
import { useCheckoutSettings } from '@/hooks/useAppearanceSettings';
import { Button } from '@/components/ui/button';
import { SearchableSelect } from '@/components/ui/searchable-select';
import { DynamicCheckoutField, type CheckoutField } from '@/components/DynamicCheckoutField';
import Container from '@/components/Layout/Container';
import SEOHead from '@/components/SEOHead';
import { formatPrice } from '@/lib/currency';
import { ArrowLeft, ShoppingBag, MapPin, Check, Edit2, Loader2, X, Tag } from 'lucide-react';
import { toast } from 'sonner';
import { apiClient } from '@/lib/api/client';
import { api } from '@/lib/api/client';
import { AddressSelector } from '@/components/AddressSelector';
import { applyCoupon, removeCoupon, fetchCart } from '@/lib/cart/api';

interface SavedAddress {
  id: number;
  label: string;
  type: 'billing' | 'shipping' | 'both';
  first_name: string;
  last_name: string;
  company?: string;
  address_1: string;
  address_2?: string;
  city: string;
  state: string;
  postcode: string;
  country: string;
  email?: string;
  phone?: string;
  is_default: boolean;
}

export default function Checkout() {
  const navigate = useNavigate();
  const { cart } = useCartStore();
  const { layout, elements } = useCheckoutSettings();
  const [isProcessing, setIsProcessing] = useState(false);
  const [couponCode, setCouponCode] = useState('');
  const [isApplyingCoupon, setIsApplyingCoupon] = useState(false);
  const [appliedCoupons, setAppliedCoupons] = useState<{ code: string; discount: number }[]>([]);
  const [discountTotal, setDiscountTotal] = useState(0);
  const user = (window as any).woonoowCustomer?.user;

  // Check if cart needs shipping (virtual-only carts don't need shipping)
  // Use cart.needs_shipping from WooCommerce API, fallback to item-level check
  const isVirtualOnly = React.useMemo(() => {
    // Prefer the needs_shipping flag from the cart API ( WooCommerce calculates this properly)
    if (typeof cart.needs_shipping === 'boolean') {
      return !cart.needs_shipping;
    }
    // Fallback: check individual items if needs_shipping not available
    if (cart.items.length === 0) return false;
    return cart.items.every(item => item.virtual || item.downloadable);
  }, [cart.items, cart.needs_shipping]);

  // Calculate totals
  const subtotal = cart.items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
  const tax = 0; // TODO: Calculate tax
  // Note: shipping is calculated from dynamic shippingCost state (defined below)

  // Form state
  const [billingData, setBillingData] = useState({
    firstName: '',
    lastName: '',
    email: '',
    phone: '',
    address: '',
    city: '',
    state: '',
    postcode: '',
    country: '',
  });

  const [shippingData, setShippingData] = useState({
    firstName: '',
    lastName: '',
    address: '',
    city: '',
    state: '',
    postcode: '',
    country: '',
  });

  const [shipToDifferentAddress, setShipToDifferentAddress] = useState(false);
  const [orderNotes, setOrderNotes] = useState('');
  const [paymentMethod, setPaymentMethod] = useState(isVirtualOnly ? 'bacs' : 'cod');

  // Saved addresses
  const [savedAddresses, setSavedAddresses] = useState<SavedAddress[]>([]);
  const [selectedBillingAddressId, setSelectedBillingAddressId] = useState<number | null>(null);
  const [selectedShippingAddressId, setSelectedShippingAddressId] = useState<number | null>(null);
  const [loadingAddresses, setLoadingAddresses] = useState(true);
  const [showBillingModal, setShowBillingModal] = useState(false);
  const [showShippingModal, setShowShippingModal] = useState(false);
  const [showBillingForm, setShowBillingForm] = useState(true);
  const [showShippingForm, setShowShippingForm] = useState(true);

  // Countries and states data
  const [countries, setCountries] = useState<{ code: string; name: string }[]>([]);
  const [states, setStates] = useState<Record<string, Record<string, string>>>({});
  const [defaultCountry, setDefaultCountry] = useState('');

  // Load countries and states
  useEffect(() => {
    const loadCountries = async () => {
      try {
        const data = await api.get<{
          countries: { code: string; name: string }[];
          states: Record<string, Record<string, string>>;
          default_country: string;
        }>('/countries');
        setCountries(data.countries || []);
        setStates(data.states || {});
        setDefaultCountry(data.default_country || '');

        // Set default country if not already set
        if (!billingData.country && data.default_country) {
          setBillingData(prev => ({ ...prev, country: data.default_country }));
        }
        if (!shippingData.country && data.default_country) {
          setShippingData(prev => ({ ...prev, country: data.default_country }));
        }
      } catch (error) {
        console.error('Failed to load countries:', error);
      }
    };
    loadCountries();
  }, []);

  // Country/state options for SearchableSelect
  const countryOptions = countries.map(c => ({ value: c.code, label: `${c.name} (${c.code})` }));
  const billingStateOptions = Object.entries(states[billingData.country] || {}).map(([code, name]) => ({ value: code, label: name }));
  const shippingStateOptions = Object.entries(states[shippingData.country] || {}).map(([code, name]) => ({ value: code, label: name }));

  // Clear state when country changes
  useEffect(() => {
    if (billingData.country && billingData.state) {
      const countryStates = states[billingData.country] || {};
      if (!countryStates[billingData.state]) {
        setBillingData(prev => ({ ...prev, state: '' }));
      }
    }
  }, [billingData.country, states]);

  useEffect(() => {
    if (shippingData.country && shippingData.state) {
      const countryStates = states[shippingData.country] || {};
      if (!countryStates[shippingData.state]) {
        setShippingData(prev => ({ ...prev, state: '' }));
      }
    }
  }, [shippingData.country, states]);

  // Dynamic checkout fields from API
  const [checkoutFields, setCheckoutFields] = useState<CheckoutField[]>([]);
  const [customFieldData, setCustomFieldData] = useState<Record<string, string>>({});

  // Dynamic shipping rates
  interface ShippingRate {
    id: string;
    label: string;
    cost: number;
    method_id: string;
    instance_id: number;
  }
  const [shippingRates, setShippingRates] = useState<ShippingRate[]>([]);
  const [selectedShippingRate, setSelectedShippingRate] = useState<string>('');
  const [isLoadingRates, setIsLoadingRates] = useState(false);
  const [shippingCost, setShippingCost] = useState(0);

  // Fetch checkout fields from API
  useEffect(() => {
    const loadCheckoutFields = async () => {
      if (cart.items.length === 0) return;

      try {
        const items = cart.items.map(item => ({
          product_id: item.product_id,
          qty: item.quantity,
        }));

        const data = await api.post<{
          ok: boolean;
          fields: CheckoutField[];
          is_digital_only: boolean;
        }>('/checkout/fields', { items, is_digital_only: isVirtualOnly });

        if (data.ok && data.fields) {
          setCheckoutFields(data.fields);

          // Initialize custom field values with defaults
          const customDefaults: Record<string, string> = {};
          data.fields.forEach(field => {
            if (field.default) {
              customDefaults[field.key] = field.default;
            }
          });
          if (Object.keys(customDefaults).length > 0) {
            setCustomFieldData(prev => ({ ...customDefaults, ...prev }));
          }

          // Set billing default values for hidden fields (e.g., Indonesia-only stores)
          const billingCountryField = data.fields.find(f => f.key === 'billing_country');
          if (billingCountryField?.type === 'hidden' && billingCountryField.default) {
            setBillingData(prev => ({ ...prev, country: billingCountryField.default || prev.country }));
          }

          // Set shipping default values for hidden fields
          const shippingCountryField = data.fields.find(f => f.key === 'shipping_country');
          if (shippingCountryField?.type === 'hidden' && shippingCountryField.default) {
            setShippingData(prev => ({ ...prev, country: shippingCountryField.default || prev.country }));
          }
        }
      } catch (error) {
        console.error('Failed to load checkout fields:', error);
      }
    };

    loadCheckoutFields();
  }, [cart.items, isVirtualOnly]);

  // NOTE: Old isFieldHidden function removed - now using getBillingField/getShippingField
  // which return undefined for hidden fields (type: 'hidden' or hidden: true)

  // Get all billing fields from API (standard + custom), filtered and sorted by priority
  // This allows ANY field to be hidden via PHP (type: 'hidden' or hidden: true)
  const billingFields = checkoutFields
    .filter(f => f.fieldset === 'billing' && f.type !== 'hidden' && !f.hidden)
    .sort((a, b) => (a.priority || 10) - (b.priority || 10));

  // Get all shipping fields from API (standard + custom), filtered and sorted by priority
  const shippingFields = checkoutFields
    .filter(f => f.fieldset === 'shipping' && f.type !== 'hidden' && !f.hidden)
    .sort((a, b) => (a.priority || 10) - (b.priority || 10));

  // Helper to get a billing field from API by key (for checking if it should be rendered)
  const getBillingField = (key: string) => billingFields.find(f => f.key === key);
  const getShippingField = (key: string) => shippingFields.find(f => f.key === key);

  // Helper to determine if a field should be full width based on class array from PHP
  // Supports: form-row-wide, form-row-first (half), form-row-last (half)
  const isFullWidthField = (fieldKey: string, fieldset: 'billing' | 'shipping' = 'billing'): boolean => {
    const field = fieldset === 'billing' ? getBillingField(fieldKey) : getShippingField(fieldKey);
    if (!field?.class || !Array.isArray(field.class)) return false;
    return field.class.includes('form-row-wide');
  };

  // Helper to get wrapper className for a field (handles width based on PHP class)
  const getFieldWrapperClass = (fieldKey: string, fieldset: 'billing' | 'shipping' = 'billing', defaultFullWidth = false): string => {
    if (isFullWidthField(fieldKey, fieldset) || defaultFullWidth) {
      return 'md:col-span-2';
    }
    return ''; // Default half width in 2-column grid
  };

  // Filter custom fields by fieldset (legacy support - for plugins that add non-standard fields)
  const billingCustomFields = checkoutFields.filter(f => f.fieldset === 'billing' && f.custom && !f.hidden && f.type !== 'hidden');
  const shippingCustomFields = checkoutFields.filter(f => f.fieldset === 'shipping' && f.custom && !f.hidden && f.type !== 'hidden');

  // Handler for custom field changes
  const handleCustomFieldChange = (key: string, value: string) => {
    setCustomFieldData(prev => ({ ...prev, [key]: value }));
  };

  // Listen for label events from searchable_select
  useEffect(() => {
    const handleLabelEvent = (e: Event) => {
      const { key, value } = (e as CustomEvent).detail;
      setCustomFieldData(prev => ({ ...prev, [key]: value }));
    };
    document.addEventListener('woonoow:field_label', handleLabelEvent);
    return () => document.removeEventListener('woonoow:field_label', handleLabelEvent);
  }, []);

  // Fetch shipping rates when address changes
  const fetchShippingRates = async () => {
    if (isVirtualOnly || !cart.items.length) return;

    // Get address data (use shipping if different, otherwise billing)
    const addressData = shipToDifferentAddress ? shippingData : billingData;

    // Need at least country to calculate shipping
    if (!addressData.country) {
      setShippingRates([]);
      return;
    }

    setIsLoadingRates(true);
    try {
      const items = cart.items.map(item => ({
        product_id: item.product_id,
        quantity: item.quantity,
      }));

      const destinationId = shipToDifferentAddress
        ? customFieldData['shipping_destination_id']
        : customFieldData['billing_destination_id'];

      const response = await api.post<{ ok: boolean; rates: ShippingRate[]; zone_name?: string }>('/checkout/shipping-rates', {
        shipping: {
          country: addressData.country,
          state: addressData.state,
          city: addressData.city,
          postcode: addressData.postcode,
          destination_id: destinationId || undefined,
        },
        items,
      });

      if (response.ok && response.rates) {
        setShippingRates(response.rates);
        // Auto-select first rate if none selected
        if (response.rates.length > 0 && !selectedShippingRate) {
          setSelectedShippingRate(response.rates[0].id);
          setShippingCost(response.rates[0].cost);
        }
      }
    } catch (error) {
      console.error('Failed to fetch shipping rates:', error);
      setShippingRates([]);
    } finally {
      setIsLoadingRates(false);
    }
  };

  // Trigger shipping rate fetch when address or destination changes
  useEffect(() => {
    const addressData = shipToDifferentAddress ? shippingData : billingData;
    const destinationId = shipToDifferentAddress
      ? customFieldData['shipping_destination_id']
      : customFieldData['billing_destination_id'];

    // Debounce the fetch
    const timeoutId = setTimeout(() => {
      if (addressData.country) {
        fetchShippingRates();
      }
    }, 500);

    return () => clearTimeout(timeoutId);
  }, [
    billingData.country, billingData.state, billingData.city, billingData.postcode,
    shippingData.country, shippingData.state, shippingData.city, shippingData.postcode,
    shipToDifferentAddress,
    customFieldData['billing_destination_id'],
    customFieldData['shipping_destination_id'],
    cart.items.length,
  ]);

  // Update shipping cost when rate selected
  const handleShippingRateChange = (rateId: string) => {
    setSelectedShippingRate(rateId);
    const rate = shippingRates.find(r => r.id === rateId);
    setShippingCost(rate?.cost || 0);
  };

  useEffect(() => {
    const loadAddresses = async () => {
      if (!user?.isLoggedIn) {
        setLoadingAddresses(false);
        return;
      }

      try {
        const addresses = await api.get<SavedAddress[]>('/account/addresses');
        setSavedAddresses(addresses);

        // Auto-select default addresses
        const defaultBilling = addresses.find(a => a.is_default && (a.type === 'billing' || a.type === 'both'));
        const defaultShipping = addresses.find(a => a.is_default && (a.type === 'shipping' || a.type === 'both'));

        if (defaultBilling) {
          setSelectedBillingAddressId(defaultBilling.id);
          fillBillingFromAddress(defaultBilling);
          setShowBillingForm(false); // Hide form when default address is auto-selected
        }
        if (defaultShipping && !isVirtualOnly) {
          setSelectedShippingAddressId(defaultShipping.id);
          fillShippingFromAddress(defaultShipping);
          setShowShippingForm(false); // Hide form when default address is auto-selected
        }
      } catch (error) {
        console.error('Failed to load addresses:', error);
      } finally {
        setLoadingAddresses(false);
      }
    };

    loadAddresses();
  }, [user, isVirtualOnly]);

  // Helper functions to fill forms from saved addresses
  const fillBillingFromAddress = (address: SavedAddress) => {
    setBillingData({
      firstName: address.first_name,
      lastName: address.last_name,
      email: address.email || billingData.email,
      phone: address.phone || billingData.phone,
      address: address.address_1,
      city: address.city,
      state: address.state,
      postcode: address.postcode,
      country: address.country,
    });
  };

  const fillShippingFromAddress = (address: SavedAddress) => {
    setShippingData({
      firstName: address.first_name,
      lastName: address.last_name,
      address: address.address_1,
      city: address.city,
      state: address.state,
      postcode: address.postcode,
      country: address.country,
    });
  };

  const handleSelectBillingAddress = (address: SavedAddress) => {
    setSelectedBillingAddressId(address.id);
    fillBillingFromAddress(address);
    setShowBillingForm(false); // Hide form when address is selected
  };

  const handleSelectShippingAddress = (address: SavedAddress) => {
    setSelectedShippingAddressId(address.id);
    fillShippingFromAddress(address);
    setShowShippingForm(false); // Hide form when address is selected
  };

  // Auto-fill form with user data if logged in
  useEffect(() => {
    if (user?.isLoggedIn && user?.billing && savedAddresses.length === 0) {
      setBillingData({
        firstName: user.billing.first_name || '',
        lastName: user.billing.last_name || '',
        email: user.billing.email || user.email || '',
        phone: user.billing.phone || '',
        address: user.billing.address_1 || '',
        city: user.billing.city || '',
        state: user.billing.state || '',
        postcode: user.billing.postcode || '',
        country: user.billing.country || '',
      });
    }

    if (user?.isLoggedIn && user?.shipping) {
      setShippingData({
        firstName: user.shipping.first_name || '',
        lastName: user.shipping.last_name || '',
        address: user.shipping.address_1 || '',
        city: user.shipping.city || '',
        state: user.shipping.state || '',
        postcode: user.shipping.postcode || '',
        country: user.shipping.country || '',
      });
    }
  }, [user]);

  const handleApplyCoupon = async () => {
    if (!couponCode.trim()) return;

    setIsApplyingCoupon(true);
    try {
      const updatedCart = await applyCoupon(couponCode.trim());
      if (updatedCart.coupons) {
        setAppliedCoupons(updatedCart.coupons);
        setDiscountTotal(updatedCart.discount_total || 0);
      }
      setCouponCode('');
      toast.success('Coupon applied successfully');
    } catch (error: any) {
      toast.error(error.message || 'Failed to apply coupon');
    } finally {
      setIsApplyingCoupon(false);
    }
  };

  const handleRemoveCoupon = async (code: string) => {
    setIsApplyingCoupon(true);
    try {
      const updatedCart = await removeCoupon(code);
      if (updatedCart.coupons) {
        setAppliedCoupons(updatedCart.coupons);
        setDiscountTotal(updatedCart.discount_total || 0);
      }
      toast.success('Coupon removed');
    } catch (error: any) {
      toast.error(error.message || 'Failed to remove coupon');
    } finally {
      setIsApplyingCoupon(false);
    }
  };

  // Load cart data including coupons on mount
  useEffect(() => {
    const loadCartData = async () => {
      try {
        const cartData = await fetchCart();
        if (cartData.coupons) {
          setAppliedCoupons(cartData.coupons);
          setDiscountTotal(cartData.discount_total || 0);
        }
      } catch (error) {
        console.error('Failed to load cart data:', error);
      }
    };
    loadCartData();
  }, []);

  const handlePlaceOrder = async (e: React.FormEvent) => {
    e.preventDefault();
    setIsProcessing(true);

    try {
      // Prepare order data
      const orderData = {
        items: cart.items.map(item => ({
          product_id: item.product_id,
          variation_id: item.variation_id,
          qty: item.quantity,
          meta: item.attributes ? Object.entries(item.attributes).map(([key, value]) => ({
            key,
            value
          })) : []
        })),
        billing: {
          first_name: billingData.firstName,
          last_name: billingData.lastName,
          email: billingData.email,
          phone: billingData.phone,
          address_1: billingData.address,
          city: billingData.city,
          state: billingData.state,
          postcode: billingData.postcode,
          country: billingData.country,
          // Include custom billing fields
          ...Object.fromEntries(
            billingCustomFields.map(f => [f.key.replace('billing_', ''), customFieldData[f.key] || ''])
          ),
        },
        shipping: shipToDifferentAddress ? {
          first_name: shippingData.firstName,
          last_name: shippingData.lastName,
          address_1: shippingData.address,
          city: shippingData.city,
          state: shippingData.state,
          postcode: shippingData.postcode,
          country: shippingData.country,
          ship_to_different: true,
          // Include custom shipping fields
          ...Object.fromEntries(
            shippingCustomFields.map(f => [f.key.replace('shipping_', ''), customFieldData[f.key] || ''])
          ),
        } : {
          ship_to_different: false,
        },
        payment_method: paymentMethod,
        shipping_method: selectedShippingRate || undefined, // Selected shipping rate ID
        // Also send shipping cost/title for direct use when WC rate lookup fails (API-based shipping like Rajaongkir)
        shipping_cost: shippingCost,
        shipping_title: shippingRates.find(r => r.id === selectedShippingRate)?.label || '',
        coupons: appliedCoupons.map(c => c.code), // Send applied coupon codes
        customer_note: orderNotes,
        // Include all custom field data for backend processing
        custom_fields: customFieldData,
      };

      // Submit order
      const response = await apiClient.post('/checkout/submit', orderData);
      const data = (response as any).data || response;

      if (data.ok && data.order_id) {
        // Clear cart - use store method directly
        useCartStore.getState().clearCart();

        toast.success('Order placed successfully!');

        // Navigate to thank you page via SPA routing
        // Using window.location.replace to prevent back button issues
        const thankYouUrl = `/order-received/${data.order_id}?key=${data.order_key}`;
        navigate(thankYouUrl, { replace: true });
        return; // Stop execution here
      } else {
        throw new Error(data.error || 'Failed to create order');
      }
    } catch (error: any) {
      toast.error(error.message || 'Failed to place order');
      console.error('Order creation error:', error);
    } finally {
      setIsProcessing(false);
    }
  };

  // Empty cart redirect (but only if not processing)
  if (cart.items.length === 0 && !isProcessing) {
    return (
      <Container>
        <div className="text-center py-16">
          <ShoppingBag className="mx-auto h-16 w-16 text-gray-400 mb-4" />
          <h2 className="text-2xl font-bold mb-2">Your cart is empty</h2>
          <p className="text-gray-600 mb-6">Add some products before checking out!</p>
          <Button onClick={() => navigate('/shop')}>
            <ArrowLeft className="mr-2 h-4 w-4" />
            Continue Shopping
          </Button>
        </div>
      </Container>
    );
  }

  return (
    <Container>
      <SEOHead title="Checkout" description="Complete your purchase" />
      <div className="py-8">
        {/* Header */}
        <div className="mb-8">
          <Button variant="ghost" onClick={() => navigate('/cart')} className="mb-4">
            <ArrowLeft className="mr-2 h-4 w-4" />
            Back to Cart
          </Button>
          <h1 className="text-3xl font-bold">Checkout</h1>
        </div>

        <form onSubmit={handlePlaceOrder}>
          <div className={`grid gap-8 ${layout.style === 'single-column' ? 'grid-cols-1' : layout.order_summary === 'top' ? 'grid-cols-1' : 'lg:grid-cols-3'}`}>
            {/* Billing & Shipping Forms */}
            <div className={`space-y-6 ${layout.style === 'single-column' || layout.order_summary === 'top' ? '' : 'lg:col-span-2'}`}>
              {/* Selected Billing Address Summary */}
              {!loadingAddresses && savedAddresses.length > 0 && savedAddresses.some(a => a.type === 'billing' || a.type === 'both') && (
                <div className="bg-white border rounded-lg p-6">
                  <div className="flex items-center justify-between mb-4">
                    <h2 className="text-xl font-bold flex items-center gap-2">
                      <MapPin className="w-5 h-5" />
                      Billing Address
                    </h2>
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      onClick={() => setShowBillingModal(true)}
                      className="flex items-center gap-2"
                    >
                      <Edit2 className="w-4 h-4" />
                      Change Address
                    </Button>
                  </div>

                  {selectedBillingAddressId ? (
                    (() => {
                      const selected = savedAddresses.find(a => a.id === selectedBillingAddressId);
                      return selected ? (
                        <div>
                          <div className="bg-primary/5 border-2 border-primary rounded-lg p-4">
                            <div className="flex items-center gap-2 mb-2">
                              <p className="font-semibold">{selected.label}</p>
                              {selected.is_default && (
                                <span className="text-xs bg-green-100 text-green-700 px-2 py-0.5 rounded">Default</span>
                              )}
                            </div>
                            <p className="text-sm font-medium text-gray-900">{selected.first_name} {selected.last_name}</p>
                            {selected.phone && <p className="text-sm text-gray-600">{selected.phone}</p>}
                            <p className="text-sm text-gray-600 mt-2">{selected.address_1}</p>
                            {selected.address_2 && <p className="text-sm text-gray-600">{selected.address_2}</p>}
                            <p className="text-sm text-gray-600">{selected.city}, {selected.state} {selected.postcode}</p>
                            <p className="text-sm text-gray-600">{selected.country}</p>
                          </div>
                          <Button
                            type="button"
                            variant="ghost"
                            size="sm"
                            onClick={() => setShowBillingForm(true)}
                            className="mt-3 text-primary hover:text-primary"
                          >
                            Use a different address
                          </Button>
                        </div>
                      ) : null;
                    })()
                  ) : (
                    <p className="text-gray-500 text-sm">No address selected</p>
                  )}
                </div>
              )}

              {/* Billing Address Modal */}
              <AddressSelector
                isOpen={showBillingModal}
                onClose={() => setShowBillingModal(false)}
                addresses={savedAddresses}
                selectedAddressId={selectedBillingAddressId}
                onSelectAddress={handleSelectBillingAddress}
                type="billing"
              />

              {/* Billing Details Form - Only show if no saved address selected or user wants to enter manually */}
              {(savedAddresses.length === 0 || !selectedBillingAddressId || showBillingForm) && (
                <div className="bg-white border rounded-lg p-6">
                  <h2 className="text-xl font-bold mb-4">Billing Details</h2>
                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                    {/* All fields conditionally rendered based on API response */}
                    {/* This allows ANY field to be hidden via PHP snippet */}
                    {/* Width controlled via class: ['form-row-wide'] from PHP */}
                    {getBillingField('billing_first_name') && (
                      <div className={getFieldWrapperClass('billing_first_name', 'billing')}>
                        <label className="block text-sm font-medium mb-2">{getBillingField('billing_first_name')?.label || 'First Name'} {getBillingField('billing_first_name')?.required && '*'}</label>
                        <input
                          type="text"
                          required={getBillingField('billing_first_name')?.required}
                          value={billingData.firstName}
                          onChange={(e) => setBillingData({ ...billingData, firstName: e.target.value })}
                          className="w-full border !rounded-lg px-4 py-2"
                        />
                      </div>
                    )}
                    {getBillingField('billing_last_name') && (
                      <div className={getFieldWrapperClass('billing_last_name', 'billing')}>
                        <label className="block text-sm font-medium mb-2">{getBillingField('billing_last_name')?.label || 'Last Name'} {getBillingField('billing_last_name')?.required && '*'}</label>
                        <input
                          type="text"
                          required={getBillingField('billing_last_name')?.required}
                          value={billingData.lastName}
                          onChange={(e) => setBillingData({ ...billingData, lastName: e.target.value })}
                          className="w-full border !rounded-lg px-4 py-2"
                        />
                      </div>
                    )}
                    {getBillingField('billing_email') && (
                      <div className="md:col-span-2">
                        <label className="block text-sm font-medium mb-2">{getBillingField('billing_email')?.label || 'Email Address'} {getBillingField('billing_email')?.required && '*'}</label>
                        <input
                          type="email"
                          required={getBillingField('billing_email')?.required}
                          value={billingData.email}
                          onChange={(e) => setBillingData({ ...billingData, email: e.target.value })}
                          className="w-full border !rounded-lg px-4 py-2"
                        />
                      </div>
                    )}
                    {getBillingField('billing_phone') && (
                      <div className="md:col-span-2">
                        <label className="block text-sm font-medium mb-2">{getBillingField('billing_phone')?.label || 'Phone'} {getBillingField('billing_phone')?.required && '*'}</label>
                        <input
                          type="tel"
                          required={getBillingField('billing_phone')?.required}
                          value={billingData.phone}
                          onChange={(e) => setBillingData({ ...billingData, phone: e.target.value })}
                          className="w-full border !rounded-lg px-4 py-2"
                        />
                      </div>
                    )}

                    {/* Address fields - only for physical products */}
                    {!isVirtualOnly && (
                      <>
                        {getBillingField('billing_address_1') && (
                          <div className="md:col-span-2">
                            <label className="block text-sm font-medium mb-2">{getBillingField('billing_address_1')?.label || 'Street Address'} {getBillingField('billing_address_1')?.required && '*'}</label>
                            <input
                              type="text"
                              required={getBillingField('billing_address_1')?.required}
                              value={billingData.address}
                              onChange={(e) => setBillingData({ ...billingData, address: e.target.value })}
                              className="w-full border !rounded-lg px-4 py-2"
                            />
                          </div>
                        )}
                        {/* City field - conditionally rendered based on API */}
                        {getBillingField('billing_city') && (
                          <div>
                            <label className="block text-sm font-medium mb-2">{getBillingField('billing_city')?.label || 'City'} {getBillingField('billing_city')?.required && '*'}</label>
                            <input
                              type="text"
                              required={getBillingField('billing_city')?.required}
                              value={billingData.city}
                              onChange={(e) => setBillingData({ ...billingData, city: e.target.value })}
                              className="w-full border !rounded-lg px-4 py-2"
                            />
                          </div>
                        )}
                        {/* Country field - conditionally rendered based on API */}
                        {getBillingField('billing_country') && (
                          <div>
                            <label className="block text-sm font-medium mb-2">{getBillingField('billing_country')?.label || 'Country'} {getBillingField('billing_country')?.required && '*'}</label>
                            <SearchableSelect
                              options={countryOptions}
                              value={billingData.country}
                              onChange={(v) => setBillingData({ ...billingData, country: v })}
                              placeholder="Select country"
                              disabled={countries.length === 1}
                            />
                          </div>
                        )}
                        {/* State field - conditionally rendered based on API */}
                        {getBillingField('billing_state') && (
                          <div>
                            <label className="block text-sm font-medium mb-2">{getBillingField('billing_state')?.label || 'State / Province'} {getBillingField('billing_state')?.required && '*'}</label>
                            {billingStateOptions.length > 0 ? (
                              <SearchableSelect
                                options={billingStateOptions}
                                value={billingData.state}
                                onChange={(v) => setBillingData({ ...billingData, state: v })}
                                placeholder="Select state"
                              />
                            ) : (
                              <input
                                type="text"
                                value={billingData.state}
                                onChange={(e) => setBillingData({ ...billingData, state: e.target.value })}
                                placeholder="Enter state/province"
                                className="w-full border !rounded-lg px-4 py-2"
                              />
                            )}
                          </div>
                        )}
                        {/* Postcode field - conditionally rendered based on API */}
                        {getBillingField('billing_postcode') && (
                          <div>
                            <label className="block text-sm font-medium mb-2">{getBillingField('billing_postcode')?.label || 'Postcode / ZIP'} {getBillingField('billing_postcode')?.required && '*'}</label>
                            <input
                              type="text"
                              required={getBillingField('billing_postcode')?.required}
                              value={billingData.postcode}
                              onChange={(e) => setBillingData({ ...billingData, postcode: e.target.value })}
                              className="w-full border !rounded-lg px-4 py-2"
                            />
                          </div>
                        )}

                        {/* Custom billing fields from plugins */}
                        {billingCustomFields.map(field => (
                          <DynamicCheckoutField
                            key={field.key}
                            field={field}
                            value={customFieldData[field.key] || ''}
                            onChange={(v) => handleCustomFieldChange(field.key, v)}
                            countryOptions={countryOptions}
                            stateOptions={billingStateOptions}
                          />
                        ))}
                      </>
                    )}
                  </div>
                </div>
              )}

              {/* Ship to Different Address - only for physical products */}
              {!isVirtualOnly && (
                <div className="bg-white border rounded-lg p-6">
                  <label className="flex items-center gap-2 mb-4">
                    <input
                      type="checkbox"
                      checked={shipToDifferentAddress}
                      onChange={(e) => setShipToDifferentAddress(e.target.checked)}
                      className="w-4 h-4"
                    />
                    <span className="font-medium">Ship to a different address?</span>
                  </label>

                  {shipToDifferentAddress && (
                    <>
                      {/* Selected Shipping Address Summary */}
                      {!loadingAddresses && savedAddresses.length > 0 && savedAddresses.some(a => a.type === 'shipping' || a.type === 'both') && (
                        <div className="mb-6">
                          <div className="flex items-center justify-between mb-3">
                            <h3 className="text-lg font-semibold flex items-center gap-2">
                              <MapPin className="w-4 h-4" />
                              Shipping Address
                            </h3>
                            <Button
                              type="button"
                              variant="outline"
                              size="sm"
                              onClick={() => setShowShippingModal(true)}
                              className="flex items-center gap-2"
                            >
                              <Edit2 className="w-4 h-4" />
                              Change Address
                            </Button>
                          </div>

                          {selectedShippingAddressId ? (
                            (() => {
                              const selected = savedAddresses.find(a => a.id === selectedShippingAddressId);
                              return selected ? (
                                <div>
                                  <div className="bg-primary/5 border-2 border-primary rounded-lg p-4">
                                    <div className="flex items-center gap-2 mb-2">
                                      <p className="font-semibold">{selected.label}</p>
                                      {selected.is_default && (
                                        <span className="text-xs bg-green-100 text-green-700 px-2 py-0.5 rounded">Default</span>
                                      )}
                                    </div>
                                    <p className="text-sm font-medium text-gray-900">{selected.first_name} {selected.last_name}</p>
                                    {selected.phone && <p className="text-sm text-gray-600">{selected.phone}</p>}
                                    <p className="text-sm text-gray-600 mt-2">{selected.address_1}</p>
                                    {selected.address_2 && <p className="text-sm text-gray-600">{selected.address_2}</p>}
                                    <p className="text-sm text-gray-600">{selected.city}, {selected.state} {selected.postcode}</p>
                                    <p className="text-sm text-gray-600">{selected.country}</p>
                                  </div>
                                  <Button
                                    type="button"
                                    variant="ghost"
                                    size="sm"
                                    onClick={() => setShowShippingForm(true)}
                                    className="mt-3 text-primary hover:text-primary"
                                  >
                                    Use a different address
                                  </Button>
                                </div>
                              ) : null;
                            })()
                          ) : (
                            <p className="text-gray-500 text-sm">No address selected</p>
                          )}
                        </div>
                      )}

                      {/* Shipping Address Modal */}
                      <AddressSelector
                        isOpen={showShippingModal}
                        onClose={() => setShowShippingModal(false)}
                        addresses={savedAddresses}
                        selectedAddressId={selectedShippingAddressId}
                        onSelectAddress={handleSelectShippingAddress}
                        type="shipping"
                      />

                      {/* Shipping Form - Only show if no saved address selected or user wants to enter manually */}
                      {(!selectedShippingAddressId || showShippingForm) && (
                        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                          {/* Dynamic shipping fields using getShippingField like billing */}
                          {getShippingField('shipping_first_name') && (
                            <div className={getFieldWrapperClass('shipping_first_name', 'shipping')}>
                              <label className="block text-sm font-medium mb-2">{getShippingField('shipping_first_name')?.label || 'First Name'} {getShippingField('shipping_first_name')?.required && '*'}</label>
                              <input
                                type="text"
                                required={getShippingField('shipping_first_name')?.required}
                                value={shippingData.firstName}
                                onChange={(e) => setShippingData({ ...shippingData, firstName: e.target.value })}
                                className="w-full border !rounded-lg px-4 py-2"
                              />
                            </div>
                          )}
                          {getShippingField('shipping_last_name') && (
                            <div className={getFieldWrapperClass('shipping_last_name', 'shipping')}>
                              <label className="block text-sm font-medium mb-2">{getShippingField('shipping_last_name')?.label || 'Last Name'} {getShippingField('shipping_last_name')?.required && '*'}</label>
                              <input
                                type="text"
                                required={getShippingField('shipping_last_name')?.required}
                                value={shippingData.lastName}
                                onChange={(e) => setShippingData({ ...shippingData, lastName: e.target.value })}
                                className="w-full border !rounded-lg px-4 py-2"
                              />
                            </div>
                          )}
                          {getShippingField('shipping_address_1') && (
                            <div className={getFieldWrapperClass('shipping_address_1', 'shipping') || 'md:col-span-2'}>
                              <label className="block text-sm font-medium mb-2">{getShippingField('shipping_address_1')?.label || 'Street Address'} {getShippingField('shipping_address_1')?.required && '*'}</label>
                              <input
                                type="text"
                                required={getShippingField('shipping_address_1')?.required}
                                value={shippingData.address}
                                onChange={(e) => setShippingData({ ...shippingData, address: e.target.value })}
                                className="w-full border !rounded-lg px-4 py-2"
                              />
                            </div>
                          )}
                          {/* City field - conditionally rendered based on API */}
                          {getShippingField('shipping_city') && (
                            <div>
                              <label className="block text-sm font-medium mb-2">{getShippingField('shipping_city')?.label || 'City'} {getShippingField('shipping_city')?.required && '*'}</label>
                              <input
                                type="text"
                                required={getShippingField('shipping_city')?.required}
                                value={shippingData.city}
                                onChange={(e) => setShippingData({ ...shippingData, city: e.target.value })}
                                className="w-full border !rounded-lg px-4 py-2"
                              />
                            </div>
                          )}
                          {/* Country field - conditionally rendered based on API */}
                          {getShippingField('shipping_country') && (
                            <div>
                              <label className="block text-sm font-medium mb-2">{getShippingField('shipping_country')?.label || 'Country'} {getShippingField('shipping_country')?.required && '*'}</label>
                              <SearchableSelect
                                options={countryOptions}
                                value={shippingData.country}
                                onChange={(v) => setShippingData({ ...shippingData, country: v })}
                                placeholder="Select country"
                                disabled={countries.length === 1}
                              />
                            </div>
                          )}
                          {/* State field - conditionally rendered based on API */}
                          {getShippingField('shipping_state') && (
                            <div>
                              <label className="block text-sm font-medium mb-2">{getShippingField('shipping_state')?.label || 'State / Province'} {getShippingField('shipping_state')?.required && '*'}</label>
                              {shippingStateOptions.length > 0 ? (
                                <SearchableSelect
                                  options={shippingStateOptions}
                                  value={shippingData.state}
                                  onChange={(v) => setShippingData({ ...shippingData, state: v })}
                                  placeholder="Select state"
                                />
                              ) : (
                                <input
                                  type="text"
                                  value={shippingData.state}
                                  onChange={(e) => setShippingData({ ...shippingData, state: e.target.value })}
                                  placeholder="Enter state/province"
                                  className="w-full border !rounded-lg px-4 py-2"
                                />
                              )}
                            </div>
                          )}
                          {/* Postcode field - conditionally rendered based on API */}
                          {getShippingField('shipping_postcode') && (
                            <div>
                              <label className="block text-sm font-medium mb-2">{getShippingField('shipping_postcode')?.label || 'Postcode / ZIP'} {getShippingField('shipping_postcode')?.required && '*'}</label>
                              <input
                                type="text"
                                required={getShippingField('shipping_postcode')?.required}
                                value={shippingData.postcode}
                                onChange={(e) => setShippingData({ ...shippingData, postcode: e.target.value })}
                                className="w-full border !rounded-lg px-4 py-2"
                              />
                            </div>
                          )}

                          {/* Custom shipping fields from plugins */}
                          {shippingCustomFields.map(field => (
                            <DynamicCheckoutField
                              key={field.key}
                              field={field}
                              value={customFieldData[field.key] || ''}
                              onChange={(v) => handleCustomFieldChange(field.key, v)}
                              countryOptions={countryOptions}
                              stateOptions={shippingStateOptions}
                            />
                          ))}
                        </div>
                      )}
                    </>
                  )}
                </div>
              )}

              {/* Order Notes */}
              {elements.order_notes && (
                <div className="bg-white border rounded-lg p-6">
                  <h2 className="text-xl font-bold mb-4">Order Notes (Optional)</h2>
                  <textarea
                    value={orderNotes}
                    onChange={(e) => setOrderNotes(e.target.value)}
                    placeholder="Notes about your order, e.g. special notes for delivery."
                    className="w-full border !rounded-lg px-4 py-2 h-32"
                  />
                </div>
              )}
            </div>

            {/* Order Summary */}
            <div className={`${layout.style === 'single-column' || layout.order_summary === 'top' ? 'order-first' : 'lg:col-span-1'}`}>
              <div className="bg-white border rounded-lg p-6 sticky top-4">
                <h2 className="text-xl font-bold mb-4">Your Order</h2>

                {/* Coupon Field */}
                {elements.coupon_field && (
                  <div className="mb-4 pb-4 border-b">
                    <label className="block text-sm font-medium mb-2">Coupon Code</label>
                    <div className="flex gap-2">
                      <input
                        type="text"
                        placeholder="Enter coupon code"
                        value={couponCode}
                        onChange={(e) => setCouponCode(e.target.value)}
                        onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), handleApplyCoupon())}
                        className="flex-1 px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary"
                        disabled={isApplyingCoupon}
                      />
                      <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        onClick={handleApplyCoupon}
                        disabled={isApplyingCoupon || !couponCode.trim()}
                      >
                        {isApplyingCoupon ? <Loader2 className="h-4 w-4 animate-spin" /> : 'Apply'}
                      </Button>
                    </div>

                    {/* Applied Coupons */}
                    {appliedCoupons.length > 0 && (
                      <div className="mt-3 space-y-2">
                        {appliedCoupons.map((coupon) => (
                          <div key={coupon.code} className="flex items-center justify-between p-2 bg-green-50 border border-green-200 rounded-md">
                            <div className="flex items-center gap-2">
                              <Tag className="h-4 w-4 text-green-600" />
                              <span className="text-sm font-medium text-green-800">{coupon.code}</span>
                              <span className="text-sm text-green-600">-{formatPrice(coupon.discount)}</span>
                            </div>
                            <button
                              type="button"
                              onClick={() => handleRemoveCoupon(coupon.code)}
                              className="text-green-600 hover:text-green-800 p-1"
                              disabled={isApplyingCoupon}
                            >
                              <X className="h-4 w-4" />
                            </button>
                          </div>
                        ))}
                      </div>
                    )}
                  </div>
                )}

                {/* Order Items */}
                <div className="space-y-3 mb-4 pb-4 border-b">
                  {cart.items.map((item) => (
                    <div key={item.key} className="flex justify-between text-sm">
                      <span>
                        {item.name} × {item.quantity}
                      </span>
                      <span className="font-medium">
                        {formatPrice(item.price * item.quantity)}
                      </span>
                    </div>
                  ))}
                </div>

                {/* Shipping Options */}
                {!isVirtualOnly && elements.shipping_options && (
                  <div className="mb-4 pb-4 border-b">
                    <h3 className="font-medium mb-3">Shipping Method</h3>
                    <div className="space-y-2">
                      {isLoadingRates ? (
                        <div className="flex items-center gap-2 p-3 text-sm text-gray-500">
                          <Loader2 className="h-4 w-4 animate-spin" />
                          <span>Calculating shipping rates...</span>
                        </div>
                      ) : shippingRates.length === 0 ? (
                        <div className="p-3 text-sm text-gray-500">
                          {billingData.country
                            ? 'No shipping methods available for your location'
                            : 'Enter your address to see shipping options'}
                        </div>
                      ) : (
                        shippingRates.map((rate) => (
                          <label
                            key={rate.id}
                            className={`flex items-center justify-between p-3 border rounded-lg cursor-pointer hover:bg-gray-50 ${selectedShippingRate === rate.id ? 'border-primary bg-primary/5' : ''
                              }`}
                          >
                            <div className="flex items-center gap-2">
                              <input
                                type="radio"
                                name="shipping_method"
                                value={rate.id}
                                checked={selectedShippingRate === rate.id}
                                onChange={() => handleShippingRateChange(rate.id)}
                                className="w-4 h-4"
                              />
                              <span className="text-sm">{rate.label}</span>
                            </div>
                            <span className="text-sm font-medium">
                              {rate.cost === 0 ? 'Free' : formatPrice(rate.cost)}
                            </span>
                          </label>
                        ))
                      )}
                    </div>
                  </div>
                )}

                {/* Totals */}
                <div className="space-y-2 mb-6">
                  <div className="flex justify-between text-sm">
                    <span>Subtotal</span>
                    <span>{formatPrice(subtotal)}</span>
                  </div>
                  {/* Show discount if coupons applied */}
                  {discountTotal > 0 && (
                    <div className="flex justify-between text-sm text-green-600">
                      <span>Discount</span>
                      <span>-{formatPrice(discountTotal)}</span>
                    </div>
                  )}
                  {!isVirtualOnly && (
                    <div className="flex justify-between text-sm">
                      <span>Shipping</span>
                      <span>{shippingCost === 0 ? 'Free' : formatPrice(shippingCost)}</span>
                    </div>
                  )}
                  {tax > 0 && (
                    <div className="flex justify-between text-sm">
                      <span>Tax</span>
                      <span>{formatPrice(tax)}</span>
                    </div>
                  )}
                  <div className="border-t pt-2 flex justify-between font-bold text-lg">
                    <span>Total</span>
                    <span>{formatPrice(subtotal + (isVirtualOnly ? 0 : shippingCost) + tax - discountTotal)}</span>
                  </div>
                </div>

                {/* Payment Method */}
                <div className="mb-6">
                  <h3 className="font-medium mb-3">Payment Method</h3>
                  <div className="space-y-2">
                    {/* Hide COD for virtual-only products */}
                    {!isVirtualOnly && (
                      <label className="flex items-center gap-2 p-3 border rounded-lg cursor-pointer hover:bg-gray-50">
                        <input
                          type="radio"
                          name="payment"
                          value="cod"
                          checked={paymentMethod === 'cod'}
                          onChange={(e) => setPaymentMethod(e.target.value)}
                          className="w-4 h-4"
                        />
                        <span>Cash on Delivery</span>
                      </label>
                    )}
                    <label className="flex items-center gap-2 p-3 border rounded-lg cursor-pointer hover:bg-gray-50">
                      <input
                        type="radio"
                        name="payment"
                        value="bacs"
                        checked={paymentMethod === 'bacs'}
                        onChange={(e) => setPaymentMethod(e.target.value)}
                        className="w-4 h-4"
                      />
                      <span>Bank Transfer</span>
                    </label>
                  </div>

                  {/* Payment Icons */}
                  {elements.payment_icons && (
                    <div className="flex items-center gap-2 mt-3 pt-3 border-t">
                      <span className="text-xs text-gray-500">We accept:</span>
                      <div className="flex gap-1">
                        <div className="w-10 h-6 bg-gray-100 rounded flex items-center justify-center text-xs font-bold">VISA</div>
                        <div className="w-10 h-6 bg-gray-100 rounded flex items-center justify-center text-xs font-bold">MC</div>
                        <div className="w-10 h-6 bg-gray-100 rounded flex items-center justify-center text-xs font-bold">AMEX</div>
                      </div>
                    </div>
                  )}
                </div>

                {/* Place Order Button - Only show in sidebar layout */}
                {layout.order_summary !== 'top' && (
                  <Button
                    type="submit"
                    size="lg"
                    className="w-full"
                    disabled={isProcessing}
                  >
                    {isProcessing ? 'Processing...' : 'Place Order'}
                  </Button>
                )}
              </div>
            </div>
          </div>

          {/* Place Order Button - Show at bottom when summary is on top */}
          {layout.order_summary === 'top' && (
            <div className="mt-6">
              <Button
                type="submit"
                size="lg"
                className="w-full"
                disabled={isProcessing}
              >
                {isProcessing ? 'Processing...' : 'Place Order'}
              </Button>
            </div>
          )}
        </form>
      </div>
    </Container>
  );
}
