// UI components for the ecommerce sandbox. Transformed in-browser by Babel Standalone.
// Each component is attached to `window` so App.jsx (loaded after this file) can use it
// without a module bundler.
(function () {
  var useState = React.useState;
  var useEffect = React.useEffect;

  function formatPrice(price) {
    return '$' + price.toFixed(2);
  }

  function Header(props) {
    return (
      <header className="site-header">
        <div className="brand" onClick={function () { props.navigate('#/'); }}>
          Analytics Sandbox 1
        </div>
        <nav className="nav">
          <button className="link-button" onClick={function () { props.navigate('#/'); }}>Shop</button>
          <button className="link-button cart-link" onClick={function () { props.navigate('#/cart'); }}>
            Cart
            {props.cartCount > 0 && <span className="cart-badge">{props.cartCount}</span>}
          </button>
        </nav>
      </header>
    );
  }

  function ProductCard(props) {
    var product = props.product;
    return (
      <div className="product-card" onClick={function () { props.onSelect(product); }}>
        <div className="product-emoji">{product.emoji}</div>
        <div className="product-name">{product.name}</div>
        <div className="product-category">{product.category}</div>
        <div className="product-price">{formatPrice(product.price)}</div>
        <button className="btn btn-secondary">View details</button>
      </div>
    );
  }

  function ProductList(props) {
    useEffect(function () {
      window.GTMEvents.viewItemList(props.products, 'home_grid', 'Home page product list');
    }, []);

    function handleSelect(product) {
      window.GTMEvents.selectItem(product, 'home_grid', 'Home page product list');
      props.navigate('#/product/' + product.id);
    }

    return (
      <div>
        <h1>Shop all products</h1>
        <div className="product-grid">
          {props.products.map(function (product) {
            return <ProductCard key={product.id} product={product} onSelect={handleSelect} />;
          })}
        </div>
      </div>
    );
  }

  function ProductDetail(props) {
    var product = props.products.filter(function (p) { return p.id === props.productId; })[0];
    var qtyState = useState(1);
    var qty = qtyState[0];
    var setQty = qtyState[1];
    var addedState = useState(false);
    var added = addedState[0];
    var setAdded = addedState[1];

    useEffect(function () {
      if (product) {
        window.GTMEvents.viewItem(product);
      }
      setAdded(false);
    }, [props.productId]);

    if (!product) {
      return (
        <div>
          <p>Product not found.</p>
          <button className="btn" onClick={function () { props.navigate('#/'); }}>Back to shop</button>
        </div>
      );
    }

    function handleAddToCart() {
      window.GTMEvents.addToCart(product, qty);
      props.onAddToCart(product, qty);
      setAdded(true);
    }

    return (
      <div className="product-detail">
        <button className="link-button back-link" onClick={function () { props.navigate('#/'); }}>&larr; Back to shop</button>
        <div className="product-detail-main">
          <div className="product-emoji product-emoji-large">{product.emoji}</div>
          <div className="product-detail-info">
            <h1>{product.name}</h1>
            <p className="product-category">{product.category} &middot; {product.variant}</p>
            <p className="product-price product-price-large">{formatPrice(product.price)}</p>
            <p>{product.description}</p>
            <div className="qty-row">
              <label htmlFor="qty">Qty</label>
              <input
                id="qty"
                type="number"
                min="1"
                value={qty}
                onChange={function (e) {
                  var val = parseInt(e.target.value, 10);
                  setQty(val > 0 ? val : 1);
                }}
              />
            </div>
            <button className="btn btn-primary" onClick={handleAddToCart}>Add to cart</button>
            {added && (
              <p className="added-msg">
                Added to cart. <button className="link-button" onClick={function () { props.navigate('#/cart'); }}>View cart</button>
              </p>
            )}
          </div>
        </div>
      </div>
    );
  }

  function Cart(props) {
    useEffect(function () {
      window.GTMEvents.viewCart(props.cart);
    }, []);

    var total = props.cart.reduce(function (sum, entry) { return sum + entry.product.price * entry.quantity; }, 0);

    if (props.cart.length === 0) {
      return (
        <div>
          <h1>Your cart</h1>
          <p>Your cart is empty.</p>
          <button className="btn btn-primary" onClick={function () { props.navigate('#/'); }}>Continue shopping</button>
        </div>
      );
    }

    return (
      <div>
        <h1>Your cart</h1>
        <div className="cart-list">
          {props.cart.map(function (entry) {
            return (
              <div className="cart-row" key={entry.product.id}>
                <div className="cart-emoji">{entry.product.emoji}</div>
                <div className="cart-info">
                  <div className="product-name">{entry.product.name}</div>
                  <div className="product-category">{entry.product.variant}</div>
                </div>
                <div className="qty-controls">
                  <button className="btn btn-small" onClick={function () { props.onDecrement(entry.product); }}>-</button>
                  <span>{entry.quantity}</span>
                  <button className="btn btn-small" onClick={function () { props.onIncrement(entry.product); }}>+</button>
                </div>
                <div className="cart-line-total">{formatPrice(entry.product.price * entry.quantity)}</div>
                <button className="link-button remove-link" onClick={function () { props.onRemove(entry.product); }}>Remove</button>
              </div>
            );
          })}
        </div>
        <div className="cart-summary">
          <span>Subtotal</span>
          <span className="cart-total">{formatPrice(total)}</span>
        </div>
        <button className="btn btn-primary" onClick={function () { props.onBeginCheckout(); }}>Proceed to checkout</button>
      </div>
    );
  }

  var SHIPPING_OPTIONS = [
    { id: 'standard', label: 'Standard (3-5 days)', cost: 5.99 },
    { id: 'express', label: 'Express (1-2 days)', cost: 14.99 }
  ];

  var PAYMENT_OPTIONS = [
    { id: 'credit_card', label: 'Credit card' },
    { id: 'paypal', label: 'PayPal' }
  ];

  function Checkout(props) {
    var stepState = useState('shipping');
    var step = stepState[0];
    var setStep = stepState[1];
    var shippingState = useState(SHIPPING_OPTIONS[0].id);
    var shippingTier = shippingState[0];
    var setShippingTier = shippingState[1];
    var paymentState = useState(PAYMENT_OPTIONS[0].id);
    var paymentType = paymentState[0];
    var setPaymentType = paymentState[1];

    var subtotal = props.cart.reduce(function (sum, entry) { return sum + entry.product.price * entry.quantity; }, 0);
    var shippingCost = (SHIPPING_OPTIONS.filter(function (o) { return o.id === shippingTier; })[0] || SHIPPING_OPTIONS[0]).cost;
    var tax = subtotal * 0.08;
    var orderTotal = subtotal + shippingCost + tax;

    if (props.cart.length === 0 && step !== 'placed') {
      return (
        <div>
          <h1>Checkout</h1>
          <p>Your cart is empty.</p>
          <button className="btn btn-primary" onClick={function () { props.navigate('#/'); }}>Continue shopping</button>
        </div>
      );
    }

    function submitShipping(e) {
      e.preventDefault();
      props.onAddShippingInfo(shippingTier);
      setStep('payment');
    }

    function submitPayment(e) {
      e.preventDefault();
      props.onAddPaymentInfo(paymentType);
      setStep('review');
    }

    function placeOrder() {
      props.onPlaceOrder(shippingCost, tax);
    }

    return (
      <div className="checkout">
        <h1>Checkout</h1>
        <ol className="checkout-steps">
          <li className={step === 'shipping' ? 'active' : (step === 'payment' || step === 'review') ? 'done' : ''}>1. Shipping</li>
          <li className={step === 'payment' ? 'active' : step === 'review' ? 'done' : ''}>2. Payment</li>
          <li className={step === 'review' ? 'active' : ''}>3. Review &amp; place order</li>
        </ol>

        {step === 'shipping' && (
          <form onSubmit={submitShipping} className="checkout-form">
            <label>Full name<input required type="text" defaultValue="Jane Doe" /></label>
            <label>Address<input required type="text" defaultValue="123 Main St" /></label>
            <fieldset>
              <legend>Shipping method</legend>
              {SHIPPING_OPTIONS.map(function (opt) {
                return (
                  <label className="radio-row" key={opt.id}>
                    <input
                      type="radio"
                      name="shipping"
                      checked={shippingTier === opt.id}
                      onChange={function () { setShippingTier(opt.id); }}
                    />
                    {opt.label} - {formatPrice(opt.cost)}
                  </label>
                );
              })}
            </fieldset>
            <button className="btn btn-primary" type="submit">Continue to payment</button>
          </form>
        )}

        {step === 'payment' && (
          <form onSubmit={submitPayment} className="checkout-form">
            <fieldset>
              <legend>Payment method</legend>
              {PAYMENT_OPTIONS.map(function (opt) {
                return (
                  <label className="radio-row" key={opt.id}>
                    <input
                      type="radio"
                      name="payment"
                      checked={paymentType === opt.id}
                      onChange={function () { setPaymentType(opt.id); }}
                    />
                    {opt.label}
                  </label>
                );
              })}
            </fieldset>
            {paymentType === 'credit_card' && (
              <label>Card number<input type="text" defaultValue="4242 4242 4242 4242" /></label>
            )}
            <button className="btn btn-primary" type="submit">Review order</button>
          </form>
        )}

        {step === 'review' && (
          <div className="review">
            <h2>Order summary</h2>
            <div className="cart-list">
              {props.cart.map(function (entry) {
                return (
                  <div className="cart-row" key={entry.product.id}>
                    <div className="cart-emoji">{entry.product.emoji}</div>
                    <div className="cart-info">
                      <div className="product-name">{entry.product.name}</div>
                      <div className="product-category">Qty {entry.quantity}</div>
                    </div>
                    <div className="cart-line-total">{formatPrice(entry.product.price * entry.quantity)}</div>
                  </div>
                );
              })}
            </div>
            <div className="cart-summary"><span>Subtotal</span><span>{formatPrice(subtotal)}</span></div>
            <div className="cart-summary"><span>Shipping ({shippingTier})</span><span>{formatPrice(shippingCost)}</span></div>
            <div className="cart-summary"><span>Tax</span><span>{formatPrice(tax)}</span></div>
            <div className="cart-summary"><span>Total</span><span className="cart-total">{formatPrice(orderTotal)}</span></div>
            <button className="btn btn-primary" onClick={placeOrder}>Place order</button>
          </div>
        )}
      </div>
    );
  }

  function Confirmation(props) {
    if (!props.order) {
      return (
        <div>
          <h1>No recent order</h1>
          <button className="btn btn-primary" onClick={function () { props.navigate('#/'); }}>Back to shop</button>
        </div>
      );
    }
    var order = props.order;
    return (
      <div>
        <h1>Thank you for your order!</h1>
        <p>Order <strong>{order.transactionId}</strong> has been placed.</p>
        <div className="cart-list">
          {order.cart.map(function (entry) {
            return (
              <div className="cart-row" key={entry.product.id}>
                <div className="cart-emoji">{entry.product.emoji}</div>
                <div className="cart-info">
                  <div className="product-name">{entry.product.name}</div>
                  <div className="product-category">Qty {entry.quantity}</div>
                </div>
                <div className="cart-line-total">{formatPrice(entry.product.price * entry.quantity)}</div>
              </div>
            );
          })}
        </div>
        <div className="cart-summary"><span>Total charged</span><span className="cart-total">{formatPrice(order.total)}</span></div>
        <button className="btn btn-primary" onClick={function () { props.navigate('#/'); }}>Continue shopping</button>
      </div>
    );
  }

  function DataLayerPanel() {
    var openState = useState(true);
    var open = openState[0];
    var setOpen = openState[1];
    var logState = useState([]);
    var log = logState[0];
    var setLog = logState[1];

    // Runs after other components' mount effects (e.g. view_item_list on the
    // product list), so reading window.__dataLayerLog here also picks up
    // events fired earlier in the same commit.
    useEffect(function () {
      setLog(window.__dataLayerLog.slice());
      window.__onDataLayerPush = function (entry) {
        if (!entry || !entry.payload || !entry.payload.event) {
          return;
        }
        setLog(function (prev) { return prev.concat([entry]).slice(-25); });
      };
      return function () { window.__onDataLayerPush = null; };
    }, []);

    return (
      <div className={'datalayer-panel' + (open ? ' open' : '')}>
        <div className="datalayer-header" onClick={function () { setOpen(!open); }}>
          <span>Data Layer Log ({log.length})</span>
          <span>{open ? '\u25BC' : '\u25B2'}</span>
        </div>
        {open && (
          <div className="datalayer-body">
            <button className="link-button" onClick={function (e) { e.stopPropagation(); setLog([]); }}>Clear log</button>
            {log.length === 0 && <p className="datalayer-empty">No events yet. Interact with the store to see GA4 ecommerce events pushed to window.dataLayer.</p>}
            {log.slice().reverse().map(function (entry, i) {
              return (
                <div className="datalayer-entry" key={i}>
                  <div className="datalayer-entry-title">{entry.time} &mdash; <strong>{entry.payload.event}</strong></div>
                  <pre>{JSON.stringify(entry.payload, null, 2)}</pre>
                </div>
              );
            })}
          </div>
        )}
      </div>
    );
  }

  window.Header = Header;
  window.ProductList = ProductList;
  window.ProductDetail = ProductDetail;
  window.Cart = Cart;
  window.Checkout = Checkout;
  window.Confirmation = Confirmation;
  window.DataLayerPanel = DataLayerPanel;
})();
