"use client";

import Image from "next/image";
import Link from "next/link";
import DataLink from "@/components/common/DataLink";
import {
  startTransition,
  useCallback,
  useEffect,
  type MouseEvent,
  useMemo,
  useState,
} from "react";
import { toast } from "sonner";
import {
  cartAssets,
  cartCouponForm,
  cartLocalStorageKey,
  cartShippingAmount,
  cartTotalsCopy,
  parseStoredCartLines,
  type CartLine,
  type CartProduct,
  initialCartLines,
} from "@/data/cart";
import { getCartProduct } from "@/lib/cart-products";

const iconImgStyle = { width: "auto", height: "auto" } as const;
const removeBtnStyle = {
  background: "none",
  border: "none",
  padding: 0,
  cursor: "pointer",
  display: "inline-flex",
} as const;
const STAR_SIZE = 16;
const QTY_MIN = 1;
const QTY_MAX = 99;

function formatMoneyWhole(amount: number) {
  return new Intl.NumberFormat("en-US", {
    style: "currency",
    currency: "USD",
    minimumFractionDigits: 0,
    maximumFractionDigits: 0,
  }).format(amount);
}

function formatMoneyTable(amount: number) {
  return new Intl.NumberFormat("en-US", {
    style: "currency",
    currency: "USD",
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  }).format(amount);
}

function productById(id: string): CartProduct | undefined {
  return getCartProduct(id);
}

function TitleLink({ product }: { product: CartProduct }) {
  const inner = (
    <DataLink href={`/product-details/${product.id}`} title="">
      {product.title}
    </DataLink>
  );
  if (product.titleHeading === "h2") {
    return <h2 className="title">{inner}</h2>;
  }
  return <h3 className="title">{inner}</h3>;
}

function persistCartLines(next: CartLine[]) {
  try {
    if (typeof window === "undefined") return;
    localStorage.setItem(cartLocalStorageKey, JSON.stringify(next));
  } catch {
    /* private mode / quota */
  }
}

export default function Cart() {
  const [lines, setLines] = useState<CartLine[]>(() =>
    initialCartLines.map((l) => ({ ...l })),
  );

  useEffect(() => {
    try {
      const raw = localStorage.getItem(cartLocalStorageKey);
      if (raw === null) return;
      const restored = parseStoredCartLines(JSON.parse(raw) as unknown);
      if (restored !== null) {
        startTransition(() => {
          setLines(restored);
        });
      }
    } catch {
      /* invalid JSON */
    }
  }, []);

  const commitLines = useCallback(
    (updater: (prev: CartLine[]) => CartLine[]) => {
      setLines((prev) => {
        const next = updater(prev);
        persistCartLines(next);
        return next;
      });
    },
    [],
  );

  const setQuantity = useCallback(
    (productId: string, quantity: number) => {
      const next = Math.min(QTY_MAX, Math.max(QTY_MIN, quantity));
      commitLines((prev) =>
        prev.map((line) =>
          line.productId === productId ? { ...line, quantity: next } : line,
        ),
      );
    },
    [commitLines],
  );

  const increment = useCallback(
    (productId: string) => {
      commitLines((prev) =>
        prev.map((line) =>
          line.productId === productId
            ? {
                ...line,
                quantity: Math.min(QTY_MAX, line.quantity + 1),
              }
            : line,
        ),
      );
    },
    [commitLines],
  );

  const decrement = useCallback(
    (productId: string) => {
      commitLines((prev) =>
        prev.map((line) =>
          line.productId === productId
            ? {
                ...line,
                quantity: Math.max(QTY_MIN, line.quantity - 1),
              }
            : line,
        ),
      );
    },
    [commitLines],
  );

  const removeLine = useCallback(
    (productId: string) => {
      commitLines((prev) =>
        prev.filter((line) => line.productId !== productId),
      );
    },
    [commitLines],
  );

  const { subtotal, shipping, total } = useMemo(() => {
    let sub = 0;
    for (const line of lines) {
      const p = productById(line.productId);
      if (p) sub += p.unitPrice * line.quantity;
    }
    const ship = lines.length > 0 ? cartShippingAmount : 0;
    return { subtotal: sub, shipping: ship, total: sub + ship };
  }, [lines]);

  const onUpdateCartClick = useCallback(
    (e: MouseEvent<HTMLAnchorElement>) => {
      e.preventDefault();
      persistCartLines(lines);
      toast.success("Cart updated successfully", {
        description: "Your quantities and totals have been refreshed.",
      });
    },
    [lines],
  );

  return (
    <>
      <div
        className="cart-table"
        data-aos="zoom-in"
        data-aos-duration={900}
        data-aos-delay={300}
      >
        <table>
          <thead>
            <tr>
              <th>Product</th>
              <th>Price</th>
              <th>Quantity</th>
              <th>Subtotal</th>
              <th>Remove</th>
            </tr>
          </thead>
          <tbody>
            {lines.length === 0 ? (
              <tr>
                <td colSpan={5}>Your cart is empty.</td>
              </tr>
            ) : (
              lines.map((line) => {
                const product = productById(line.productId);
                if (!product) return null;
                const lineSubtotal = product.unitPrice * line.quantity;
                const removeAlt = `Remove ${product.title} from cart`;

                return (
                  <tr key={line.productId}>
                    <td>
                      <div className="shop-cart-product">
                        <div className="shop-product-cart-img">
                          <Link href={`/product-details/${product.id}`}>
                            <Image
                              src={product.imageSrc}
                              alt={product.imageAlt}
                              width={product.imageWidth}
                              height={product.imageHeight}
                            />
                          </Link>
                        </div>
                        <div className="shop-product-cart-info">
                          <TitleLink product={product} />
                          <ul className="rating-area">
                            {Array.from({ length: product.rating }, (_, i) => (
                              <li key={i}>
                                <Image
                                  src={cartAssets.ratingIcon}
                                  alt={cartAssets.ratingAlt}
                                  width={STAR_SIZE}
                                  height={STAR_SIZE}
                                />
                              </li>
                            ))}
                            <li>
                              <span>{product.reviewCountLabel}</span>
                            </li>
                          </ul>
                        </div>
                      </div>
                    </td>
                    <td>
                      <span className="price">
                        {formatMoneyWhole(product.unitPrice)}
                      </span>
                    </td>
                    <td>
                      <div className="qty-box">
                        <button
                          type="button"
                          className="qty-btn minus"
                          aria-label="Decrease quantity"
                          onClick={() => decrement(line.productId)}
                        >
                          -
                        </button>
                        <input
                          type="text"
                          inputMode="numeric"
                          className="qty-input"
                          value={line.quantity}
                          aria-label={`Quantity for ${product.title}`}
                          onChange={(e) => {
                            const raw = e.target.value.replace(/\D/g, "");
                            if (raw === "") {
                              setQuantity(line.productId, QTY_MIN);
                              return;
                            }
                            setQuantity(
                              line.productId,
                              Number.parseInt(raw, 10),
                            );
                          }}
                        />
                        <button
                          type="button"
                          className="qty-btn plus"
                          aria-label="Increase quantity"
                          onClick={() => increment(line.productId)}
                        >
                          +
                        </button>
                      </div>
                    </td>
                    <td>
                      <span className="price">
                        {formatMoneyWhole(lineSubtotal)}
                      </span>
                    </td>
                    <td>
                      <button
                        type="button"
                        className="remove-cart-item"
                        style={removeBtnStyle}
                        aria-label={removeAlt}
                        onClick={() => removeLine(line.productId)}
                      >
                        <Image
                          src={cartAssets.removeIcon}
                          alt={removeAlt}
                          width={20}
                          height={20}
                          style={iconImgStyle}
                        />
                      </button>
                    </td>
                  </tr>
                );
              })
            )}
          </tbody>
        </table>
        <div className="cart-table-bottom">
          <form
            className="coupan-form"
            onSubmit={(e) => {
              e.preventDefault();
            }}
          >
            <div className="form-group">
              <label>{cartCouponForm.label}</label>
              <input
                type="text"
                name={cartCouponForm.name}
                placeholder={cartCouponForm.placeholder}
                required={true}
              />
            </div>
            <button type="submit" className="btn-style1">
              {cartCouponForm.applyLabel}
              <span>
                <Image
                  src={cartAssets.arrowIcon}
                  alt={cartAssets.arrowAltApply}
                  width={14}
                  height={14}
                />
              </span>
            </button>
          </form>
          <DataLink href="#" className="btn-style1 v2" onClick={onUpdateCartClick}>
            Update Cart
            <span>
              <Image
                src={cartAssets.arrowIcon}
                alt={cartAssets.arrowAltUpdate}
                width={14}
                height={14}
              />
            </span>
          </DataLink>
        </div>
      </div>
      <div
        className="cart-totals"
        data-aos="fade-up"
        data-aos-duration={900}
        data-aos-delay={300}
      >
        <h3 className="title">{cartTotalsCopy.sectionTitle}</h3>
        <p>{cartTotalsCopy.description}</p>
        <table>
          <tbody>
            <tr>
              <th>{cartTotalsCopy.tableSubtotal}</th>
              <td>{formatMoneyTable(subtotal)}</td>
            </tr>
            <tr>
              <th>{cartTotalsCopy.tableShipping}</th>
              <td>{formatMoneyTable(shipping)}</td>
            </tr>
            <tr>
              <th>{cartTotalsCopy.tableTotal}</th>
              <td>{formatMoneyTable(total)}</td>
            </tr>
          </tbody>
        </table>
        <Link href="/checkout" className="btn-style1">
          Checkout
          <span>
            <Image
              src={cartAssets.arrowIcon}
              alt={cartAssets.arrowAltCheckout}
              width={14}
              height={14}
            />
          </span>
        </Link>
      </div>
    </>
  );
}
