"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { ExternalLink, MessageCircle, ShoppingCart, Store } from "lucide-react";
import type { MarketplaceProduct } from "@/lib/marketplace-data";
import { getMarketplaceDisplayPrice } from "@/lib/marketplace-product-pricing";
import {
  calculateEffectiveQuantity,
  checkSaleQuantityLimits,
  resolveTierPrice,
} from "@/lib/price-tiers";

type MarketplaceProductDetailClientProps = {
  product: MarketplaceProduct;
};

type NormalizedCustomField = {
  id: string;
  title: string;
  field_type: "text" | "textarea" | "number";
  placeholder: string;
  required: boolean;
  variation_signature: string | null;
  position: number;
};

function formatMoney(value: number) {
  return new Intl.NumberFormat("pt-BR", {
    style: "currency",
    currency: "BRL",
  }).format(Number(value) || 0);
}

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 formatQuantityValue(value: number) {
  if (!Number.isFinite(value) || value <= 0) return "0";
  const normalized = Number(value.toFixed(3));
  return Number.isInteger(normalized)
    ? String(normalized)
    : new Intl.NumberFormat("pt-BR", { minimumFractionDigits: 0, maximumFractionDigits: 3 }).format(normalized);
}

function resolveAllowedQuantities(product: MarketplaceProduct) {
  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] < currentValue) return allowedValues[index];
    }
    return null;
  }

  for (let index = 0; index < allowedValues.length; index += 1) {
    if (allowedValues[index] > currentValue) return allowedValues[index];
  }
  return null;
}

function normalizeVariationSignature(combination: Record<string, string> | null | undefined) {
  if (!combination || typeof combination !== "object") return "";
  return Object.entries(combination)
    .map(([key, value]) => [String(key || "").trim().toLowerCase(), String(value || "").trim().toLowerCase()] as const)
    .filter(([key, value]) => Boolean(key) && Boolean(value))
    .sort((a, b) => a[0].localeCompare(b[0]))
    .map(([key, value]) => `${key}:${value}`)
    .join("|");
}

function normalizeText(value: string) {
  return String(value || "").trim().toLowerCase();
}

function matchesFieldVariationSignature(
  fieldSignature: string,
  params: {
    selectedVariationSignature: string;
    selectedOptions: Record<string, string[]>;
  }
) {
  const signature = normalizeText(fieldSignature);
  if (!signature) return true;

  if (signature.startsWith("option::")) {
    const [, rawAttr, rawValue] = signature.split("::");
    const attr = normalizeText(rawAttr || "");
    const value = normalizeText(rawValue || "");
    if (!attr || !value) return false;
    const selected = params.selectedOptions[Object.keys(params.selectedOptions).find((key) => normalizeText(key) === attr) || ""];
    if (!Array.isArray(selected)) return false;
    return selected.some((item) => normalizeText(item) === value);
  }

  return signature === normalizeText(params.selectedVariationSignature);
}

function buildOptionSignature(attributeName: string, optionLabel: string) {
  return `option::${normalizeText(attributeName)}::${normalizeText(optionLabel)}`;
}

function normalizeCustomFieldsConfig(input: MarketplaceProduct["custom_fields_config"]) {
  if (!Array.isArray(input)) return [] as NormalizedCustomField[];
  return input
    .map((field, index) => {
      const title = String(field?.title || "").trim();
      if (!title || field?.active === false) return null;
      const id = String(field?.id || `cf_${index + 1}`).trim() || `cf_${index + 1}`;
      const fieldType = field?.field_type === "textarea" || field?.field_type === "number" ? field.field_type : "text";
      const variationSignature = String(field?.variation_signature || "").trim().toLowerCase();
      return {
        id,
        title,
        field_type: fieldType,
        placeholder: String(field?.placeholder || "").trim(),
        required: Boolean(field?.required),
        variation_signature: variationSignature || null,
        position: Number.isFinite(Number(field?.position)) ? Number(field?.position) : index,
      } satisfies NormalizedCustomField;
    })
    .filter((field): field is NormalizedCustomField => Boolean(field))
    .sort((a, b) => a.position - b.position);
}

function 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}`;
}

function normalizeProductImages(product: MarketplaceProduct) {
  const images = Array.isArray(product.product_images) ? [...product.product_images] : [];
  const filtered = images
    .filter((image) => String(image?.image_url || "").trim())
    .sort((a, b) => {
      const primaryA = a.is_primary ? 0 : 1;
      const primaryB = b.is_primary ? 0 : 1;
      if (primaryA !== primaryB) return primaryA - primaryB;
      return Number(a.sort_order ?? 0) - Number(b.sort_order ?? 0);
    });

  if (!filtered.length && product.image_url) {
    return [{ id: "legacy-image", image_url: product.image_url, is_primary: true }];
  }

  return filtered;
}

export default function MarketplaceProductDetailClient({
  product,
}: MarketplaceProductDetailClientProps) {
  const galleryImages = useMemo(() => normalizeProductImages(product), [product]);
  const defaultImageId = galleryImages.find((image) => image.is_primary)?.id || galleryImages[0]?.id || null;
  const [activeImageId, setActiveImageId] = useState<string | null>(defaultImageId);
  const activeImage = galleryImages.find((image) => image.id === activeImageId) || galleryImages[0] || null;

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

  const [quantity, setQuantity] = useState(minimumQuantity);
  const [quantityInput, setQuantityInput] = useState(formatQuantityValue(minimumQuantity));
  const [widthDigits, setWidthDigits] = useState("");
  const [heightDigits, setHeightDigits] = useState("");
  const [selectedOptions, setSelectedOptions] = useState<Record<string, string[]>>({});
  const [customFieldValues, setCustomFieldValues] = useState<Record<string, string>>({});

  useEffect(() => {
    setQuantity(minimumQuantity);
    setQuantityInput(formatQuantityValue(minimumQuantity));
  }, [minimumQuantity]);

  const hasVariations = Array.isArray(product.product_attributes) && product.product_attributes.length > 0;
  const orderedAttributes = useMemo(() => {
    return (product.product_attributes || [])
      .slice()
      .sort((a, b) => Number(a?.position ?? 0) - Number(b?.position ?? 0));
  }, [product.product_attributes]);

  const requiredOptionsByAttr = useMemo(() => {
    const map: Record<string, string[]> = {};
    orderedAttributes.forEach((attr) => {
      const attrName = String(attr?.name || "").trim();
      if (!attrName) return;
      const required = (attr.options || [])
        .map((option, index) =>
          typeof option === "string"
            ? { label: option, is_required: false, position: index }
            : { ...option, label: String(option?.label || ""), position: option?.position ?? index }
        )
        .filter((option) => option.label && Boolean(option.is_required))
        .map((option) => option.label);
      if (required.length) map[attrName] = required;
    });
    return map;
  }, [orderedAttributes]);

  const effectiveSelectedOptions = useMemo(() => {
    const next: Record<string, string[]> = {};
    orderedAttributes.forEach((attr) => {
      const attrName = String(attr?.name || "").trim();
      if (!attrName) return;
      const required = requiredOptionsByAttr[attrName] || [];
      const userSelected = selectedOptions[attrName] || [];
      if (attr.allow_multiple) {
        const merged = Array.from(new Set([...required, ...userSelected]));
        if (merged.length) next[attrName] = merged;
      } else {
        const chosen = userSelected[0] || required[0];
        if (chosen) next[attrName] = [chosen];
      }
    });
    return next;
  }, [orderedAttributes, requiredOptionsByAttr, selectedOptions]);

  const selectedOptionImageId = useMemo(() => {
    const availableImageIds = new Set(galleryImages.map((image) => image.id));
    for (const attribute of orderedAttributes) {
      const attrName = String(attribute?.name || "").trim();
      const selected = effectiveSelectedOptions[attrName] || [];
      if (!selected.length || !Array.isArray(attribute.options)) continue;
      for (const selectedLabel of selected) {
        const option = attribute.options.find((item) => {
          const label = typeof item === "string" ? item : String(item?.label || "");
          return label === selectedLabel;
        });
        if (!option || typeof option === "string") continue;
        if (option.image_id && availableImageIds.has(option.image_id)) {
          return option.image_id;
        }
      }
    }
    return null;
  }, [effectiveSelectedOptions, galleryImages, orderedAttributes]);

  useEffect(() => {
    if (selectedOptionImageId) {
      setActiveImageId(selectedOptionImageId);
      return;
    }
    setActiveImageId(defaultImageId);
  }, [defaultImageId, selectedOptionImageId]);

  const optionPriceBreakdown = useMemo(() => {
    return orderedAttributes.reduce(
      (acc, attr) => {
        const attrName = String(attr?.name || "").trim();
        const selected = effectiveSelectedOptions[attrName] || [];
        if (!selected.length || !Array.isArray(attr.options)) return acc;
        for (const label of selected) {
          const option = attr.options.find((item) => (typeof item === "string" ? item : String(item?.label || "")) === label);
          if (!option || typeof option === "string") continue;
          const optionPrice = Number(option.price) || 0;
          if (option.price_applies_per_quantity === false) {
            acc.oneTime += optionPrice;
          } else {
            acc.perQuantity += optionPrice;
          }
        }
        return acc;
      },
      { perQuantity: 0, oneTime: 0 }
    );
  }, [effectiveSelectedOptions, orderedAttributes]);

  const trackInventory = product.track_inventory !== false;
  const inventoryScope = product.inventory_scope || "product";
  const inventoryAttributeName = String(product.inventory_attribute_name || "").trim().toLowerCase();

  const selectedOptionEntries = useMemo(() => {
    return orderedAttributes.flatMap((attribute) => {
      const attrName = String(attribute?.name || "").trim();
      if (!attrName) return [];
      const selected = effectiveSelectedOptions[attrName] || [];
      if (!selected.length) return [];
      return selected
        .map((selectedLabel) => {
          const option = (attribute.options || []).find((item) => {
            const label = typeof item === "string" ? item : String(item?.label || "");
            return label === selectedLabel;
          });
          if (!option || typeof option === "string") return null;
          const optionId = typeof option.id === "string" ? option.id : null;
          return {
            option_id: optionId,
            attribute_name: attrName,
            label: String(option.label || ""),
            price: Number(option.price) || 0,
            price_applies_per_quantity: option.price_applies_per_quantity !== false,
            stock: Number.isFinite(Number(option.stock)) ? Number(option.stock) : null,
            affects_stock: inventoryScope === "option" && attrName.trim().toLowerCase() === inventoryAttributeName,
          };
        })
        .filter(Boolean) as Array<{
        option_id: string | null;
        attribute_name: string;
        label: string;
        price: number;
        price_applies_per_quantity: boolean;
        stock: number | null;
        affects_stock: boolean;
      }>;
    });
  }, [effectiveSelectedOptions, inventoryAttributeName, inventoryScope, orderedAttributes]);

  const trackedOptionStocks = selectedOptionEntries
    .filter((entry) => entry.affects_stock && typeof entry.stock === "number")
    .map((entry) => Number(entry.stock));

  const matchedVariant = useMemo(() => {
    if (inventoryScope !== "variant") return null;
    const selectedFlat: Record<string, string> = {};
    for (const [attribute, labels] of Object.entries(effectiveSelectedOptions)) {
      const label = labels[0];
      if (!label) continue;
      selectedFlat[attribute.trim().toLowerCase()] = label.trim().toLowerCase();
    }
    const selectedKeys = Object.keys(selectedFlat).sort();
    if (!selectedKeys.length) return null;
    const variations = Array.isArray(product.product_variations) ? product.product_variations : [];
    for (const variation of variations) {
      const comboRaw = variation.combination || {};
      const combo: Record<string, string> = {};
      for (const [attribute, label] of Object.entries(comboRaw)) {
        combo[attribute.trim().toLowerCase()] = String(label || "").trim().toLowerCase();
      }
      const comboKeys = Object.keys(combo).sort();
      if (comboKeys.length !== selectedKeys.length) continue;
      const same = selectedKeys.every((key) => combo[key] === selectedFlat[key]);
      if (same) return variation;
    }
    return null;
  }, [effectiveSelectedOptions, inventoryScope, product.product_variations]);

  const selectedVariationSignature = useMemo(() => {
    if (matchedVariant?.combination) {
      return normalizeVariationSignature(matchedVariant.combination);
    }
    const selectedFlat: Record<string, string> = {};
    for (const [attribute, labels] of Object.entries(effectiveSelectedOptions)) {
      const label = labels[0];
      if (!label) continue;
      selectedFlat[attribute] = label;
    }
    return normalizeVariationSignature(selectedFlat);
  }, [effectiveSelectedOptions, matchedVariant]);

  const customFieldsConfig = useMemo(
    () => normalizeCustomFieldsConfig(product.custom_fields_config),
    [product.custom_fields_config]
  );

  const alwaysVisibleCustomFields = useMemo(
    () => customFieldsConfig.filter((field) => !field.variation_signature),
    [customFieldsConfig]
  );

  const linkedVisibleCustomFields = useMemo(() => {
    if (!customFieldsConfig.length) return [] as NormalizedCustomField[];
    return customFieldsConfig.filter((field) => {
      if (!field.variation_signature) return false;
      return matchesFieldVariationSignature(field.variation_signature, {
        selectedVariationSignature,
        selectedOptions: effectiveSelectedOptions,
      });
    });
  }, [customFieldsConfig, effectiveSelectedOptions, selectedVariationSignature]);

  const visibleCustomFields = useMemo(
    () => [...alwaysVisibleCustomFields, ...linkedVisibleCustomFields].sort((a, b) => a.position - b.position),
    [alwaysVisibleCustomFields, linkedVisibleCustomFields]
  );

  const missingRequiredCustomFields = useMemo(() => {
    return visibleCustomFields.filter((field) => {
      if (!field.required) return false;
      const value = String(customFieldValues[field.id] || "").trim();
      return !value;
    });
  }, [customFieldValues, visibleCustomFields]);

  const hasValidCustomFields = missingRequiredCustomFields.length === 0;
  const hasTrackedSelection =
    !trackInventory
      ? true
      : inventoryScope === "option"
        ? selectedOptionEntries.some((entry) => entry.affects_stock)
        : inventoryScope === "variant"
          ? matchedVariant !== null
          : true;

  const currentStock =
    !trackInventory
      ? Number.POSITIVE_INFINITY
      : inventoryScope === "option" && trackedOptionStocks.length > 0
        ? Math.min(...trackedOptionStocks)
        : inventoryScope === "variant" && matchedVariant
          ? Number(matchedVariant.stock) || 0
          : Number(product.stock) || 0;

  const normalizedStock = Number.isFinite(Number(currentStock))
    ? Math.max(0, Number(currentStock))
    : Number.POSITIVE_INFINITY;

  const isVariationSelected = hasVariations
    ? orderedAttributes.every((attr) => {
        if (!attr.is_required) return true;
        const attrName = String(attr?.name || "").trim();
        return (effectiveSelectedOptions[attrName] || []).length > 0;
      })
    : true;

  const handleOptionSelect = (attrName: string, option: string, allowMultiple?: boolean, isRequiredOption?: boolean) => {
    setSelectedOptions((prev) => {
      const required = requiredOptionsByAttr[attrName] || [];
      const current = allowMultiple
        ? Array.from(new Set([...required, ...(prev[attrName] || [])]))
        : (prev[attrName]?.[0] ? [prev[attrName][0]] : (required[0] ? [required[0]] : []));
      if (allowMultiple) {
        const exists = current.includes(option);
        if (exists) {
          if (isRequiredOption) return prev;
          const next = (prev[attrName] || []).filter((value) => value !== option);
          return { ...prev, [attrName]: next };
        }
        return { ...prev, [attrName]: [...(prev[attrName] || []), option] };
      }
      const isCurrentlySelected = current[0] === option;
      if (isCurrentlySelected) {
        if (isRequiredOption) return prev;
        const next = { ...prev };
        delete next[attrName];
        return next;
      }
      return { ...prev, [attrName]: [option] };
    });
  };

  const unitType = product.unit_type || "unit";
  const isSquareMeter = unitType === "square_meter";
  const usesAllowedQuantitySteps = !isSquareMeter && allowedQuantities.length > 0;

  const quantityInputDigits = quantityInput.replace(/\D/g, "");
  const manualInputQuantity =
    !usesAllowedQuantitySteps && quantityInputDigits
      ? Math.max(minimumQuantity, Number.parseInt(quantityInputDigits, 10))
      : null;
  const quantityForValidation =
    usesAllowedQuantitySteps || manualInputQuantity === null ? quantity : manualInputQuantity;

  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 getQuantityCheck = (nextQuantity: number) => {
    const effectiveQuantity = calculateEffectiveQuantity({
      quantity: nextQuantity,
      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,
    });
  };

  const hasStockForQuantity = (nextQuantity: number) => {
    if (!trackInventory) return true;
    if (!Number.isFinite(normalizedStock)) return true;
    const nextEffectiveQuantity = calculateEffectiveQuantity({
      quantity: nextQuantity,
      unit_type: unitType,
      width_m: isSquareMeter ? parsedWidth : undefined,
      height_m: isSquareMeter ? parsedHeight : undefined,
    });
    return nextEffectiveQuantity <= normalizedStock + 0.000001;
  };

  const quantityCheck = getQuantityCheck(quantityForValidation);

  const nextQuantityDown = usesAllowedQuantitySteps
    ? resolveAdjacentAllowedQuantity(allowedQuantities, quantity, -1)
    : Math.max(minimumQuantity, quantity - 1);
  const nextQuantityUp = usesAllowedQuantitySteps
    ? resolveAdjacentAllowedQuantity(allowedQuantities, quantity, 1)
    : quantity + 1;

  const canDecreaseQuantity =
    nextQuantityDown !== null &&
    nextQuantityDown > 0 &&
    (usesAllowedQuantitySteps ? getQuantityCheck(nextQuantityDown).isValid : quantity > minimumQuantity);
  const canIncreaseQuantity =
    nextQuantityUp !== null &&
    getQuantityCheck(nextQuantityUp).isValid &&
    hasStockForQuantity(nextQuantityUp);

  const handleQuantityChange = (delta: number) => {
    if (usesAllowedQuantitySteps) {
      const direction: -1 | 1 = delta < 0 ? -1 : 1;
      const nextAllowed = resolveAdjacentAllowedQuantity(allowedQuantities, quantity, direction);
      if (nextAllowed === null) return;
      if (!getQuantityCheck(nextAllowed).isValid) return;
      if (!hasStockForQuantity(nextAllowed)) return;
      setQuantity(nextAllowed);
      setQuantityInput(formatQuantityValue(nextAllowed));
      return;
    }

    const next = Math.max(minimumQuantity, quantity + delta);
    if (!getQuantityCheck(next).isValid) return;
    if (!hasStockForQuantity(next)) return;
    setQuantity(next);
    setQuantityInput(String(next));
  };

  const handleQuantityInputChange = (rawValue: string) => {
    if (usesAllowedQuantitySteps) return;
    const digitsOnly = rawValue.replace(/\D/g, "");
    setQuantityInput(digitsOnly);
    if (!digitsOnly) return;
    const next = Number.parseInt(digitsOnly, 10);
    if (Number.isFinite(next) && getQuantityCheck(next).isValid && hasStockForQuantity(next)) {
      setQuantity(Math.max(minimumQuantity, next));
    }
  };

  const normalizeQuantityInput = () => {
    if (usesAllowedQuantitySteps) {
      setQuantityInput(formatQuantityValue(quantity));
      return;
    }
    const digitsOnly = quantityInput.replace(/\D/g, "");
    if (!digitsOnly) {
      setQuantityInput(String(quantity));
      return;
    }
    const normalized = Math.max(minimumQuantity, Number.parseInt(digitsOnly, 10));
    if (!getQuantityCheck(normalized).isValid || !hasStockForQuantity(normalized)) {
      setQuantityInput(String(normalized));
      return;
    }
    setQuantity(normalized);
    setQuantityInput(String(normalized));
  };

  const effectiveQty = calculateEffectiveQuantity({
    quantity: quantityForValidation,
    unit_type: unitType,
    width_m: isSquareMeter ? parsedWidth : undefined,
    height_m: isSquareMeter ? parsedHeight : undefined,
  });
  const safeEffectiveQty = effectiveQty > 0 ? effectiveQty : 1;
  const optionsPrice = optionPriceBreakdown.perQuantity + optionPriceBreakdown.oneTime / safeEffectiveQty;
  const basePrice = Number(product.price) || 0;
  const tierResolution = resolveTierPrice(basePrice, effectiveQty, product.product_price_tiers || []);
  const resolvedUnitPrice = product.use_variation_price_only
    ? Math.max(0, optionsPrice)
    : Math.max(0, tierResolution.unitPrice + optionsPrice);
  const totalPrice = product.price_on_request
    ? null
    : isSquareMeter
      ? isValidDims
        ? resolvedUnitPrice * effectiveQty
        : 0
      : resolvedUnitPrice * effectiveQty;
  const exceedsStock = trackInventory && Number.isFinite(normalizedStock) && effectiveQty > normalizedStock + 0.000001;
  const areaEach = isSquareMeter && isValidDims ? parsedWidth * parsedHeight : 0;
  const totalArea = isSquareMeter && isValidDims ? areaEach * quantityForValidation : 0;

  const displayPrice = getMarketplaceDisplayPrice(product);
  const priceTitle = product.price_on_request
    ? "Preço"
    : isSquareMeter
      ? "Preço sob medida"
      : displayPrice.startsAt
        ? "A partir de"
        : "Preço unitário";

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

  const quantityPricingRows = useMemo(() => {
    const activePriceTiers = (product.product_price_tiers || []).filter((tier) => {
      if (tier.active === false) return false;
      const minQty = Number(tier.min_qty);
      const unitPrice = Number(tier.unit_price);
      return Number.isFinite(minQty) && minQty > 0 && Number.isFinite(unitPrice) && unitPrice > 0;
    });
    if (isSquareMeter || product.price_on_request || activePriceTiers.length === 0) return [];

    const candidateQuantities = allowedQuantities.length > 0
      ? allowedQuantities
      : Array.from(
          new Set(
            [minimumQuantity, ...activePriceTiers.map((tier) => Number(tier.min_qty))]
              .filter((value) => Number.isFinite(value) && value > 0)
              .map((value) => Number(value.toFixed(3)))
          )
        ).sort((a, b) => a - b);

    return candidateQuantities.map((qty) => {
      const rowEffectiveQuantity = calculateEffectiveQuantity({
        quantity: qty,
        unit_type: unitType,
      });
      const safeRowEffectiveQty = rowEffectiveQuantity > 0 ? rowEffectiveQuantity : 1;
      const rowOptionUnitAdjustment =
        optionPriceBreakdown.perQuantity + optionPriceBreakdown.oneTime / safeRowEffectiveQty;
      const rowTierResolution = resolveTierPrice(basePrice, rowEffectiveQuantity, product.product_price_tiers || []);
      const unitPrice = product.use_variation_price_only
        ? Math.max(0, rowOptionUnitAdjustment)
        : Math.max(0, rowTierResolution.unitPrice + rowOptionUnitAdjustment);
      return {
        quantity: qty,
        unitPrice,
        totalPrice: unitPrice * rowEffectiveQuantity,
        isSelected: Math.abs(quantity - qty) <= 0.000001,
        disabled: !getQuantityCheck(qty).isValid || !hasStockForQuantity(qty),
      };
    });
  }, [
    allowedQuantities,
    basePrice,
    getQuantityCheck,
    hasStockForQuantity,
    isSquareMeter,
    minimumQuantity,
    optionPriceBreakdown.oneTime,
    optionPriceBreakdown.perQuantity,
    product.price_on_request,
    product.product_price_tiers,
    product.use_variation_price_only,
    quantity,
    unitType,
  ]);

  const storeProductUrl = useMemo(() => {
    const baseUrl = String(product.store?.publicUrl || "").trim();
    if (!baseUrl) return "";
    return `${baseUrl.replace(/\/$/, "")}/p/${product.id}`;
  }, [product.id, product.store?.publicUrl]);

  const ctaDisabled =
    (trackInventory && normalizedStock <= 0) ||
    exceedsStock ||
    (isSquareMeter && !isValidDims) ||
    !isVariationSelected ||
    !quantityCheck.isValid ||
    !hasTrackedSelection ||
    !hasValidCustomFields ||
    !storeProductUrl;

  const ctaLabel = !trackInventory || normalizedStock > 0
    ? !isVariationSelected
      ? "Selecione as opções"
      : !hasTrackedSelection
        ? "Selecione uma opção"
        : !hasValidCustomFields
          ? "Preencha os campos"
          : isSquareMeter && !isValidDims
            ? "Informe as medidas"
            : exceedsStock
              ? "Quantidade acima do estoque"
              : "Comprar na loja"
    : "Indisponível";

  const description = String(product.description || "").trim();
  const hasHtmlDescription = /<\/?[a-z][\s\S]*>/i.test(description);

  return (
    <div className="flex flex-col lg:flex-row gap-12">
      <div className="flex-1">
        <div className="aspect-square rounded-3xl overflow-hidden bg-gray-100 border border-gray-200">
          {activeImage ? (
            <img
              src={activeImage.image_url}
              alt={product.name}
              className="w-full h-full object-cover"
            />
          ) : (
            <div className="w-full h-full flex items-center justify-center text-gray-400">Sem imagem</div>
          )}
        </div>

        {galleryImages.length > 1 && (
          <div className="flex gap-4 mt-4 overflow-x-auto pb-2">
            {galleryImages.map((image) => {
              const isActive = image.id === activeImage?.id;
              return (
                <button
                  key={image.id}
                  type="button"
                  onClick={() => setActiveImageId(image.id)}
                  className={`w-20 h-20 rounded-xl overflow-hidden border-2 flex-shrink-0 bg-gray-100 transition-colors ${
                    isActive ? "border-violet-600" : "border-transparent hover:border-violet-300"
                  }`}
                >
                  <img src={image.image_url} alt="" className="w-full h-full object-cover" />
                </button>
              );
            })}
          </div>
        )}
      </div>

      <div className="flex-1 flex flex-col">
        <div className="mb-2">
          <span className="inline-block px-3 py-1 bg-violet-100 text-violet-800 text-xs font-bold rounded-full uppercase tracking-wider">
            {product.category || "Produto"}
          </span>
        </div>

        <h1 className="text-3xl lg:text-4xl font-extrabold text-gray-900 mb-4">
          {product.name}
        </h1>

        <div className="flex items-center gap-3 mb-8 pb-8 border-b border-gray-100">
          <Link href={`/lojas/${product.store?.slug || ""}`} className="flex items-center gap-3 hover:opacity-80 transition-opacity">
            <div className="w-10 h-10 rounded-full bg-gray-100 border border-gray-200 overflow-hidden flex items-center justify-center flex-shrink-0">
              {product.store?.logoUrl ? (
                <img src={product.store.logoUrl} alt="" className="w-full h-full object-cover" />
              ) : (
                <Store className="w-5 h-5 text-gray-400" />
              )}
            </div>
            <div>
              <div className="text-sm font-bold text-gray-900 leading-tight">
                {product.store?.name || "Loja Parceira"}
              </div>
              <div className="text-xs text-gray-500">
                Ver perfil da loja
              </div>
            </div>
          </Link>
        </div>

        <div className="mb-8">
          <div className="text-sm text-gray-500 mb-1">{priceTitle}</div>
          <div className="text-4xl font-extrabold text-gray-900">
            {isSquareMeter && !product.price_on_request
              ? isValidDims
                ? formatMoney(totalPrice || 0)
                : "Informe as medidas"
              : displayPrice.label}
          </div>
          {isSquareMeter && !product.price_on_request && (
            <div className="text-sm text-gray-500 mt-2">
              {isValidDims ? `${totalArea.toFixed(2)} m² no total` : "Preencha largura e altura para calcular"}
            </div>
          )}
        </div>

        <div className="space-y-6">
          {hasVariations && (
            <div className="space-y-4">
              {orderedAttributes.map((attr) => {
                const attrName = String(attr?.name || "").trim();
                if (!attrName) return null;
                return (
                  <div key={String(attr.id || attrName)} className="space-y-2">
                    <div className="flex flex-wrap items-center gap-2">
                      <span className="text-[11px] font-semibold uppercase tracking-[0.08em] text-zinc-500">
                        {attrName}
                      </span>
                      {attr.allow_multiple && (
                        <span className="rounded-full border border-zinc-200 px-2 py-0.5 text-[10px] font-medium text-zinc-500">
                          Múltipla escolha
                        </span>
                      )}
                      {attr.is_required && (
                        <span className="rounded-full border border-violet-200 px-2 py-0.5 text-[10px] font-medium text-violet-700">
                          Obrigatório
                        </span>
                      )}
                    </div>
                    <div className="flex flex-wrap gap-2">
                      {(attr.options || [])
                        .map((optionOrString, index) => {
                          if (typeof optionOrString === "string") {
                            return { label: optionOrString, price: 0, is_required: false, position: index };
                          }
                          return {
                            ...optionOrString,
                            label: String(optionOrString?.label || ""),
                            price: Number(optionOrString?.price) || 0,
                            position: optionOrString?.position ?? index,
                          };
                        })
                        .filter((option) => option.label)
                        .sort((a, b) => Number(a.position ?? 0) - Number(b.position ?? 0))
                        .map((option) => {
                          const optionLabel = option.label;
                          const optionPrice = Number(option.price) || 0;
                          const isSelected = (effectiveSelectedOptions[attrName] || []).includes(optionLabel);
                          const isRequiredOption = Boolean(option.is_required);
                          return (
                            <button
                              key={optionLabel}
                              type="button"
                              onClick={() => handleOptionSelect(attrName, optionLabel, Boolean(attr.allow_multiple), isRequiredOption)}
                              className={`flex items-center gap-2 rounded-xl border px-4 py-2.5 text-sm font-medium transition-all ${
                                isSelected
                                  ? "border-violet-600 bg-violet-600 text-white"
                                  : "border-zinc-200 bg-white text-zinc-700 hover:border-zinc-300 hover:bg-zinc-50"
                              }`}
                            >
                              <span>{optionLabel}</span>
                              {isRequiredOption && (
                                <span className={`inline-flex h-4 w-4 items-center justify-center rounded-full text-[10px] font-bold ${
                                  isSelected ? "bg-white/90 text-gray-800" : "bg-violet-600 text-white"
                                }`}>
                                  *
                                </span>
                              )}
                              {optionPrice > 0 && (
                                <span className={`rounded px-1.5 py-0.5 text-[11px] ${
                                  isSelected ? "bg-white/20" : "bg-zinc-100 text-zinc-500"
                                }`}>
                                  +{formatMoney(optionPrice)}
                                </span>
                              )}
                            </button>
                          );
                        })}
                    </div>
                    {linkedVisibleCustomFields
                      .filter((field) => {
                        const signature = normalizeText(field.variation_signature || "");
                        if (!signature.startsWith("option::")) return false;
                        const selected = effectiveSelectedOptions[attrName] || [];
                        return selected.some(
                          (selectedOptionLabel) =>
                            signature === normalizeText(buildOptionSignature(attrName, selectedOptionLabel))
                        );
                      })
                      .map((field) => (
                        <div key={field.id} className="rounded-2xl border border-violet-200 bg-violet-50/70 p-4 space-y-2">
                          <label className="text-sm font-semibold text-gray-800">
                            {field.title}
                            {field.required ? <span className="text-rose-600"> *</span> : null}
                          </label>
                          {field.field_type === "textarea" ? (
                            <textarea
                              value={customFieldValues[field.id] || ""}
                              onChange={(e) => setCustomFieldValues((prev) => ({ ...prev, [field.id]: e.target.value }))}
                              placeholder={field.placeholder}
                              rows={3}
                              className="w-full rounded-xl border border-violet-200 bg-white px-3 py-2.5 text-sm text-slate-800 focus:outline-none focus:ring-2 focus:ring-violet-200"
                            />
                          ) : (
                            <input
                              type="text"
                              value={customFieldValues[field.id] || ""}
                              onChange={(e) => setCustomFieldValues((prev) => ({ ...prev, [field.id]: e.target.value }))}
                              placeholder={field.placeholder}
                              className="w-full rounded-xl border border-violet-200 bg-white px-3 py-2.5 text-sm text-slate-800 focus:outline-none focus:ring-2 focus:ring-violet-200"
                            />
                          )}
                        </div>
                      ))}
                  </div>
                );
              })}
            </div>
          )}

          {linkedVisibleCustomFields
            .filter((field) => !normalizeText(field.variation_signature || "").startsWith("option::"))
            .map((field) => (
              <div key={field.id} className="rounded-2xl border border-violet-200 bg-violet-50/70 p-4 space-y-2">
                <label className="text-sm font-semibold text-gray-800">
                  {field.title}
                  {field.required ? <span className="text-rose-600"> *</span> : null}
                </label>
                {field.field_type === "textarea" ? (
                  <textarea
                    value={customFieldValues[field.id] || ""}
                    onChange={(e) => setCustomFieldValues((prev) => ({ ...prev, [field.id]: e.target.value }))}
                    placeholder={field.placeholder}
                    rows={3}
                    className="w-full rounded-xl border border-violet-200 bg-white px-3 py-2.5 text-sm text-slate-800 focus:outline-none focus:ring-2 focus:ring-violet-200"
                  />
                ) : (
                  <input
                    type={field.field_type === "number" ? "number" : "text"}
                    value={customFieldValues[field.id] || ""}
                    onChange={(e) => setCustomFieldValues((prev) => ({ ...prev, [field.id]: e.target.value }))}
                    placeholder={field.placeholder}
                    className="w-full rounded-xl border border-violet-200 bg-white px-3 py-2.5 text-sm text-slate-800 focus:outline-none focus:ring-2 focus:ring-violet-200"
                  />
                )}
              </div>
            ))}

          {alwaysVisibleCustomFields.length > 0 && (
            <div className="space-y-4">
              {alwaysVisibleCustomFields.map((field) => (
                <div key={field.id} className="space-y-2">
                  <label className="text-sm font-semibold text-gray-800">
                    {field.title}
                    {field.required ? <span className="text-rose-600"> *</span> : null}
                  </label>
                  {field.field_type === "textarea" ? (
                    <textarea
                      value={customFieldValues[field.id] || ""}
                      onChange={(e) => setCustomFieldValues((prev) => ({ ...prev, [field.id]: e.target.value }))}
                      placeholder={field.placeholder}
                      rows={3}
                      className="w-full rounded-xl border border-gray-200 bg-white px-3 py-2.5 text-sm text-slate-800 focus:outline-none focus:ring-2 focus:ring-violet-200"
                    />
                  ) : (
                    <input
                      type={field.field_type === "number" ? "number" : "text"}
                      value={customFieldValues[field.id] || ""}
                      onChange={(e) => setCustomFieldValues((prev) => ({ ...prev, [field.id]: e.target.value }))}
                      placeholder={field.placeholder}
                      className="w-full rounded-xl border border-gray-200 bg-white px-3 py-2.5 text-sm text-slate-800 focus:outline-none focus:ring-2 focus:ring-violet-200"
                    />
                  )}
                </div>
              ))}
            </div>
          )}

          {isSquareMeter && (
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-1">
                <span className="text-[11px] font-semibold uppercase tracking-[0.08em] text-zinc-500">Largura (m)</span>
                <input
                  inputMode="numeric"
                  value={widthM}
                  onKeyDown={(event) => {
                    if (event.key !== "Backspace") return;
                    const hasSelection = event.currentTarget.selectionStart !== event.currentTarget.selectionEnd;
                    if (hasSelection) return;
                    event.preventDefault();
                    setWidthDigits((value) => value.slice(0, -1));
                  }}
                  onChange={(event) => setWidthDigits(event.target.value.replace(/\D/g, ""))}
                  className="w-full rounded-xl border border-zinc-200 px-3 py-2.5 focus:outline-none focus:ring-2 focus:ring-violet-200"
                  placeholder="Ex: 1,20"
                />
              </div>
              <div className="space-y-1">
                <span className="text-[11px] font-semibold uppercase tracking-[0.08em] text-zinc-500">Altura (m)</span>
                <input
                  inputMode="numeric"
                  value={heightM}
                  onKeyDown={(event) => {
                    if (event.key !== "Backspace") return;
                    const hasSelection = event.currentTarget.selectionStart !== event.currentTarget.selectionEnd;
                    if (hasSelection) return;
                    event.preventDefault();
                    setHeightDigits((value) => value.slice(0, -1));
                  }}
                  onChange={(event) => setHeightDigits(event.target.value.replace(/\D/g, ""))}
                  className="w-full rounded-xl border border-zinc-200 px-3 py-2.5 focus:outline-none focus:ring-2 focus:ring-violet-200"
                  placeholder="Ex: 0,80"
                />
              </div>
            </div>
          )}

          {quantityPricingRows.length > 0 && (
            <div className="space-y-2">
              <span className="text-sm font-semibold text-gray-900">Escolha a quantidade</span>
              <div className="max-h-72 overflow-auto rounded-2xl border border-violet-200 bg-white">
                <div className="sticky top-0 z-10 grid grid-cols-[1.2fr_1fr_1fr] border-b border-violet-200 bg-violet-50">
                  <span className="px-3 py-2 text-xs font-bold uppercase tracking-wide text-violet-900">Quantidade</span>
                  <span className="px-3 py-2 text-xs font-bold uppercase tracking-wide text-violet-900">Valor por unidade</span>
                  <span className="px-3 py-2 text-xs font-bold uppercase tracking-wide text-violet-900">Valor total</span>
                </div>
                {quantityPricingRows.map((row) => (
                  <label
                    key={`qty-row-${row.quantity}`}
                    className={`grid grid-cols-[1.2fr_1fr_1fr] items-center border-b border-violet-100 last:border-b-0 ${
                      row.disabled ? "cursor-not-allowed text-gray-400" : "cursor-pointer text-gray-800 hover:bg-violet-50/60"
                    } ${row.isSelected ? "bg-violet-100/80" : ""}`}
                  >
                    <span className="flex items-center gap-2 px-3 py-3">
                      <input
                        type="radio"
                        name={`qty-tier-${product.id}`}
                        checked={row.isSelected}
                        onChange={() => {
                          if (row.disabled) return;
                          setQuantity(row.quantity);
                          setQuantityInput(formatQuantityValue(row.quantity));
                        }}
                        disabled={row.disabled}
                        className="h-4 w-4"
                      />
                      <span className="text-sm font-semibold">{formatTierThreshold(row.quantity, unitType)}</span>
                    </span>
                    <span className="px-3 py-3 text-sm font-medium">{formatMoney(row.unitPrice)}</span>
                    <span className="px-3 py-3 text-sm font-semibold">{formatMoney(row.totalPrice)}</span>
                  </label>
                ))}
              </div>
            </div>
          )}

          <div className="grid gap-5 border-t border-zinc-200 pt-5 sm:grid-cols-[auto_1fr] sm:items-end">
            <div className="flex flex-col items-start gap-2">
              <div className="flex items-center rounded-xl border border-zinc-200 bg-white">
                <button
                  type="button"
                  onClick={() => handleQuantityChange(-1)}
                  disabled={!canDecreaseQuantity}
                  className="flex h-11 w-11 items-center justify-center text-zinc-500 transition-colors hover:bg-zinc-50 disabled:opacity-50"
                >
                  -
                </button>
                <input
                  type="text"
                  inputMode="numeric"
                  value={usesAllowedQuantitySteps ? formatQuantityValue(quantity) : quantityInput}
                  onChange={(event) => handleQuantityInputChange(event.target.value)}
                  onFocus={(event) => event.currentTarget.select()}
                  onBlur={normalizeQuantityInput}
                  readOnly={usesAllowedQuantitySteps}
                  className={`h-11 w-16 text-center font-medium text-zinc-900 outline-none ${
                    usesAllowedQuantitySteps ? "cursor-not-allowed bg-zinc-50 text-zinc-500" : ""
                  }`}
                  aria-label="Quantidade"
                />
                <button
                  type="button"
                  onClick={() => handleQuantityChange(1)}
                  disabled={!canIncreaseQuantity}
                  className="flex h-11 w-11 items-center justify-center text-zinc-500 transition-colors hover:bg-zinc-50 disabled:opacity-50"
                >
                  +
                </button>
              </div>
              {trackInventory && Number.isFinite(normalizedStock) && (
                <span className={`inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-semibold ${
                  exceedsStock ? "border-red-300 text-red-600" : "border-gray-300 text-gray-600"
                }`}>
                  Maximo disponivel: {formatQuantityValue(normalizedStock)}.
                </span>
              )}
            </div>

            <div className="flex flex-col items-start sm:items-end">
              <span className="text-[11px] font-semibold uppercase tracking-[0.08em] text-zinc-500">
                {isSquareMeter ? "Total estimado (m²)" : "Total estimado"}
              </span>
              <span className="text-[1.65rem] font-semibold tracking-[-0.04em] text-violet-700">
                {product.price_on_request ? "Sob consulta" : formatMoney(totalPrice || 0)}
              </span>
              {quantityRuleMessage && (
                <span className="mt-1 inline-flex items-center rounded-full border border-amber-300 px-2.5 py-1 text-[11px] font-semibold text-amber-700">
                  {quantityRuleMessage}
                </span>
              )}
            </div>
          </div>

          <div className="rounded-2xl border border-violet-200 bg-violet-50/60 p-4 text-sm text-violet-900">
            O marketplace agora replica as regras de configuração deste produto. Para concluir a compra, siga para a loja do vendedor com as opções selecionadas.
          </div>

          <div className="flex flex-col gap-3">
            {ctaDisabled ? (
              <button
                type="button"
                disabled
                className="flex w-full items-center justify-center gap-3 rounded-xl bg-violet-300 px-6 py-4 text-base font-semibold text-white opacity-70"
              >
                <ShoppingCart className="w-5 h-5" />
                {ctaLabel}
              </button>
            ) : (
              <a
                href={storeProductUrl}
                target="_blank"
                rel="noopener noreferrer"
                className="flex w-full items-center justify-center gap-3 rounded-xl bg-violet-600 px-6 py-4 text-base font-semibold text-white transition-all hover:bg-violet-700"
              >
                <ExternalLink className="w-5 h-5" />
                {ctaLabel}
              </a>
            )}
            {product.store?.publicUrl ? (
              <a
                href={product.store.publicUrl}
                target="_blank"
                rel="noopener noreferrer"
                className="flex w-full items-center justify-center gap-2 rounded-xl border border-gray-200 px-6 py-3.5 font-semibold text-zinc-700 transition-all hover:border-zinc-300 hover:bg-zinc-50"
              >
                <Store className="w-5 h-5" />
                Visitar loja
              </a>
            ) : null}
            {product.store?.publicUrl ? (
              <a
                href={storeProductUrl || product.store.publicUrl}
                target="_blank"
                rel="noopener noreferrer"
                className="flex w-full items-center justify-center gap-2 rounded-xl border border-gray-200 px-6 py-3.5 font-semibold text-zinc-700 transition-all hover:border-zinc-300 hover:bg-zinc-50"
              >
                <MessageCircle className="w-5 h-5" />
                Abrir produto na loja
              </a>
            ) : null}
          </div>
        </div>

        {description ? (
          <section className="mt-10 border-t border-gray-100 pt-8">
            <h2 className="text-xl font-bold text-gray-900 mb-4">Detalhes do produto</h2>
            <div className="prose prose-sm max-w-none text-gray-700">
              {hasHtmlDescription ? (
                <div dangerouslySetInnerHTML={{ __html: description }} />
              ) : (
                <p>{description}</p>
              )}
            </div>
          </section>
        ) : null}
      </div>
    </div>
  );
}
