// react
import React, { useCallback, useMemo, useState } from "react";
// third-party
import classNames from "classnames";
import { useRouter } from "next/router";
import { format as formatUrl } from "url";
// application
import AppLink from "~/components/shared/AppLink";
import { normalizeLinkHref } from "~/components/shared/AppLink";
import InputNumber from "~/components/shared/InputNumber";
import url from "~/services/url";
import { IProduct } from "~/interfaces/product";
import {
    useCart,
    useCartAddItem,
    useCartUpdateQuantities,
    useCartRemoveItem,
} from "~/store/cart/cartHooks";
import { useExchangeRate } from "~/services/hooks/useExchangeRate";
import { formatPriceDecimals } from "~/utils/formatPrice";
import { toTitleCase } from "~/utils/textFormat";

function getDollarPrice(product: IProduct): number {
    if (
        product.maximo != null &&
        typeof product.maximo === "number" &&
        !isNaN(product.maximo) &&
        product.maximo > 0
    ) {
        return product.maximo;
    }
    const price =
        typeof product.price === "number" && !isNaN(product.price) ? product.price : 0;
    return price;
}

function formatBolivarDisplay(value: number): string {
    if (Number.isNaN(value)) return "0,00";
    return value.toLocaleString("es-VE", {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,
        useGrouping: true,
    });
}

interface Props {
    products: IProduct[];
}

function CatalogProductsTable({ products }: Props) {
    const router = useRouter();
    const exchangeRate = useExchangeRate();
    const cart = useCart();
    const cartAddItem = useCartAddItem();
    const cartUpdateQuantities = useCartUpdateQuantities();
    const cartRemoveItem = useCartRemoveItem();

    // Estado local para el toggle: "Agregado" / "Añadir" por producto.
    const [added, setAdded] = useState<Record<number, boolean>>({});

    // Cantidad seleccionada por producto en la columna "Cantidad".
    const [quantities, setQuantities] = useState<Record<number, number>>({});

    const handleRowClick = useCallback(
        (product: IProduct) => {
            const productUrl = url.product(product);
            const normalized = normalizeLinkHref(productUrl);
            router.push(formatUrl(normalized.as));
        },
        [router],
    );

    // Mapa de id producto -> item del carrito (si ya está agregado).
    const cartItemsByProduct = useMemo(() => {
        const map: Record<number, (typeof cart.items)[number]> = {};
        cart.items.forEach((item) => {
            map[item.product.id] = item;
        });
        return map;
    }, [cart.items]);

    const handleQuantityChange = (productId: number, value: number | string) => {
        const parsed = typeof value === "string" ? parseFloat(value) : value;
        setQuantities((prev) => ({
            ...prev,
            [productId]: Number.isNaN(parsed) || parsed < 1 ? 1 : Math.floor(parsed),
        }));
    };

    const handleAddToCart = (product: IProduct, event: React.MouseEvent) => {
        event.preventDefault();
        event.stopPropagation();

        const quantity = quantities[product.id] || 1;
        const existing = cartItemsByProduct[product.id];
        const toggled = added[product.id];

        // Alternar el estado visual inmediatamente.
        setAdded((prev) => ({ ...prev, [product.id]: !toggled }));

        if (toggled) {
            // Segundo click: quitar del carrito -> vuelve a "Añadir".
            if (existing) {
                cartRemoveItem(existing.id);
            }
        } else {
            // Primer click: agregar -> pasa a "Agregado".
            if (existing) {
                cartUpdateQuantities([{ itemId: existing.id, value: quantity }]);
            } else {
                cartAddItem(product, [], quantity);
            }
        }
    };

    return (
        <div className="catalog-products-table-wrap">
            <div className="table-responsive">
                <table className="catalog-products-table">
                    <thead>
                        <tr>
                            <th className="catalog-products-table__col-code">Código</th>
                            <th className="catalog-products-table__col-name">Producto</th>
                            <th className="catalog-products-table__col-price">Precio $</th>
                            <th className="catalog-products-table__col-price-bs">Precio Bs.</th>
                            <th className="catalog-products-table__col-status">Status</th>
                            <th className="catalog-products-table__col-quantity">Cantidad</th>
                            <th className="catalog-products-table__col-cart">Cotizar</th>
                        </tr>
                    </thead>
                    <tbody>
                        {products.map((product) => {
                            const discountValue = Number((product as any).discount ?? 0);
                            const hasDiscount = discountValue > 0;
                            const isAvailable = product.status === 1;
                            const dollarPrice = getDollarPrice(product);
                            const bolivarPrice = dollarPrice * (exchangeRate > 0 ? exchangeRate : 0);
                            const discountedDollarPrice = hasDiscount
                                ? dollarPrice * (1 - discountValue / 100)
                                : dollarPrice;
                            const discountedBolivarPrice = hasDiscount
                                ? bolivarPrice * (1 - discountValue / 100)
                                : bolivarPrice;
                            const dollarMain = formatPriceDecimals(
                                hasDiscount ? discountedDollarPrice : dollarPrice,
                            );
                            const bolivarMain = formatBolivarDisplay(
                                hasDiscount ? discountedBolivarPrice : bolivarPrice,
                            );
                            // Precio original (antes del descuento) para mostrarlo tachado
                            const dollarStrike = formatPriceDecimals(dollarPrice);
                            const bolivarStrike = formatBolivarDisplay(bolivarPrice);

                            const selQuantity = quantities[product.id] || 1;

                            return (
                                <tr
                                    key={product.id}
                                    className="catalog-products-table__row"
                                    onClick={() => handleRowClick(product)}
                                    role="button"
                                    tabIndex={0}
                                    onKeyDown={(e) => {
                                        if (e.key === "Enter" || e.key === " ") {
                                            e.preventDefault();
                                            handleRowClick(product);
                                        }
                                    }}
                                >
                                    <td className="catalog-products-table__code">
                                        {product.sku || "—"}
                                    </td>
                                    <td className="catalog-products-table__name">
                                        <AppLink href={url.product(product)} className="catalog-products-table__product-name">{toTitleCase(product.name)}</AppLink>
                                        {hasDiscount && (
                                            <span className="catalog-products-table__offer-badge">
                                                -{discountValue}% Descuento
                                            </span>
                                        )}
                                    </td>
                                    <td className="catalog-products-table__price">
                                        {hasDiscount ? (
                                            <>
                                                <span className="catalog-products-table__price-current">US$ {dollarMain}</span>
                                                <span className="catalog-products-table__price-original">US$ {dollarStrike}</span>
                                            </>
                                        ) : (
                                            `US$ ${dollarMain}`
                                        )}
                                    </td>
                                    <td className="catalog-products-table__price-bs">
                                        {hasDiscount ? (
                                            <>
                                                <span className="catalog-products-table__price-current">Bs. {bolivarMain}</span>
                                                <span className="catalog-products-table__price-original">Bs. {bolivarStrike}</span>
                                            </>
                                        ) : (
                                            `Bs. ${bolivarMain}`
                                        )}
                                    </td>
                                    <td className="catalog-products-table__col-status">
                                        <span
                                            className={classNames("catalog-products-table__status-dot", {
                                                "catalog-products-table__status-dot--available": isAvailable,
                                                "catalog-products-table__status-dot--unavailable": !isAvailable,
                                            })}
                                            title={isAvailable ? "Disponible" : "No disponible"}
                                            aria-label={isAvailable ? "Disponible" : "No disponible"}
                                        />
                                    </td>
                                    <td
                                        className="catalog-products-table__col-quantity"
                                        onClick={(e) => e.stopPropagation()}
                                    >
                                        {isAvailable ? (
                                            <InputNumber
                                                min={1}
                                                size="sm"
                                                className="catalog-products-table__quantity"
                                                value={selQuantity}
                                                onClick={(e) => e.stopPropagation()}
                                                onChange={(value) => handleQuantityChange(product.id, value)}
                                            />
                                        ) : (
                                            <span className="text-muted small">—</span>
                                        )}
                                    </td>
                                    <td className="catalog-products-table__col-cart">
                                        {isAvailable && (
                                            <button
                                                type="button"
                                                className={classNames("catalog-products-table__add", {
                                                    "catalog-products-table__add--added": added[product.id],
                                                })}
                                                onClick={(e) => handleAddToCart(product, e)}
                                                aria-pressed={added[product.id]}
                                                                                            aria-label={added[product.id] ? "Agregado" : "Cotizar"}
                                            >
                                                <i className={classNames("fas", added[product.id] ? "fa-check" : "fa-cart-plus")} />
                                                <span>{added[product.id] ? "AGREGADO" : "COTIZAR"}</span>
                                            </button>
                                        )}
                                    </td>
                                </tr>
                            );
                        })}
                    </tbody>
                </table>
            </div>
        </div>
    );
}

export default React.memo(CatalogProductsTable);


