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, Edit2, Loader2, X, Tag, Check, ChevronDown } 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';
import { CaptchaWidget } from '@/components/CaptchaWidget';
import { cn } from '@/lib/utils';

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 [activeStep, setActiveStep] = useState(1); // 1=Information, 2=Shipping, 3=Payment

  const [couponCode, setCouponCode] = useState('');
  const [isApplyingCoupon, setIsApplyingCoupon] = useState(false);
  const [appliedCoupons, setAppliedCoupons] = useState<{ code: string; discount: number }[]>([]);
  const [discountTotal, setDiscountTotal] = useState(0);
  const [captchaToken, setCaptchaToken] = useState('');
  const user = (window as any).woonoowCustomer?.user;
  const security = (window as any).woonoowCustomer?.security;

  // 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>>>({});

  // 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 || {});

        // 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();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // 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, billingData.state, states]);

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

  }, [shippingData.country, shippingData.state, 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);
  const billingFirstNameField = getBillingField('billing_first_name');
  const billingLastNameField = getBillingField('billing_last_name');
  const shippingFirstNameField = getShippingField('shipping_first_name');
  const shippingLastNameField = getShippingField('shipping_last_name');

  // 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');

  const hasValue = (value: unknown) => String(value ?? '').trim().length > 0;

  const isCheckoutReady = React.useMemo(() => {
    const billingFieldValues: Record<string, string> = {
      billing_first_name: billingData.firstName,
      billing_last_name: billingData.lastName,
      billing_email: billingData.email,
      billing_phone: billingData.phone,
      billing_address_1: billingData.address,
      billing_city: billingData.city,
      billing_state: billingData.state,
      billing_postcode: billingData.postcode,
      billing_country: billingData.country,
    };

    const renderedBillingFields = billingFields.filter(field => {
      const isAddressField = [
        'billing_address_1',
        'billing_address_2',
        'billing_city',
        'billing_state',
        'billing_postcode',
        'billing_country',
      ].includes(field.key);
      return !isAddressField || !isVirtualOnly;
    });

    const requiredBillingMissing = renderedBillingFields.some(field => {
      if (!field.required) return false;
      if (field.custom) return !hasValue(customFieldData[field.key]);
      return !hasValue(billingFieldValues[field.key]);
    });

    if (requiredBillingMissing) return false;

    if (shipToDifferentAddress && !isVirtualOnly) {
      const shippingFieldValues: Record<string, string> = {
        shipping_first_name: shippingData.firstName,
        shipping_last_name: shippingData.lastName,
        shipping_address_1: shippingData.address,
        shipping_city: shippingData.city,
        shipping_state: shippingData.state,
        shipping_postcode: shippingData.postcode,
        shipping_country: shippingData.country,
      };

      const requiredShippingMissing = shippingFields.some(field => {
        if (!field.required) return false;
        if (field.custom) return !hasValue(customFieldData[field.key]);
        return !hasValue(shippingFieldValues[field.key]);
      });

      if (requiredShippingMissing) return false;
    }

    if (!paymentMethod) return false;

    if (!isVirtualOnly && elements.shipping_options && shippingRates.length > 0 && !selectedShippingRate) {
      return false;
    }

    return true;
  }, [
    billingData,
    billingFields,
    customFieldData,
    elements.shipping_options,
    isVirtualOnly,
    paymentMethod,
    selectedShippingRate,
    shipToDifferentAddress,
    shippingData,
    shippingFields,
    shippingRates.length,
  ]);

  // 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 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: 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;

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

    return () => clearTimeout(timeoutId);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    billingData.country, billingData.state, billingData.city, billingData.postcode,
    shippingData.country, shippingData.state, shippingData.city, shippingData.postcode,
    shipToDifferentAddress,
    customFieldData,
    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();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [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, savedAddresses.length]);

  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 {
      const referralCode = (() => {
        try {
          const stored = localStorage.getItem('woonoow_ref')?.trim();
          if (stored) return stored;
        } catch {
          // Ignore storage access errors.
        }

        const match = document.cookie.match(/(?:^|;\s*)woonoow_ref=([^;]+)/);
        return match ? decodeURIComponent(match[1]).trim() : '';
      })();

      // 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,
        // CAPTCHA token for security validation
        captcha_token: captchaToken,
        referral_code: referralCode || undefined,
      };

      // 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!');

        // Build thank you page URL
        const thankYouUrl = `/order-received/${data.order_id}?key=${data.order_key}`;

        // If user was logged in during this request (guest auto-register), 
        // we need a full page reload to recognize the auth cookie
        if (data.user_logged_in) {
          // Get basePath from window
          const basePath = (window as any).woonoowCustomer?.basePath ?? '/store';
          
          // Ensure thankYouUrl starts with / if basePath doesn't end with /
          const sep = basePath.endsWith('/') || thankYouUrl.startsWith('/') ? '' : '/';
          const prefix = thankYouUrl.startsWith('/') && basePath.endsWith('/') ? basePath.slice(0, -1) : basePath;
          
          // Full page reload so browser recognizes the new auth cookie
          const path = thankYouUrl.startsWith('/') ? thankYouUrl.slice(1) : thankYouUrl;
          window.location.href = `${prefix}${sep}${path}`;
        } else {
          // Already logged in or no login happened - SPA navigate is fine
          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>
    );
  }

  // Step header helper
  const StepHeader = ({ step, title }: { step: number; title: string }) => {
    const done = step < activeStep;
    const active = step === activeStep;
    return (
      <button
        type="button"
        className={cn(
          'font-[inherit] w-full flex items-center gap-4 px-6 py-5 text-left transition-colors',
          active ? 'bg-white dark:bg-background' : 'bg-gray-50 dark:bg-card hover:bg-gray-100 dark:hover:bg-accent',
        )}
        onClick={() => step < activeStep && setActiveStep(step)}
      >
        <span className={cn(
          'w-8 h-8 rounded-full flex items-center justify-center text-sm font-bold shrink-0',
          done ? 'bg-green-500 text-white' : active ? 'bg-blue-600 text-white dark:bg-blue-500 dark:text-white' : 'bg-gray-200 text-gray-600 dark:bg-slate-700 dark:text-slate-100',
        )}>
          {done ? <Check className="w-4 h-4" /> : step}
        </span>
        <span className={cn('font-semibold text-base', !active && !done && 'text-gray-400')}>{title}</span>
        {done && <ChevronDown className="w-4 h-4 ml-auto text-gray-400 rotate-[-90deg]" />}
      </button>
    );
  };

  return (
    <Container>
      <SEOHead title="Checkout" description="Complete your purchase" />

      {security?.captcha_provider && security.captcha_provider !== 'none' && (
        <CaptchaWidget
          provider={security.captcha_provider}
          siteKey={security.captcha_provider === 'recaptcha' ? security.recaptcha_site_key : security.turnstile_site_key}
          onToken={setCaptchaToken}
          action="checkout"
        />
      )}

      <div className="py-8">
        <Button variant="ghost" onClick={() => navigate('/cart')} className="mb-6">
          <ArrowLeft className="mr-2 h-4 w-4" /> Back to Cart
        </Button>
        <h1 className="text-3xl font-bold mb-8">Checkout</h1>

        <form onSubmit={handlePlaceOrder}>
          <div className="lg:grid lg:grid-cols-3 lg:gap-8">
            {/* ── LEFT: Accordion Steps ── */}
            <div className="lg:col-span-2 space-y-4">

              {/* ── STEP 1: Information ── */}
              <div className="border rounded-xl overflow-hidden bg-white dark:bg-background">
                <StepHeader step={1} title="Contact & Billing" />
                {activeStep === 1 && (
                  <div className="px-6 pb-6 pt-2 space-y-4">
                    {/* Saved address picker */}
                    {!loadingAddresses && savedAddresses.length > 0 && savedAddresses.some(a => a.type === 'billing' || a.type === 'both') && (
                      <div>
                        <div className="flex items-center justify-between mb-3">
                          <span className="text-sm font-medium flex items-center gap-2"><MapPin className="w-4 h-4" />Saved Addresses</span>
                          <Button type="button" variant="outline" size="sm" onClick={() => setShowBillingModal(true)}>
                            <Edit2 className="w-3 h-3 mr-1" /> Change
                          </Button>
                        </div>
                        {selectedBillingAddressId && (() => {
                          const sel = savedAddresses.find(a => a.id === selectedBillingAddressId);
                          return sel ? (
                            <div className="bg-primary/5 border-2 border-primary rounded-lg p-4 text-sm">
                              <p className="font-semibold">{sel.label}{sel.is_default && <span className="ml-2 text-xs bg-green-100 text-green-700 px-1.5 rounded">Default</span>}</p>
                              <p>{sel.first_name} {sel.last_name}</p>
                              <p className="text-gray-600">{sel.address_1}, {sel.city}, {sel.state} {sel.postcode}</p>
                            </div>
                          ) : null;
                        })()}
                        <Button type="button" variant="ghost" size="sm" className="mt-2 text-primary" onClick={() => setShowBillingForm(true)}>
                          Use a different address
                        </Button>
                      </div>
                    )}

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

                    {(savedAddresses.length === 0 || !selectedBillingAddressId || showBillingForm) && (
                      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                        {billingFirstNameField && (
                          <div className={getFieldWrapperClass('billing_first_name', 'billing', !billingLastNameField)}>
                            <label className="block text-sm font-medium mb-1">{billingLastNameField ? (billingFirstNameField.label || 'First Name') : 'Name'}{billingFirstNameField.required && ' *'}</label>
                            <input type="text" required={billingFirstNameField.required} value={billingData.firstName} onChange={e => setBillingData({ ...billingData, firstName: e.target.value })} className="w-full border rounded-lg px-4 py-2" />
                          </div>
                        )}
                        {billingLastNameField && (
                          <div className={getFieldWrapperClass('billing_last_name', 'billing')}>
                            <label className="block text-sm font-medium mb-1">{billingLastNameField.label || 'Last Name'}{billingLastNameField.required && ' *'}</label>
                            <input type="text" required={billingLastNameField.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-1">{getBillingField('billing_email')?.label || 'Email'}{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-1">{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>
                        )}
                        {!isVirtualOnly && (
                          <>
                            {getBillingField('billing_address_1') && (
                              <div className="md:col-span-2">
                                <label className="block text-sm font-medium mb-1">{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>
                            )}
                            {getBillingField('billing_city') && (
                              <div>
                                <label className="block text-sm font-medium mb-1">{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>
                            )}
                            {getBillingField('billing_country') && (
                              <div>
                                <label className="block text-sm font-medium mb-1">{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>
                            )}
                            {getBillingField('billing_state') && (
                              <div>
                                <label className="block text-sm font-medium mb-1">{getBillingField('billing_state')?.label || 'State'}{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 })} className="w-full border rounded-lg px-4 py-2" />}
                              </div>
                            )}
                            {getBillingField('billing_postcode') && (
                              <div>
                                <label className="block text-sm font-medium mb-1">{getBillingField('billing_postcode')?.label || 'Postcode'}{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>
                            )}
                            {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 className="pt-2">
                      <Button type="button" onClick={() => setActiveStep(2)} className="w-full">
                        Continue to {isVirtualOnly ? 'Payment' : 'Shipping'} →
                      </Button>
                    </div>
                  </div>
                )}
              </div>

              {/* ── STEP 2: Shipping (physical only) ── */}
              {!isVirtualOnly && (
                <div className="border rounded-xl overflow-hidden bg-white dark:bg-background">
                  <StepHeader step={2} title="Shipping" />
                  {activeStep === 2 && (
                    <div className="px-6 pb-6 pt-2 space-y-4">
                      {/* Ship to different address toggle */}
                      <label className="flex items-center gap-3 cursor-pointer">
                        <input type="checkbox" checked={shipToDifferentAddress} onChange={e => setShipToDifferentAddress(e.target.checked)} className="w-4 h-4" />
                        <span className="text-sm font-medium">Ship to a different address?</span>
                      </label>

                      {shipToDifferentAddress && (
                        <>
                          {!loadingAddresses && savedAddresses.length > 0 && savedAddresses.some(a => a.type === 'shipping' || a.type === 'both') && (
                            <div>
                              <div className="flex items-center justify-between mb-2">
                                <span className="text-sm font-medium">Shipping Address</span>
                                <Button type="button" variant="outline" size="sm" onClick={() => setShowShippingModal(true)}><Edit2 className="w-3 h-3 mr-1" />Change</Button>
                              </div>
                              {selectedShippingAddressId && (() => {
                                const sel = savedAddresses.find(a => a.id === selectedShippingAddressId);
                                return sel ? (
                                  <div className="bg-primary/5 border-2 border-primary rounded-lg p-4 text-sm">
                                    <p className="font-semibold">{sel.label}</p>
                                    <p>{sel.first_name} {sel.last_name}</p>
                                    <p className="text-gray-600">{sel.address_1}, {sel.city} {sel.postcode}</p>
                                  </div>
                                ) : null;
                              })()}
                              <Button type="button" variant="ghost" size="sm" className="mt-2 text-primary" onClick={() => setShowShippingForm(true)}>Use a different address</Button>
                            </div>
                          )}
                          <AddressSelector isOpen={showShippingModal} onClose={() => setShowShippingModal(false)} addresses={savedAddresses} selectedAddressId={selectedShippingAddressId} onSelectAddress={handleSelectShippingAddress} type="shipping" />

                          {(!selectedShippingAddressId || showShippingForm) && (
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                              {shippingFirstNameField && <div className={getFieldWrapperClass('shipping_first_name', 'shipping', !shippingLastNameField)}><label className="block text-sm font-medium mb-1">{shippingLastNameField ? (shippingFirstNameField.label || 'First Name') : 'Name'}</label><input type="text" value={shippingData.firstName} onChange={e => setShippingData({ ...shippingData, firstName: e.target.value })} className="w-full border rounded-lg px-4 py-2" /></div>}
                              {shippingLastNameField && <div className={getFieldWrapperClass('shipping_last_name', 'shipping')}><label className="block text-sm font-medium mb-1">{shippingLastNameField.label || 'Last Name'}</label><input type="text" 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="md:col-span-2"><label className="block text-sm font-medium mb-1">Address</label><input type="text" value={shippingData.address} onChange={e => setShippingData({ ...shippingData, address: e.target.value })} className="w-full border rounded-lg px-4 py-2" /></div>}
                              {getShippingField('shipping_city') && <div><label className="block text-sm font-medium mb-1">City</label><input type="text" value={shippingData.city} onChange={e => setShippingData({ ...shippingData, city: e.target.value })} className="w-full border rounded-lg px-4 py-2" /></div>}
                              {getShippingField('shipping_country') && <div><label className="block text-sm font-medium mb-1">Country</label><SearchableSelect options={countryOptions} value={shippingData.country} onChange={v => setShippingData({ ...shippingData, country: v })} placeholder="Select country" disabled={countries.length === 1} /></div>}
                              {getShippingField('shipping_state') && <div><label className="block text-sm font-medium mb-1">State</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 })} className="w-full border rounded-lg px-4 py-2" />}</div>}
                              {getShippingField('shipping_postcode') && <div><label className="block text-sm font-medium mb-1">Postcode</label><input type="text" value={shippingData.postcode} onChange={e => setShippingData({ ...shippingData, postcode: e.target.value })} className="w-full border rounded-lg px-4 py-2" /></div>}
                              {shippingCustomFields.map(field => <DynamicCheckoutField key={field.key} field={field} value={customFieldData[field.key] || ''} onChange={v => handleCustomFieldChange(field.key, v)} countryOptions={countryOptions} stateOptions={shippingStateOptions} />)}
                            </div>
                          )}
                        </>
                      )}

                      {/* Shipping rates */}
                      {elements.shipping_options && (
                        <div>
                          <h3 className="font-medium mb-2 text-sm">Shipping Method</h3>
                          {isLoadingRates ? (
                            <div className="flex items-center gap-2 text-sm text-gray-500"><Loader2 className="h-4 w-4 animate-spin" />Calculating...</div>
                          ) : shippingRates.length === 0 ? (
                            <p className="text-sm text-gray-500">{billingData.country ? 'No methods available for your location' : 'Enter address first'}</p>
                          ) : (
                            <div className="space-y-2">
                              {shippingRates.map(rate => (
                                <label key={rate.id} className={cn('flex items-center justify-between p-3 border rounded-lg cursor-pointer hover:bg-gray-50 dark:hover:bg-accent', 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>
                      )}

                      {elements.order_notes && (
                        <div>
                          <label className="block text-sm font-medium mb-1">Order Notes (Optional)</label>
                          <textarea value={orderNotes} onChange={e => setOrderNotes(e.target.value)} placeholder="Special notes for delivery" className="w-full border rounded-lg px-4 py-2 h-24" />
                        </div>
                      )}

                      <Button type="button" onClick={() => setActiveStep(3)} className="w-full">Continue to Payment →</Button>
                    </div>
                  )}
                </div>
              )}

              {/* ── STEP 3: Payment ── */}
              <div className="border rounded-xl overflow-hidden bg-white dark:bg-background">
                <StepHeader step={isVirtualOnly ? 2 : 3} title="Payment" />
                {activeStep === (isVirtualOnly ? 2 : 3) && (
                  <div className="px-6 pb-6 pt-2 space-y-4">
                    <div className="space-y-2">
                      {!isVirtualOnly && (
                        <label className={cn('flex items-center gap-3 p-3 border rounded-lg cursor-pointer hover:bg-gray-50 dark:hover:bg-accent', paymentMethod === 'cod' && 'border-primary bg-primary/5')}>
                          <input type="radio" name="payment" value="cod" checked={paymentMethod === 'cod'} onChange={e => setPaymentMethod(e.target.value)} className="w-4 h-4" />
                          <span className="font-medium text-sm">Cash on Delivery</span>
                        </label>
                      )}
                      <label className={cn('flex items-center gap-3 p-3 border rounded-lg cursor-pointer hover:bg-gray-50 dark:hover:bg-accent', paymentMethod === 'bacs' && 'border-primary bg-primary/5')}>
                        <input type="radio" name="payment" value="bacs" checked={paymentMethod === 'bacs'} onChange={e => setPaymentMethod(e.target.value)} className="w-4 h-4" />
                        <span className="font-medium text-sm">Bank Transfer</span>
                      </label>
                    </div>

                    {elements.payment_icons && (
                      <div className="flex items-center gap-2 pt-2 border-t">
                        <span className="text-xs text-gray-500">We accept:</span>
                        {['VISA', 'MC', 'AMEX'].map(c => <div key={c} className="w-10 h-6 bg-gray-100 rounded flex items-center justify-center text-xs font-bold">{c}</div>)}
                      </div>
                    )}
                  </div>
                )}
              </div>
            </div>

            {/* ── RIGHT: Order Summary (sticky) ── */}
            <div className="mt-6 lg:mt-0">
              <div className="border rounded-xl p-6 sticky top-4 space-y-4 bg-white dark:bg-background">
                <h2 className="text-xl font-bold">Your Order</h2>

                {/* Coupon */}
                {elements.coupon_field && (
                  <div className="pb-4 border-b space-y-2">
                    <div className="flex gap-2">
                      <input type="text" placeholder="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-lg text-sm" 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>
                    {appliedCoupons.map(c => (
                      <div key={c.code} className="flex items-center justify-between p-2 bg-green-50 border border-green-200 rounded-md text-sm">
                        <div className="flex items-center gap-2"><Tag className="h-4 w-4 text-green-600" /><span className="font-medium text-green-800">{c.code}</span><span className="text-green-600">-{formatPrice(c.discount)}</span></div>
                        <button type="button" onClick={() => handleRemoveCoupon(c.code)} disabled={isApplyingCoupon} className="text-green-600 hover:text-green-800 p-1"><X className="h-4 w-4" /></button>
                      </div>
                    ))}
                  </div>
                )}

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

                {/* Totals */}
                <div className="space-y-1.5 text-sm">
                  <div className="flex justify-between"><span>Subtotal</span><span>{formatPrice(subtotal)}</span></div>
                  {discountTotal > 0 && <div className="flex justify-between text-green-600"><span>Discount</span><span>-{formatPrice(discountTotal)}</span></div>}
                  {!isVirtualOnly && <div className="flex justify-between"><span>Shipping</span><span>{shippingCost === 0 ? 'Free' : formatPrice(shippingCost)}</span></div>}
                  {tax > 0 && <div className="flex justify-between"><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>

                <div className="pt-2 border-t">
                  <Button
                    type="submit"
                    size="lg"
                    className="w-full"
                    disabled={isProcessing || !isCheckoutReady}
                  >
                    {isProcessing ? (
                      <>
                        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                        Processing...
                      </>
                    ) : (
                      'Place Order'
                    )}
                  </Button>
                  {!isCheckoutReady && (
                    <p className="mt-2 text-center text-xs text-muted-foreground">
                      Complete the required checkout details to place your order.
                    </p>
                  )}
                </div>
              </div>
            </div>
          </div>
        </form>
      </div>
    </Container>
  );
}
