"use client";

import { useCart } from "@/context/CartContext";
import { valorMinimoDoItem } from "@/lib/adicionais";
import ValorMinimoDoItem from "@/components/ValorMinimoDoItem";
import { ShoppingBag } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import { createPortal } from "react-dom";
import { getReadableTextColor } from "@/lib/color-contrast";
import {
  calculateEffectiveQuantity,
  checkSaleQuantityLimits,
  calculateTierDiscountPct,
  getBestTierDiscount,
  resolveTierPrice,
  type ProductPriceTier,
} from "@/lib/price-tiers";

type ProductForCart = {
  id: string;
  name: string;
  price: number;
  image_url?: string;
  stock: number;
  track_inventory?: boolean | null;
  allow_negative_stock?: boolean | null;
  user_id: string;
  unit_type?: string | null;
  price_on_request?: boolean | null;
  product_price_tiers?: ProductPriceTier[] | null;
  /* Valor mínimo do item (migration 194). */
  valor_minimo_item?: number | string | null;
  valor_minimo_loja?: boolean | null;
  min_sale_qty_enabled?: boolean | null;
  min_sale_qty?: number | null;
  max_sale_qty_enabled?: boolean | null;
  max_sale_qty?: number | null;
  allowed_sale_qty_enabled?: boolean | null;
  allowed_sale_quantities?: number[] | null;
  has_variations?: boolean;
  /* "digital": a compra é rápida, na página do produto, fora do carrinho. */
  product_kind?: string | null;
  custom_fields_config?: Array<{
    id?: string | null;
    title?: string | null;
    active?: boolean | null;
  }> | null;
};

import { useRouter } from "next/navigation";
import { useVisaoDaLoja } from "@/components/VisaoDaLojaContext";
import { estaEsgotado } from "@/lib/loja/regras-da-loja";

const EPSILON = 0.000001;

function formatDiscountPct(value: number) {
  const safeValue = Number(value) || 0;
  return new Intl.NumberFormat("pt-BR", {
    maximumFractionDigits: safeValue >= 10 ? 0 : 1,
    minimumFractionDigits: 0,
  }).format(safeValue);
}

function formatTierThreshold(minQty: number, unitType: string) {
  const qty = Number(minQty) || 0;
  const qtyLabel = Number.isInteger(qty)
    ? String(qty)
    : new Intl.NumberFormat("pt-BR", { maximumFractionDigits: 2 }).format(qty);

  if (unitType === "square_meter") return `${qtyLabel} m²`;
  if (unitType === "meter" || unitType === "linear_meter") return `${qtyLabel} m`;
  return `${qtyLabel} unidades`;
}

function formatQuantityLimit(value: number | null) {
  if (value === null || !Number.isFinite(value)) return "0";
  const rounded = Number(value.toFixed(3));
  return Number.isInteger(rounded)
    ? String(rounded)
    : new Intl.NumberFormat("pt-BR", { minimumFractionDigits: 0, maximumFractionDigits: 3 }).format(rounded);
}

function resolveFixedPieces(product: ProductForCart) {
  const allowedValues = resolveAllowedQuantities(product);
  if ((product.unit_type || "unit") !== "square_meter" && allowedValues.length === 1) {
    return allowedValues[0];
  }

  const minEnabled = Boolean(product.min_sale_qty_enabled);
  const maxEnabled = Boolean(product.max_sale_qty_enabled);
  const minRaw = Number(product.min_sale_qty);
  const maxRaw = Number(product.max_sale_qty);
  const hasBothLimits =
    minEnabled &&
    maxEnabled &&
    Number.isFinite(minRaw) &&
    Number.isFinite(maxRaw) &&
    minRaw > 0 &&
    maxRaw > 0;

  if (!hasBothLimits || Math.abs(minRaw - maxRaw) > EPSILON) {
    return null;
  }

  return Math.max(1, Math.ceil(minRaw));
}

function resolveAllowedQuantities(product: ProductForCart) {
  if (!product.allowed_sale_qty_enabled || !Array.isArray(product.allowed_sale_quantities)) return [];
  const values = product.allowed_sale_quantities
    .map((value) => Number(value))
    .filter((value) => Number.isFinite(value) && value > 0)
    .map((value) => Number(value.toFixed(3)));
  if (!values.length) return [];
  return Array.from(new Set(values)).sort((a, b) => a - b);
}

function resolveAdjacentAllowedQuantity(allowedValues: number[], currentValue: number, direction: -1 | 1) {
  if (!allowedValues.length) return null;
  if (direction < 0) {
    for (let index = allowedValues.length - 1; index >= 0; index -= 1) {
      if (allowedValues[index] + EPSILON < currentValue) return allowedValues[index];
    }
    return null;
  }
  for (let index = 0; index < allowedValues.length; index += 1) {
    if (allowedValues[index] - EPSILON > currentValue) return allowedValues[index];
  }
  return null;
}

export default function AddToCartButton({ 
  product, 
  primaryColor, 
  fullWidth = false,
  slug,
  variant = "default",
}: { 
  product: ProductForCart, 
  primaryColor: string,
  fullWidth?: boolean,
  slug?: string,
  variant?: "default" | "icon"
}) {
  const { addToCart } = useCart();
  const router = useRouter();
  /* O que este visitante pode ver e fazer (regras da loja). */
  const visao = useVisaoDaLoja();
  const textoSemPreco = visao.textoNoLugarDoPreco;
  const hasCustomFields = useMemo(() => {
    const fields = Array.isArray(product.custom_fields_config) ? product.custom_fields_config : [];
    return fields.some((field) => String(field?.title || "").trim() && field?.active !== false);
  }, [product.custom_fields_config]);
  const [isOpen, setIsOpen] = useState(false);
  const [isDesktopViewport, setIsDesktopViewport] = useState(false);
  const [widthDigits, setWidthDigits] = useState("");
  const [heightDigits, setHeightDigits] = useState("");
  const allowedQuantities = useMemo(() => resolveAllowedQuantities(product), [product]);
  const initialPieces = useMemo(() => {
    if ((product.unit_type || "unit") === "square_meter") return 1;
    if (allowedQuantities.length > 0) return allowedQuantities[0];
    const minEnabled = Boolean(product.min_sale_qty_enabled);
    const minQty = minEnabled ? Number(product.min_sale_qty) : 0;
    if (!minEnabled || !Number.isFinite(minQty) || minQty <= 1) return 1;
    return Math.max(1, Math.ceil(minQty));
  }, [allowedQuantities, product.min_sale_qty, product.min_sale_qty_enabled, product.unit_type]);
  const [pieces, setPieces] = useState(initialPieces);
  const [piecesInput, setPiecesInput] = useState(() => formatQuantityLimit(initialPieces));
  const [addError, setAddError] = useState("");
  const fixedPieces = resolveFixedPieces(product);
  const isPiecesLocked = fixedPieces !== null;
  const hasAllowedQuantities = allowedQuantities.length > 0;
  const isIntervalMode = Boolean(product.allowed_sale_qty_enabled) && hasAllowedQuantities;
  const selectedPieces = isPiecesLocked && fixedPieces !== null ? fixedPieces : pieces;
  const selectedPiecesInput =
    isPiecesLocked && fixedPieces !== null
      ? formatQuantityLimit(fixedPieces)
      : hasAllowedQuantities
        ? formatQuantityLimit(selectedPieces)
        : piecesInput;

  const handlePiecesInputChange = (rawValue: string) => {
    if (isPiecesLocked || hasAllowedQuantities) return;
    const digitsOnly = rawValue.replace(/\D/g, "");
    setAddError("");
    setPiecesInput(digitsOnly);
    if (!digitsOnly) return;
    const next = Number.parseInt(digitsOnly, 10);
    if (Number.isFinite(next)) {
      setPieces(Math.max(1, next));
    }
  };

  const normalizePiecesInput = () => {
    if (isPiecesLocked || hasAllowedQuantities) return;
    const digitsOnly = piecesInput.replace(/\D/g, "");
    const normalized = digitsOnly ? Math.max(1, Number.parseInt(digitsOnly, 10)) : 1;
    setPieces(normalized);
    setPiecesInput(String(normalized));
  };

  const formatDigitsToMeters = (digits: string) => {
    const cleaned = digits.replace(/\D/g, "");
    if (!cleaned) return "";

    const padded = cleaned.padStart(3, "0");
    const intPartRaw = padded.slice(0, -2);
    const intPart = intPartRaw.replace(/^0+(?=\d)/, "") || "0";
    const fracPart = padded.slice(-2);
    return `${intPart},${fracPart}`;
  };

  const unitType = product.unit_type || "unit";
  const isSquareMeter = unitType === "square_meter";

  const widthM = formatDigitsToMeters(widthDigits);
  const heightM = formatDigitsToMeters(heightDigits);
  const parsedWidth = Number(widthM.replace(",", "."));
  const parsedHeight = Number(heightM.replace(",", "."));
  const isValidDims = isSquareMeter ? parsedWidth > 0 && parsedHeight > 0 : true;

  const areaEach = useMemo(() => {
    if (!isSquareMeter || !isValidDims) return 0;
    return parsedWidth * parsedHeight;
  }, [isSquareMeter, isValidDims, parsedHeight, parsedWidth]);

  const totalArea = useMemo(() => {
    if (!isSquareMeter || !isValidDims) return 0;
    return areaEach * selectedPieces;
  }, [areaEach, isSquareMeter, isValidDims, selectedPieces]);

  const tierResolution = useMemo(() => {
    const effectiveQty = calculateEffectiveQuantity({
      quantity: selectedPieces,
      unit_type: unitType,
      width_m: isSquareMeter ? parsedWidth : undefined,
      height_m: isSquareMeter ? parsedHeight : undefined,
    });
    return resolveTierPrice(product.price, effectiveQty, product.product_price_tiers || []);
  }, [isSquareMeter, parsedHeight, parsedWidth, product.price, product.product_price_tiers, selectedPieces, unitType]);

  const resolvedUnitPrice = tierResolution.unitPrice;
  const appliedTier = tierResolution.tier;
  const appliedDiscountPct = calculateTierDiscountPct(product.price, resolvedUnitPrice);
  const showcaseTierDiscount = useMemo(
    () => getBestTierDiscount(product.price, product.product_price_tiers || []),
    [product.price, product.product_price_tiers]
  );

  const totalPrice = useMemo(() => {
    if (product.price_on_request) return null;
    const effectiveQty = calculateEffectiveQuantity({
      quantity: selectedPieces,
      unit_type: unitType,
      width_m: isSquareMeter ? parsedWidth : undefined,
      height_m: isSquareMeter ? parsedHeight : undefined,
    });
    if (!isValidDims) return 0;
    return resolvedUnitPrice * effectiveQty;
  }, [isSquareMeter, isValidDims, parsedHeight, parsedWidth, product.price_on_request, resolvedUnitPrice, selectedPieces, unitType]);
  /* Valor mínimo do item: a linha inteira vale pelo menos ele (o carrinho faz a mesma conta). */
  const valorMinimo = valorMinimoDoItem(product, "loja");
  const minimoAplicado =
    valorMinimo !== null && isValidDims && totalPrice !== null && Math.round(totalPrice * 100) / 100 < valorMinimo ? valorMinimo : null;

  const getCheckForPieces = (nextPieces: number) => {
    const effectiveQty = calculateEffectiveQuantity({
      quantity: nextPieces,
      unit_type: unitType,
      width_m: isSquareMeter ? parsedWidth : undefined,
      height_m: isSquareMeter ? parsedHeight : undefined,
    });
    return checkSaleQuantityLimits({
      min_sale_qty_enabled: product.min_sale_qty_enabled,
      min_sale_qty: product.min_sale_qty,
      max_sale_qty_enabled: product.max_sale_qty_enabled,
      max_sale_qty: product.max_sale_qty,
      allowed_sale_qty_enabled: product.allowed_sale_qty_enabled,
      allowed_sale_quantities: product.allowed_sale_quantities,
      effectiveQuantity: effectiveQty,
    });
  };

  const quantityCheck = getCheckForPieces(selectedPieces);
  /* Esgotado so quando o estoque limita a venda: com "Permitir estoque
     negativo" o produto entra no carrinho como se houvesse saldo. */
  const esgotado = estaEsgotado(product);

  const quantityRuleMessage = useMemo(() => {
    if (quantityCheck.isBelowMin && quantityCheck.minQty !== null) {
      return `Quantidade minima: ${formatQuantityLimit(quantityCheck.minQty)}.`;
    }
    if (quantityCheck.isAboveMax && quantityCheck.maxQty !== null) {
      return `Quantidade maxima: ${formatQuantityLimit(quantityCheck.maxQty)}.`;
    }
    if (quantityCheck.isNotAllowedValue && quantityCheck.allowedQuantities.length > 0) {
      return `Use quantidade permitida: ${quantityCheck.allowedQuantities.map((value) => formatQuantityLimit(value)).join(", ")}.`;
    }
    return "";
  }, [quantityCheck.allowedQuantities, quantityCheck.isAboveMax, quantityCheck.isBelowMin, quantityCheck.isNotAllowedValue, quantityCheck.maxQty, quantityCheck.minQty]);

  const quickDefaultQuantity = useMemo(() => {
    if (allowedQuantities.length > 0) return allowedQuantities[0];
    const minEnabled = Boolean(product.min_sale_qty_enabled);
    const minQty = minEnabled ? Number(product.min_sale_qty) : 0;
    if (!minEnabled || !Number.isFinite(minQty) || minQty <= 1) return 1;
    return Math.max(1, Math.ceil(minQty));
  }, [allowedQuantities, product.min_sale_qty, product.min_sale_qty_enabled]);

  const quickAddPreviewCheck = useMemo(() => {
    const effectiveQty = calculateEffectiveQuantity({
      quantity: quickDefaultQuantity,
      unit_type: unitType,
    });
    return checkSaleQuantityLimits({
      min_sale_qty_enabled: product.min_sale_qty_enabled,
      min_sale_qty: product.min_sale_qty,
      max_sale_qty_enabled: product.max_sale_qty_enabled,
      max_sale_qty: product.max_sale_qty,
      allowed_sale_qty_enabled: product.allowed_sale_qty_enabled,
      allowed_sale_quantities: product.allowed_sale_quantities,
      effectiveQuantity: effectiveQty,
    });
  }, [product.allowed_sale_quantities, product.allowed_sale_qty_enabled, product.max_sale_qty, product.max_sale_qty_enabled, product.min_sale_qty, product.min_sale_qty_enabled, quickDefaultQuantity, unitType]);

  const quickAddRuleMessage = useMemo(() => {
    if (quickAddPreviewCheck.isBelowMin && quickAddPreviewCheck.minQty !== null) {
      return `Quantidade minima: ${formatQuantityLimit(quickAddPreviewCheck.minQty)}.`;
    }
    if (quickAddPreviewCheck.isAboveMax && quickAddPreviewCheck.maxQty !== null) {
      return `Quantidade maxima: ${formatQuantityLimit(quickAddPreviewCheck.maxQty)}.`;
    }
    if (quickAddPreviewCheck.isNotAllowedValue && quickAddPreviewCheck.allowedQuantities.length > 0) {
      return `Use quantidade permitida: ${quickAddPreviewCheck.allowedQuantities
        .map((value) => formatQuantityLimit(value))
        .join(", ")}.`;
    }
    return "";
  }, [quickAddPreviewCheck.allowedQuantities, quickAddPreviewCheck.isAboveMax, quickAddPreviewCheck.isBelowMin, quickAddPreviewCheck.isNotAllowedValue, quickAddPreviewCheck.maxQty, quickAddPreviewCheck.minQty]);

  const nextPiecesDown = hasAllowedQuantities
    ? resolveAdjacentAllowedQuantity(allowedQuantities, selectedPieces, -1)
    : Math.max(1, selectedPieces - 1);
  const nextPiecesUp = hasAllowedQuantities
    ? resolveAdjacentAllowedQuantity(allowedQuantities, selectedPieces, 1)
    : selectedPieces + 1;
  const canDecreasePieces =
    !isPiecesLocked &&
    nextPiecesDown !== null &&
    nextPiecesDown > 0 &&
    getCheckForPieces(nextPiecesDown).isValid;
  const canIncreasePieces =
    !isPiecesLocked &&
    nextPiecesUp !== null &&
    getCheckForPieces(nextPiecesUp).isValid;

  const formatMoney = (value: number) =>
    new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(value);
  const buttonTextColor = useMemo(() => getReadableTextColor(primaryColor), [primaryColor]);
  const isIconVariant = variant === "icon";
  const shouldPortalModal = isIconVariant && isDesktopViewport;

  useEffect(() => {
    const media = window.matchMedia("(min-width: 1024px)");
    const update = () => setIsDesktopViewport(media.matches);
    update();
    media.addEventListener("change", update);
    return () => media.removeEventListener("change", update);
  }, []);

  const modalContent = isOpen ? (
    <div
      className="fixed inset-0 z-[80] flex items-center justify-center"
      onClick={() => setIsOpen(false)}
    >
      <div className="absolute inset-0 bg-black/40" />
      <div
        className="relative w-full max-w-md rounded-2xl bg-white shadow-xl border border-gray-100 p-6"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="flex items-center justify-between gap-4">
          <div className="min-w-0">
            <div className="text-sm font-semibold text-gray-900 truncate">{product.name}</div>
            {product.price_on_request ? (
              <div className="text-xs text-gray-500">{textoSemPreco}</div>
            ) : (
              <div className="space-y-0.5">
                <div className="text-xs font-semibold text-violet-700">Preço sob medida</div>
                <div className="text-[11px] text-gray-500">Informe as medidas para calcular o valor final</div>
              </div>
            )}
            {showcaseTierDiscount && !product.price_on_request && !isIntervalMode && (
              <div className="mt-2">
                <span className="inline-flex items-center rounded-full border border-emerald-200 bg-emerald-50 px-2.5 py-1 text-[10px] font-bold uppercase tracking-wide text-emerald-700">
                  {formatDiscountPct(showcaseTierDiscount.discountPct)}% OFF a partir de{" "}
                  {formatTierThreshold(showcaseTierDiscount.tier.min_qty, unitType)}
                </span>
              </div>
            )}
          </div>
          <button
            type="button"
            className="h-9 w-9 rounded-xl border border-gray-200 text-gray-500 hover:bg-gray-50"
            onClick={() => setIsOpen(false)}
          >
            x
          </button>
        </div>

        <div className="mt-4 grid grid-cols-2 gap-3">
          <div className="space-y-1">
            <label className="text-xs font-semibold text-gray-600">Largura (m)</label>
            <input
              inputMode="numeric"
              value={widthM}
              onKeyDown={(e) => {
                if (e.key !== "Backspace") return;
                const hasSelection = e.currentTarget.selectionStart !== e.currentTarget.selectionEnd;
                if (hasSelection) return;
                e.preventDefault();
                setWidthDigits((d) => d.slice(0, -1));
              }}
              onChange={(e) => {
                setAddError("");
                setWidthDigits(e.target.value.replace(/\D/g, ""));
              }}
              className="w-full px-3 py-2 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-[var(--ks-color-primary)]/30 focus:border-[var(--ks-color-primary)]"
              placeholder="Ex: 1,20"
            />
          </div>
          <div className="space-y-1">
            <label className="text-xs font-semibold text-gray-600">Altura (m)</label>
            <input
              inputMode="numeric"
              value={heightM}
              onKeyDown={(e) => {
                if (e.key !== "Backspace") return;
                const hasSelection = e.currentTarget.selectionStart !== e.currentTarget.selectionEnd;
                if (hasSelection) return;
                e.preventDefault();
                setHeightDigits((d) => d.slice(0, -1));
              }}
              onChange={(e) => {
                setAddError("");
                setHeightDigits(e.target.value.replace(/\D/g, ""));
              }}
              className="w-full px-3 py-2 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-[var(--ks-color-primary)]/30 focus:border-[var(--ks-color-primary)]"
              placeholder="Ex: 0,80"
            />
          </div>
        </div>

        <div className="mt-3 flex items-center justify-between gap-3">
          <div className="space-y-1">
            <div className="text-xs font-semibold text-gray-600">Quantidade (peças)</div>
            <div className="inline-flex items-center rounded-xl border border-gray-200 bg-white overflow-hidden">
              <button
                type="button"
                className="h-10 w-10 text-gray-600 hover:bg-gray-50 disabled:opacity-50"
                disabled={!canDecreasePieces}
                onClick={() => {
                  const next = hasAllowedQuantities
                    ? resolveAdjacentAllowedQuantity(allowedQuantities, selectedPieces, -1)
                    : Math.max(1, selectedPieces - 1);
                  if (next === null) return;
                  setPieces(next);
                  setPiecesInput(formatQuantityLimit(next));
                  setAddError("");
                }}
              >
                -
              </button>
              <input
                type="text"
                inputMode="numeric"
                pattern="[0-9]*"
                value={selectedPiecesInput}
                onChange={(e) => handlePiecesInputChange(e.target.value)}
                onFocus={(e) => e.currentTarget.select()}
                onBlur={normalizePiecesInput}
                readOnly={isPiecesLocked || hasAllowedQuantities}
                className={`w-14 h-10 text-center font-semibold text-gray-900 outline-none ${
                  isPiecesLocked || hasAllowedQuantities ? "cursor-not-allowed bg-gray-50 text-gray-500" : ""
                }`}
                aria-label="Quantidade"
              />
              <button
                type="button"
                className="h-10 w-10 text-gray-600 hover:bg-gray-50"
                disabled={!canIncreasePieces}
                onClick={() => {
                  const next = hasAllowedQuantities
                    ? resolveAdjacentAllowedQuantity(allowedQuantities, selectedPieces, 1)
                    : selectedPieces + 1;
                  if (next === null) return;
                  setPieces(next);
                  setPiecesInput(formatQuantityLimit(next));
                  setAddError("");
                }}
              >
                +
              </button>
            </div>
          </div>

          <div className="text-right">
            <div className="text-[11px] font-bold uppercase tracking-wide text-gray-500">Total</div>
            <div className="text-lg font-black text-gray-900">
              {product.price_on_request ? textoSemPreco : formatMoney(minimoAplicado ?? (totalPrice || 0))}
            </div>
            <div className="text-[11px] text-gray-500">
              {isValidDims ? `${totalArea.toFixed(2)} m²` : "Informe as medidas"}
            </div>
            {valorMinimo !== null && !product.price_on_request && (
              <div className="mt-1.5">
                <ValorMinimoDoItem minimo={valorMinimo} cor={primaryColor} className="!text-[11px]" />
              </div>
            )}
            {appliedTier && !product.price_on_request && !isIntervalMode && (
              <div className={`mt-1 text-[11px] ${appliedDiscountPct > 0 ? "text-emerald-600" : "text-sky-600"}`}>
                {appliedDiscountPct > 0
                  ? `Desconto aplicado: ${formatDiscountPct(appliedDiscountPct)}% OFF (a partir de ${formatTierThreshold(appliedTier.min_qty, unitType)}).`
                  : `Faixa de preço aplicada a partir de ${formatTierThreshold(appliedTier.min_qty, unitType)}.`}
              </div>
            )}
            {quantityRuleMessage && (
              <div className="mt-1 text-[11px] font-medium text-amber-700">
                {quantityRuleMessage}
              </div>
            )}
          </div>
        </div>

        <button
          type="button"
          disabled={!isValidDims || esgotado || !quantityCheck.isValid}
          className="mt-4 w-full px-4 py-3 rounded-xl text-sm font-bold shadow-md disabled:opacity-50 disabled:cursor-not-allowed"
          style={{ backgroundColor: primaryColor, color: buttonTextColor }}
          onClick={() => {
            if (!isValidDims) return;
            const result = addToCart(product, selectedPieces, { width_m: parsedWidth, height_m: parsedHeight });
            if (!result.ok) {
              setAddError(result.message || "Nao foi possivel adicionar este produto.");
              return;
            }
            setAddError("");
            setIsOpen(false);
          }}
        >
          {visao.rotuloDoBotao || "Adicionar ao carrinho"}
        </button>
        {addError && (
          <p className="mt-2 text-xs font-medium text-red-600">{addError}</p>
        )}
      </div>
    </div>
  ) : null;

  /* Sem botao de compra: so vitrine, loja em pausa ou fechada. Quem ainda
     precisa entrar ve o botao, que leva ao login. */
  if (visao.modoDeCompra === "showcase" || (!visao.podeComprar && !visao.precisaEntrar)) return null;

  return (
    <>
      <button
        onClick={(e) => {
          e.preventDefault();
          e.stopPropagation();

          if (visao.precisaEntrar) {
            router.push(`/${slug}/cliente/login?next=${encodeURIComponent(window.location.pathname)}`);
            return;
          }
          /* Produto digital não entra no carrinho: a página dele tem a compra
             rápida, que entrega na hora. */
          if (product.product_kind === "digital" && slug) {
            router.push(`/${slug}/p/${product.id}`);
            return;
          }
          /* Pedido pelo WhatsApp, ou produto esgotado que vira pedido de
             orcamento: a pagina do produto e quem abre a conversa. */
          if ((visao.modoDeCompra === "whatsapp" || (esgotado && visao.regras.esgotado === "quote")) && slug) {
            router.push(`/${slug}/p/${product.id}`);
            return;
          }

          if ((product.has_variations || hasCustomFields) && slug) {
             router.push(`/${slug}/p/${product.id}`);
             return;
          }

          if (isSquareMeter) {
            setAddError("");
            setIsOpen(true);
            return;
          }
          const result = addToCart(product, quickDefaultQuantity);
          if (!result.ok) {
            setAddError(result.message || "Nao foi possivel adicionar este produto.");
            return;
          }
          setAddError("");
        }}
        disabled={(esgotado && visao.regras.esgotado !== "quote") || (!isSquareMeter && !quickAddPreviewCheck.isValid)}
        className={isIconVariant
          ? "h-8 w-8 min-h-8 min-w-8 shrink-0 rounded-full shadow-sm hover:shadow-md transition-all disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center"
          : `px-4 py-2 rounded-xl text-sm font-semibold hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed shadow-md flex items-center justify-center gap-2 ${fullWidth ? 'w-full py-3.5' : ''}`}
        style={{ backgroundColor: primaryColor, color: buttonTextColor }}
      >
        {isIconVariant ? (
          <ShoppingBag size={14} strokeWidth={2.5} />
        ) : (
          <>
            <ShoppingBag size={18} />
            {esgotado ? 'Indisponível' : product.product_kind === "digital" ? 'Ver produto' : (
              product.has_variations 
                ? 'Ver opções'
                : (hasCustomFields ? "Personalizar" : (isSquareMeter ? 'Calcular' : (quickDefaultQuantity > 1 ? `Adicionar ${quickDefaultQuantity}` : 'Adicionar')))
            )}
          </>
        )}
      </button>
      {!isIconVariant && !isSquareMeter && addError && (
        <p className="mt-2 text-xs font-medium text-red-600">{addError}</p>
      )}
      {!isIconVariant && !isSquareMeter && !addError && quickAddRuleMessage && (
        <p className="mt-2 text-xs font-medium text-amber-700">{quickAddRuleMessage}</p>
      )}

      {modalContent && (shouldPortalModal ? createPortal(modalContent, document.body) : modalContent)}
    </>
  );
}
