"use client";

import { Dialog, Transition } from "@headlessui/react";
import { Fragment, useState, useMemo, useEffect } from "react";
import Image from "next/image";
import { X, AlertCircle } from "lucide-react";
import { getAccessibleAccent, getReadableTextColor } from "@/lib/color-contrast";
import {
  calculateEffectiveQuantity,
  checkSaleQuantityLimits,
  resolveTierPrice,
} from "@/lib/price-tiers";

interface ComboConfigModalProps {
  isOpen: boolean;
  onClose: () => void;
  combo: any;
  productData: any;
  primaryColor: string;
  onConfirm: (quantity: number, configuration: any) => void;
}

export default function ComboConfigModal({
  isOpen,
  onClose,
  combo,
  productData,
  primaryColor,
  onConfirm,
}: ComboConfigModalProps) {
  const [quantity, setQuantity] = useState(1);
  const [widthStr, setWidthStr] = useState("");
  const [heightStr, setHeightStr] = useState("");
  const [selectedOptions, setSelectedOptions] = useState<Record<string, string>>({});
  const [error, setError] = useState("");

  // Reset state when modal opens
  useEffect(() => {
    if (isOpen) {
      // eslint-disable-next-line react-hooks/set-state-in-effect
      setQuantity(1);
      setWidthStr("");
      setHeightStr("");
      setSelectedOptions({});
      setError("");
    }
  }, [isOpen, productData]);

  // Initialize minimum quantity based on product settings
  useEffect(() => {
    if (isOpen && productData) {
      let initialQty = 1;
      const allowed = Array.isArray(productData.allowed_sale_quantities) ? productData.allowed_sale_quantities.map(Number).filter((n: number) => !isNaN(n) && n > 0).sort((a: number, b: number) => a - b) : [];
      if (productData.allowed_sale_qty_enabled && allowed.length > 0) {
        initialQty = allowed[0];
      } else if (productData.min_sale_qty_enabled && typeof productData.min_sale_qty === "number" && productData.min_sale_qty > 0) {
        initialQty = productData.min_sale_qty;
      }
      // eslint-disable-next-line react-hooks/set-state-in-effect
      setQuantity(initialQty);
    }
  }, [isOpen, productData]);

  // Calculate effective quantity for validation and pricing
  const effectiveQty = useMemo(() => {
    if (!productData) return quantity;
    return calculateEffectiveQuantity({
      quantity,
      unit_type: productData.unit_type,
      width_m: (productData.unit_type === "square_meter" || productData.unit_type === "linear_meter") ? parseFloat(widthStr.replace(",", ".")) : undefined,
      height_m: productData.unit_type === "square_meter" ? parseFloat(heightStr.replace(",", ".")) : undefined,
    });
  }, [quantity, productData, widthStr, heightStr]);

  // Quantity Limits Check
  const quantityCheck = useMemo(() => {
    if (!productData) return { isValid: true, isBelowMin: false, isAboveMax: false, isNotAllowedValue: false, minQty: null, maxQty: null, allowedQuantities: [] };
    return checkSaleQuantityLimits({
      min_sale_qty_enabled: productData.min_sale_qty_enabled,
      min_sale_qty: productData.min_sale_qty,
      max_sale_qty_enabled: productData.max_sale_qty_enabled,
      max_sale_qty: productData.max_sale_qty,
      allowed_sale_qty_enabled: productData.allowed_sale_qty_enabled,
      allowed_sale_quantities: productData.allowed_sale_quantities,
      effectiveQuantity: effectiveQty,
    });
  }, [productData, effectiveQty]);

  const isSquareMeter =
    productData?.unit_type === "square_meter" || productData?.unit_type === "linear_meter";
  const hasVariations =
    Array.isArray(productData?.product_attributes) && productData.product_attributes.length > 0;
  
  const parsedWidth = parseFloat(widthStr.replace(",", "."));
  const parsedHeight = parseFloat(heightStr.replace(",", "."));
  const isValidDims = isSquareMeter
    ? (productData?.unit_type === "square_meter" ? (parsedWidth > 0 && parsedHeight > 0) : parsedWidth > 0)
    : true;

  // Price resolution (including tiers)
  const resolvedPriceInfo = useMemo(() => {
    if (!productData) return { unitPrice: 0, totalPrice: 0, hasTierApplied: false };
    let perQuantityAdjustment = 0;
    let oneTimeAdjustment = 0;
    if (hasVariations) {
      productData.product_attributes.forEach((attr: any) => {
        const selectedLabel = selectedOptions[attr.name];
        if (selectedLabel && Array.isArray(attr.options)) {
          const opt = attr.options.find((o: any) => (typeof o === 'string' ? o : o.label) === selectedLabel);
          if (opt && typeof opt !== 'string' && opt.price) {
            if (opt.price_applies_per_quantity === false) {
              oneTimeAdjustment += Number(opt.price);
            } else {
              perQuantityAdjustment += Number(opt.price);
            }
          }
        }
      });
    }

    const safeEffectiveQty = effectiveQty > 0 ? effectiveQty : 1;
    const optionsUnitAdjustment = perQuantityAdjustment + oneTimeAdjustment / safeEffectiveQty;
    const tierResolution = resolveTierPrice(Number(productData.price) || 0, effectiveQty, productData.product_price_tiers || []);

    let finalUnitPrice = productData.use_variation_price_only
      ? Math.max(0, optionsUnitAdjustment)
      : Math.max(0, tierResolution.unitPrice + optionsUnitAdjustment);
    if (combo && combo.discount_type === "percentage") {
      finalUnitPrice = finalUnitPrice * (1 - combo.discount_value / 100);
    } else if (combo && combo.discount_type === "fixed") {
      finalUnitPrice = Math.max(0, finalUnitPrice - combo.discount_value);
    }

    return {
      unitPrice: finalUnitPrice,
      totalPrice: finalUnitPrice * effectiveQty,
      hasTierApplied: !!tierResolution.tier
    };
  }, [productData, selectedOptions, effectiveQty, combo, hasVariations]);

  if (!isOpen || !combo || !productData) return null;


  /* O texto fica em cima do botão pintado com a cor da marca: escolhe preto
     ou branco pelo contraste com ela (o cálculo antigo comparava a cor da
     marca com o fundo branco e devolvia a própria cor, texto invisível). */
  const buttonTextColor = getReadableTextColor(primaryColor, {
    dark: "#111827",
    light: "#FFFFFF",
  });

  /*
    As variações que o cliente escolhe aqui dentro. Fora ficam as que o
    lojista escondeu da loja — o combo é vitrine igual à página do produto, e
    o que não se mostra ali não pode reaparecer aqui.
  */
  const atributosDoCombo = Array.isArray(productData?.product_attributes)
    ? productData.product_attributes.filter((attr: { show_in_store?: boolean | null }) => attr?.show_in_store !== false)
    : [];

  const handleConfirm = () => {
    setError("");

    // Validate Dimensions
    if (isSquareMeter && !isValidDims) {
      setError("Por favor, preencha as medidas corretamente.");
      return;
    }

    // Validate Variations
    if (hasVariations) {
      const requiredAttributes = atributosDoCombo.filter((attr: any) => attributeIsRequired(attr));
      for (const attr of requiredAttributes) {
        if (!selectedOptions[attr.name]) {
          setError(`Selecione uma opção para: ${attr.name}`);
          return;
        }
      }
    }

    // Validate Quantity Rules
    if (!quantityCheck.isValid) {
      if (quantityCheck.isBelowMin) {
        setError(`Quantidade mínima para este produto é ${quantityCheck.minQty}.`);
      } else if (quantityCheck.isAboveMax) {
        setError(`Quantidade máxima para este produto é ${quantityCheck.maxQty}.`);
      } else if (quantityCheck.isNotAllowedValue) {
        setError(`Quantidade não permitida. Opções: ${quantityCheck.allowedQuantities.join(", ")}`);
      } else {
        setError("Quantidade inválida para as regras deste produto.");
      }
      return;
    }

    // Build configuration object
    const configuration: any = {
      unit_type: productData.unit_type,
    };

    if (isSquareMeter) {
      configuration.width_m = parsedWidth;
      configuration.height_m = productData.unit_type === "square_meter" ? parsedHeight : 1;
    }

    if (hasVariations) {
      const descParts = Object.entries(selectedOptions).map(([k, v]) => `${k}: ${v}`);
      configuration.variation = {
        id: "combo-variation",
        description: descParts.join(" / "),
        selected_options: {
          options: Object.entries(selectedOptions).map(([k, v]) => ({
            attribute_name: k,
            label: v,
            price:
              Number(
                productData.product_attributes
                  ?.find((attr: any) => attr.name === k)
                  ?.options?.find((opt: any) => (typeof opt === "string" ? opt === v : opt.label === v) && typeof opt !== "string")
                  ?.price
              ) || 0,
            price_applies_per_quantity:
              productData.product_attributes
                ?.find((attr: any) => attr.name === k)
                ?.options?.find((opt: any) => (typeof opt === "string" ? opt === v : opt.label === v) && typeof opt !== "string")
                ?.price_applies_per_quantity !== false,
          }))
        }
      };
    }

    onConfirm(quantity, { ...configuration, resolvedUnitPrice: resolvedPriceInfo.unitPrice });
  };

  function attributeIsRequired(attr: any) {
    if (attr.is_required !== undefined) return attr.is_required;
    return true; // default to true if not specified
  }

  const formatMoney = (val: number) =>
    new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(val);

  return (
    <Transition appear show={isOpen} as={Fragment}>
      <Dialog as="div" className="relative z-50" onClose={onClose}>
        <Transition.Child
          as={Fragment}
          enter="ease-out duration-300"
          enterFrom="opacity-0"
          enterTo="opacity-100"
          leave="ease-in duration-200"
          leaveFrom="opacity-100"
          leaveTo="opacity-0"
        >
          <div className="fixed inset-0 bg-black/40 backdrop-blur-sm" />
        </Transition.Child>

        <div className="fixed inset-0 overflow-y-auto">
          <div className="flex min-h-full items-center justify-center p-4 text-center">
            <Transition.Child
              as={Fragment}
              enter="ease-out duration-300"
              enterFrom="opacity-0 scale-95"
              enterTo="opacity-100 scale-100"
              leave="ease-in duration-200"
              leaveFrom="opacity-100 scale-100"
              leaveTo="opacity-0 scale-95"
            >
              <Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
                <div className="flex justify-between items-start mb-5">
                  <Dialog.Title as="h3" className="text-lg font-bold leading-6 text-gray-900 pr-8">
                    Configurar {productData.name}
                  </Dialog.Title>
                  <button
                    onClick={onClose}
                    className="rounded-full p-1 hover:bg-gray-100 transition-colors absolute top-5 right-5 text-gray-400"
                  >
                    <X size={20} />
                  </button>
                </div>

                {/* Product Info Summary */}
                <div className="flex gap-4 mb-6 bg-gray-50 p-3 rounded-xl border border-gray-100">
                  {productData.image_url && (
                    <div className="w-16 h-16 relative rounded-lg overflow-hidden shrink-0 bg-white border border-gray-200">
                      <Image src={productData.image_url} alt={productData.name} fill className="object-cover" unoptimized />
                    </div>
                  )}
                  <div>
                    <div className="text-sm font-medium text-gray-900 mb-1">{combo.title || "Oferta Combo"}</div>
                    {productData.preco_oculto ? null : (
                    <div className="flex items-center gap-2">
                      <span className="font-bold text-emerald-600">
                        {formatMoney(resolvedPriceInfo.unitPrice)}
                      </span>
                      {combo.discount_type !== "none" && (
                         <span className="text-xs text-gray-400 line-through">{formatMoney(productData.price)}</span>
                      )}
                      {resolvedPriceInfo.hasTierApplied && (
                        <span className="text-[10px] bg-emerald-100 text-emerald-700 px-1.5 py-0.5 rounded font-bold">Atacado aplicado</span>
                      )}
                    </div>
                    )}
                  </div>
                </div>

                <div className="space-y-6">
                  {/* Quantity Control */}
                  <div>
                    <h4 className="text-sm font-semibold text-gray-900 mb-3">Quantidade</h4>
                    <div className="flex items-center justify-between bg-white border border-gray-200 rounded-lg p-1.5 w-max">
                      <button
                        type="button"
                        onClick={() => setQuantity(Math.max(1, quantity - 1))}
                        className="w-10 h-10 flex items-center justify-center text-gray-500 hover:text-gray-900 hover:bg-gray-50 rounded-md transition-colors"
                      >
                        -
                      </button>
                      <input
                        type="number"
                        value={quantity}
                        onChange={(e) => {
                          let val = parseInt(e.target.value, 10);
                          if (isNaN(val) || val < 1) val = 1;
                          setQuantity(val);
                        }}
                        className="w-16 h-10 text-center font-bold text-gray-900 focus:outline-none focus:ring-2 focus:ring-primary/20 bg-transparent border-none p-0 hide-arrows"
                        min="1"
                      />
                      <button
                        type="button"
                        onClick={() => setQuantity(quantity + 1)}
                        className="w-10 h-10 flex items-center justify-center text-gray-500 hover:text-gray-900 hover:bg-gray-50 rounded-md transition-colors"
                      >
                        +
                      </button>
                    </div>
                  </div>

                  {/* Dimensions (if square meter) */}
                  {isSquareMeter && (
                    <div>
                      <h4 className="text-sm font-semibold text-gray-900 mb-3">Medidas</h4>
                      <div className="grid grid-cols-2 gap-4">
                        <div>
                          <label className="block text-xs font-medium text-gray-500 mb-1">LARGURA (M)</label>
                          <input
                            type="text"
                            inputMode="decimal"
                            placeholder="Ex: 1,20"
                            value={widthStr}
                            onChange={(e) => setWidthStr(e.target.value)}
                            className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary"
                          />
                        </div>
                        {productData.unit_type === "square_meter" && (
                          <div>
                            <label className="block text-xs font-medium text-gray-500 mb-1">ALTURA (M)</label>
                            <input
                              type="text"
                              inputMode="decimal"
                              placeholder="Ex: 0,80"
                              value={heightStr}
                              onChange={(e) => setHeightStr(e.target.value)}
                              className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary"
                            />
                          </div>
                        )}
                      </div>
                    </div>
                  )}

                  {/* Variations */}
                  {hasVariations && (
                    <div className="space-y-4">
                      {atributosDoCombo.map((attr: any) => (
                        <div key={attr.name}>
                          <h4 className="text-sm font-semibold text-gray-900 mb-2">
                            {attr.name} {attributeIsRequired(attr) && <span className="text-red-500">*</span>}
                          </h4>
                          <div className="flex flex-wrap gap-2">
                            {Array.isArray(attr.options) && attr.options.map((opt: any) => {
                              const label = typeof opt === "string" ? opt : opt.label;
                              const isSelected = selectedOptions[attr.name] === label;
                              return (
                                <button
                                  key={label}
                                  onClick={() => setSelectedOptions(prev => ({ ...prev, [attr.name]: label }))}
                                  className={`px-3 py-1.5 text-sm rounded-lg border transition-all ${
                                    isSelected 
                                      ? "border-primary bg-primary/5 text-primary font-medium" 
                                      : "border-gray-200 text-gray-700 hover:border-gray-300 hover:bg-gray-50"
                                  }`}
                                  style={isSelected ? { borderColor: primaryColor, color: getAccessibleAccent(primaryColor) } : {}}
                                >
                                  {label}
                                </button>
                              );
                            })}
                          </div>
                        </div>
                      ))}
                    </div>
                  )}
                </div>

                {error && (
                  <div className="mt-4 p-3 bg-red-50 border border-red-100 rounded-lg flex items-start gap-2 text-sm text-red-600">
                    <AlertCircle size={16} className="shrink-0 mt-0.5" />
                    <p>{error}</p>
                  </div>
                )}

                <div className="mt-8">
                  <button
                    type="button"
                    className="w-full rounded-xl px-4 py-3.5 text-sm font-bold shadow-sm transition-all hover:opacity-90 active:scale-[0.98]"
                    style={{ backgroundColor: primaryColor, color: buttonTextColor }}
                    onClick={handleConfirm}
                  >
                    Confirmar Seleção
                  </button>
                </div>
              </Dialog.Panel>
            </Transition.Child>
          </div>
        </div>
      </Dialog>
    </Transition>
  );
}
