import React, { useEffect, useMemo, useState } from 'react';
import {
  IonButton,
  IonButtons,
  IonContent,
  IonHeader,
  IonIcon,
  IonItem,
  IonLabel,
  IonList,
  IonLoading,
  IonPage,
  IonText,
  IonTitle,
  IonToolbar,
  useIonViewWillEnter,
} from '@ionic/react';
import {
  addOutline,
  bagHandleOutline,
  removeOutline,
  trashOutline,
} from 'ionicons/icons';
import { useHistory } from 'react-router-dom';
import { supabase } from '../supabase';
import type { TablesInsert } from '../database.types';
import { CartItem, LAST_ORDER_STORAGE_KEY, readCart, writeCart } from './Home';
import {
  setStatusBarBackground,
  setStatusBarStyle,
  Style,
} from '../utils/statusBar';

const Cart: React.FC = () => {
  const history = useHistory();
  const [cart, setCart] = useState<CartItem[]>([]);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');

  useIonViewWillEnter(() => {
    setStatusBarStyle(Style.Dark);
    setStatusBarBackground('#ffffff');
  });

  useEffect(() => {
    setCart(readCart());
  }, []);

  useEffect(() => {
    const syncCartFromStorage = () => setCart(readCart());
    window.addEventListener('storage', syncCartFromStorage);
    window.addEventListener(
      'cart:updated',
      syncCartFromStorage as EventListener
    );
    return () => {
      window.removeEventListener('storage', syncCartFromStorage);
      window.removeEventListener(
        'cart:updated',
        syncCartFromStorage as EventListener
      );
    };
  }, []);

  const syncCart = (nextCart: CartItem[]) => {
    setCart(nextCart);
    writeCart(nextCart);
  };

  const showError = (message: string) => {
    setErrorMessage(message);
    window.setTimeout(() => setErrorMessage(''), 4000);
  };

  const itemCount = useMemo(
    () => cart.reduce((sum, item) => sum + item.quantity, 0),
    [cart]
  );

  const subtotal = useMemo(
    () => cart.reduce((sum, item) => sum + item.price * item.quantity, 0),
    [cart]
  );

  const deliveryFee = cart.length > 0 ? 2.99 : 0;
  const total = subtotal + deliveryFee;

  const updateQuantity = (id: string, delta: number) => {
    const nextCart = cart
      .map((item) =>
        item.id === id ? { ...item, quantity: item.quantity + delta } : item
      )
      .filter((item) => item.quantity > 0);
    syncCart(nextCart);
  };

  const removeItem = (id: string) => {
    syncCart(cart.filter((item) => item.id !== id));
  };

  const placeOrder = async () => {
    if (cart.length === 0 || isSubmitting) {
      return;
    }

    setIsSubmitting(true);

    const orderNumber = `QC-${Date.now().toString().slice(-6)}`;

    const orderPayload: TablesInsert<'orders'> = {
      order_number: orderNumber,
      subtotal,
      delivery_fee: deliveryFee,
      total,
      item_count: itemCount,
      status: 'confirmed',
    };

    const { data: order, error: orderError } = await supabase
      .from('orders')
      .insert(orderPayload)
      .select()
      .single();

    if (orderError || !order) {
      setIsSubmitting(false);
      showError('We could not place your order. Please try again.');
      return;
    }

    const itemsPayload: TablesInsert<'order_items'>[] = cart.map((item) => ({
      order_id: order.id,
      product_id: item.id,
      product_name: item.name,
      unit_price: item.price,
      quantity: item.quantity,
    }));

    const { error: itemsError } = await supabase
      .from('order_items')
      .insert(itemsPayload);

    if (itemsError) {
      await supabase.from('orders').delete().eq('id', order.id);
      setIsSubmitting(false);
      showError('We could not save your order items. Please try again.');
      return;
    }

    localStorage.setItem(
      LAST_ORDER_STORAGE_KEY,
      JSON.stringify({
        id: order.id,
        orderNumber: order.order_number,
        total: Number(order.total),
        itemCount: order.item_count,
        status: order.status,
      })
    );

    writeCart([]);
    setCart([]);
    setIsSubmitting(false);
    history.replace('/order-confirmation');
  };

  return (
    <IonPage>
      <IonHeader className="ion-no-border">
        <IonToolbar>
          <IonButtons slot="start">
            <IonButton fill="clear" onClick={() => history.replace('/home')}>
              Back
            </IonButton>
          </IonButtons>
          <IonTitle>Your Cart</IonTitle>
        </IonToolbar>
      </IonHeader>

      <IonContent className="ion-padding">
        <IonLoading isOpen={isSubmitting} message="Placing your order..." />
        {errorMessage && (
          <IonText color="danger">
            <p>{errorMessage}</p>
          </IonText>
        )}
        {cart.length === 0 ? (
          <div className="empty-state cart-empty">
            <IonIcon icon={bagHandleOutline} />
            <h3>Your cart is empty</h3>
            <p className="muted-text">
              Add your first product to place an order.
            </p>
            <IonButton onClick={() => history.push('/home')}>
              Browse products
            </IonButton>
          </div>
        ) : (
          <>
            <div className="cart-overview-card">
              <div>
                <p className="overview-label">Items in cart</p>
                <h2>
                  {itemCount} item{itemCount === 1 ? '' : 's'}
                </h2>
              </div>
              <IonText color="medium">
                <p>Review your selections before placing the order.</p>
              </IonText>
            </div>

            <IonList lines="none" className="cart-list">
              {cart.map((item) => (
                <IonItem key={item.id} className="cart-item">
                  <IonLabel>
                    <h2>{item.name}</h2>
                    <p>${item.price.toFixed(2)} each</p>
                    <strong>${(item.price * item.quantity).toFixed(2)}</strong>
                  </IonLabel>
                  <div className="cart-actions">
                    <IonButton
                      fill="clear"
                      onClick={() => updateQuantity(item.id, -1)}
                    >
                      <IonIcon icon={removeOutline} />
                    </IonButton>
                    <span>{item.quantity}</span>
                    <IonButton
                      fill="clear"
                      onClick={() => updateQuantity(item.id, 1)}
                    >
                      <IonIcon icon={addOutline} />
                    </IonButton>
                    <IonButton
                      fill="clear"
                      color="danger"
                      onClick={() => removeItem(item.id)}
                    >
                      <IonIcon icon={trashOutline} />
                    </IonButton>
                  </div>
                </IonItem>
              ))}
            </IonList>

            <div className="summary-card">
              <div className="summary-row">
                <IonText color="medium">Items</IonText>
                <strong>{itemCount}</strong>
              </div>
              <div className="summary-row">
                <IonText color="medium">Subtotal</IonText>
                <strong>${subtotal.toFixed(2)}</strong>
              </div>
              <div className="summary-row">
                <IonText color="medium">Delivery</IonText>
                <strong>${deliveryFee.toFixed(2)}</strong>
              </div>
              <div className="summary-row total-row">
                <span>Total</span>
                <strong>${total.toFixed(2)}</strong>
              </div>
              <IonButton
                expand="block"
                onClick={placeOrder}
                disabled={isSubmitting}
              >
                Place order
              </IonButton>
            </div>
          </>
        )}
      </IonContent>
    </IonPage>
  );
};

export default Cart;
