// react
import React, { useCallback, useMemo } from "react";
// third-party
import classNames from "classnames";
// application
import AppImage from "~/components/shared/AppImage";
import AppLink from "~/components/shared/AppLink";
import url from "~/services/url";
import { IProduct } from "~/interfaces/product";
import { useCart, useCartAddItem, 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 {
    product: IProduct;
    canvas?: boolean;
}

function CatalogProductCard({ product, canvas = false }: Props) {
    const cart = useCart();
    const cartAddItem = useCartAddItem();
    const cartRemoveItem = useCartRemoveItem();
    const exchangeRate = useExchangeRate();

    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 dollarStrike = formatPriceDecimals(dollarPrice);
    const bolivarMain = formatBolivarDisplay(hasDiscount ? discountedBolivarPrice : bolivarPrice);

    const cartItem = useMemo(
        () => cart.items.find((item) => item.product.id === product.id),
        [cart.items, product.id],
    );
    const isInCart = Boolean(cartItem);

    const handleToggleCart = useCallback(
        (event: React.MouseEvent) => {
            event.preventDefault();
            event.stopPropagation();

            if (isInCart && cartItem) {
                cartRemoveItem(cartItem.id);
                return;
            }

            cartAddItem(product);
        },
        [cartAddItem, cartItem, cartRemoveItem, isInCart, product],
    );

    const imageSrc = product.images?.[0] || "/images/categories/category-overlay-3.jpg";

    return (
        <article
            className={classNames("catalog-product-card", {
                "catalog-product-card--canvas": canvas,
                "catalog-product-card--unavailable": !isAvailable,
            })}
        >
            <div className="catalog-product-card__content">
                <div className="catalog-product-card__image">
                    <AppLink href={url.product(product)} className="catalog-product-card__image-link">
                        <AppImage className="catalog-product-card__image-tag" src={imageSrc} />
                    </AppLink>
                </div>

                <div className="catalog-product-card__body">
                    <AppLink href={url.product(product)} className="catalog-product-card__title">
                        {toTitleCase(product.name)}
                    </AppLink>

                    <div className="catalog-product-card__badges">
                        <span
                            className={classNames("catalog-product-card__badge", {
                                "catalog-product-card__badge--available": isAvailable,
                                "catalog-product-card__badge--unavailable": !isAvailable,
                            })}
                        >
                            {isAvailable ? "DISPONIBLE" : "NO DISPONIBLE"}
                        </span>
                        {hasDiscount && (
                            <span className="catalog-product-card__badge catalog-product-card__badge--discount">
                                -{discountValue}% DESCUENTO
                            </span>
                        )}
                    </div>

                    <div className="catalog-product-card__prices">
                        {hasDiscount && (
                            <div className="catalog-product-card__price-before">Antes: US$ {dollarStrike}</div>
                        )}
                        <div className="catalog-product-card__price-usd">US$ {dollarMain}</div>
                        <div className="catalog-product-card__price-bs">Bs. {bolivarMain}</div>
                    </div>
                </div>
            </div>

            {isAvailable && (
                <button
                    type="button"
                    className={classNames("catalog-product-card__action", {
                        "catalog-product-card__action--added": isInCart,
                    })}
                    onClick={handleToggleCart}
                    aria-pressed={isInCart}
                                        aria-label={isInCart ? "Quitar de cotización" : "Cotizar"}
                >
                    <i className={classNames("catalog-product-card__action-icon", isInCart ? "fas fa-check" : "fas fa-shopping-cart")} />
                    <span className="catalog-product-card__action-text">{isInCart ? "AGREGADO" : "COTIZAR"}</span>
                </button>
            )}
        </article>
    );
}

export default React.memo(CatalogProductCard);
