"use client";

import { useEffect, useMemo, useState } from "react";
import { Plus, Trash2, X, Pencil, Check, ChevronUp, ChevronDown } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { EntradaDecimal } from "@/components/ui/campo-decimal";
import { CurrencyInput } from "@/components/ui/currency-input";
import { Switch } from "@/components/ui/switch";
import { multiplicaNaQuantidade, nomeDaMedida, unidadeDoAdicional, vendidoPorMedida, type UnidadeDoAdicional } from "@/lib/adicionais";
import { CustomSelect } from "@/components/ui/custom-select";
import type { ProductImageItem } from "@/lib/product-images";

export interface ProductOption {
  id?: string;
  label: string;
  price: number;
  /* A cor da bolinha desta opcao na vitrine; vazio = o sistema adivinha
     pelo nome ("Azul marinho" ja sabe o que fazer). */
  swatch?: string | null;
  price_applies_per_quantity?: boolean;
  /* Em que o adicional se multiplica: measure (m² ou metro), piece ou order.
     Vazio = regra antiga: multiplica na quantidade ou cobra uma vez. */
  price_unit?: string | null;
  sku?: string;
  stock?: number;
  is_required?: boolean;
  position?: number;
  image_id?: string | null;
  minimum_stock?: number;
  reorder_point?: number;
  /* Receita da opção: o insumo que ela consome por peça (ex.: pingente ×1). */
  material_id?: string | null;
  material_qty?: number;
}

export interface ProductAttribute {
  id?: string;
  name: string;
  allow_multiple?: boolean;
  is_required?: boolean;
  position?: number;
  options: ProductOption[];
  /* Como a loja desenha: vazio = automatico (o conteudo decide). */
  display_style?: string | null;
  /* Falso tira da vitrine sem apagar nada — serve para o campo tecnico que
     veio de importacao (ncm, peso, id do fornecedor). */
  show_in_store?: boolean | null;
}

// ProductVariation will be deprecated or simplified
export interface ProductVariation {
  id?: string;
  combination: Record<string, string>;
  sku: string;
  price: number | null;
  stock: number;
  cost_adjustment: number;
}

/*
  Campos de planilha que a importação transformou em variação — `ncm_8`,
  `id_fornecedor`, `cofins`, `peso_liq`. Aparecem na vitrine como quadradinho
  de escolher, o que não faz sentido nenhum para quem está comprando. O
  sistema não esconde por conta: aqui só sugere, e quem decide é o lojista.
*/
const NOMES_TECNICOS = new Set([
  "ncm", "ncm_8", "cest", "cfop", "cofins", "pis", "icms", "ipi",
  "id_fornecedor", "fornecedor", "marca_25", "origem_0_a_8",
  "tipo_class_fiscal", "tipo_produto_servico", "produto_variado_sim_nao",
  "valor_custo", "custo", "peso", "peso_liq", "peso_bruto",
  "estoque_minimo", "estoque_maximo", "unidade", "gtin", "ean", "codigo_barras",
]);

function pareceCampoTecnico(nome: string, quantasOpcoes: number) {
  const limpo = nome
    .normalize("NFD")
    .replace(/\p{Diacritic}/gu, "")
    .toLowerCase()
    .trim()
    .replace(/\s+/g, "_");
  if (NOMES_TECNICOS.has(limpo)) return true;
  return quantasOpcoes <= 1 && /_/.test(limpo) && /\d/.test(limpo);
}

/* As cores que o sistema entende sozinho pelo nome da opção — as mesmas do
   dicionário da vitrine, aqui só para mostrar a bolinha no editor. */
const CORES_CONHECIDAS: Record<string, string> = {
  preto: "#101014", branco: "#ffffff", cinza: "#8b8f98", azul: "#1f5fd0",
  vermelho: "#d92c2c", verde: "#1f9d55", amarelo: "#f5c518", laranja: "#f1701f",
  rosa: "#ef5da8", roxo: "#7b3fe4", lilas: "#b98cf0", marrom: "#7a4a24",
  bege: "#e4d3b4", vinho: "#6d1f33", dourado: "#d4af37", prata: "#c0c4c9",
  turquesa: "#1fbfb8", coral: "#f4705c", creme: "#f6ecd6", nude: "#e0bfa8",
};

/* A mesma pergunta que a vitrine faz: este atributo vira bolinha? */
function mostraCor(attr: ProductAttribute) {
  if (attr.display_style === "cores") return true;
  if (attr.display_style) return false;
  if (attr.options.some((opcao) => opcao.swatch)) return true;
  const nome = attr.name
    .normalize("NFD")
    .replace(/\p{Diacritic}/gu, "")
    .toLowerCase();
  if (!/\b(cor|cores|colour|color|tom|tonalidade|tonalidades)\b/.test(nome)) return false;
  const comCor = attr.options.filter((opcao) => corSugerida(opcao.label)).length;
  return attr.options.length > 0 && comCor / attr.options.length >= 0.6;
}

function corSugerida(rotulo: string) {
  const palavras = rotulo
    .normalize("NFD")
    .replace(/\p{Diacritic}/gu, "")
    .toLowerCase()
    .split(/[^a-z]+/)
    .filter(Boolean);
  for (const palavra of palavras) {
    if (CORES_CONHECIDAS[palavra]) return CORES_CONHECIDAS[palavra];
    if (palavra.length > 4 && palavra.endsWith("a")) {
      const masculino = `${palavra.slice(0, -1)}o`;
      if (CORES_CONHECIDAS[masculino]) return CORES_CONHECIDAS[masculino];
    }
  }
  return null;
}

const ESTILOS_DA_VITRINE = [
  { value: "", label: "Automático" },
  { value: "cores", label: "Bolinhas de cor" },
  { value: "miniaturas", label: "Miniaturas da foto" },
  { value: "botoes", label: "Botões" },
  { value: "lista", label: "Lista com busca" },
  { value: "dropdown", label: "Menu que abre" },
];

interface ProductVariationsProps {
  attributes: ProductAttribute[];
  setAttributes: (attrs: ProductAttribute[]) => void;
  productImages?: ProductImageItem[];
  variations: ProductVariation[];
  setVariations: (vars: ProductVariation[]) => void;
  basePrice: number;
  baseCost: number;
  inventoryScope?: "product" | "option" | "variant";
  /* A unidade de venda do produto: no m², o adicional escolhe entre m², peça e pedido. */
  unitType?: string | null;
  /* Empresa no estoque novo (v2): o saldo mora no estoque, não aqui; a
     receita da opção aparece na Composição como "só com esta opção". */
  estoqueNovo?: boolean;
}

export function ProductVariations({
  attributes,
  setAttributes,
  productImages = [],
  variations,
  setVariations,
  basePrice,
  baseCost,
  inventoryScope = "product",
  unitType = "unit",
  estoqueNovo = false,
}: ProductVariationsProps) {
  void basePrice;
  void baseCost;
  const [newAttrName, setNewAttrName] = useState("");
  const [optionInputs, setOptionInputs] = useState<Record<number, string>>({});
  const [optionPrices, setOptionPrices] = useState<Record<number, number>>({});
  /* Opção que já existe na variação: o "Adicionar" avisa em vez de não fazer nada. */
  const [opcaoRepetida, setOpcaoRepetida] = useState<Record<number, string>>({});
  const [editingAttributeIndex, setEditingAttributeIndex] = useState<number | null>(null);
  const [editingAttributeName, setEditingAttributeName] = useState("");
  const [draggedOption, setDraggedOption] = useState<{ attrIndex: number; optionIndex: number } | null>(null);
  const [insumos, setInsumos] = useState<Array<{ id: string; name: string; unit?: string | null }>>([]);

  useEffect(() => {
    let ativo = true;
    fetch("/api/production/materials?papel=insumo")
      .then((res) => (res.ok ? res.json() : []))
      .then((data) => {
        if (!ativo || !Array.isArray(data)) return;
        setInsumos(data.map((m: { id: string; name: string; unit?: string | null }) => ({ id: m.id, name: m.name, unit: m.unit })));
      })
      .catch(() => { /* sem lista, o vínculo fica indisponível — nada quebra */ });
    return () => { ativo = false; };
  }, []);

  const insumoOptions = useMemo(
    () => [
      { value: "", label: "Não consome insumo" },
      ...insumos.map((m) => ({ value: m.id, label: m.unit ? `${m.name} (${m.unit})` : m.name })),
    ],
    [insumos]
  );

  useEffect(() => {
    const validIds = new Set(productImages.map((image) => image.id));
    let changed = false;
    const next = attributes.map((attribute) => ({
      ...attribute,
      options: attribute.options.map((option) => {
        if (!option.image_id) return option;
        if (validIds.has(option.image_id)) return option;
        changed = true;
        return { ...option, image_id: null };
      }),
    }));
    if (changed) setAttributes(next);
  }, [attributes, productImages, setAttributes]);

  const imageSelectOptions = useMemo(
    () => [
      { value: "", label: "Sem vínculo" },
      ...productImages.map((image, index) => ({
        value: image.id,
        label: `Imagem ${index + 1}${image.is_primary ? " (principal)" : ""}`,
        image_url: image.image_url,
        description: image.is_primary ? "Imagem principal" : undefined,
      })),
    ],
    [productImages]
  );

  const updateAttribute = (index: number, patch: Partial<ProductAttribute>) => {
    const newAttrs = [...attributes];
    newAttrs[index] = { ...newAttrs[index], ...patch };
    setAttributes(newAttrs);
  };

  const moveAttribute = (fromIndex: number, toIndex: number) => {
    if (toIndex < 0 || toIndex >= attributes.length) return;
    const next = [...attributes];
    const [moved] = next.splice(fromIndex, 1);
    next.splice(toIndex, 0, moved);
    const normalized = next.map((attr, index) => ({ ...attr, position: index }));
    setAttributes(normalized);
  };

  const startEditAttributeName = (index: number) => {
    setEditingAttributeIndex(index);
    setEditingAttributeName(attributes[index]?.name || "");
  };

  const saveAttributeName = () => {
    if (editingAttributeIndex === null) return;
    const trimmed = editingAttributeName.trim();
    if (!trimmed) return;
    updateAttribute(editingAttributeIndex, { name: trimmed });
    setEditingAttributeIndex(null);
    setEditingAttributeName("");
  };

  const addAttribute = (e?: React.MouseEvent | React.KeyboardEvent) => {
    if (e && 'preventDefault' in e) e.preventDefault();
    if (!newAttrName.trim()) return;
    setAttributes([
      ...attributes,
      {
        name: newAttrName,
        options: [],
        allow_multiple: false,
        is_required: false,
        position: attributes.length,
        display_style: null,
        show_in_store: true,
      },
    ]);
    setNewAttrName("");
  };

  const removeAttribute = (index: number) => {
    const newAttrs = [...attributes];
    newAttrs.splice(index, 1);
    setAttributes(newAttrs.map((attr, idx) => ({ ...attr, position: idx })));
  };

  const addOption = (attrIndex: number, e?: React.MouseEvent | React.KeyboardEvent) => {
    if (e && 'preventDefault' in e) e.preventDefault();
    const value = optionInputs[attrIndex]?.trim();
    if (!value) return;
    
    const price = optionPrices[attrIndex] || 0;
    
    const newAttrs = [...attributes];
    /* Mesmo nome (sem contar maiúsculas e espaços) já é uma opção desta variação. */
    const chave = (texto: string) => texto.trim().replace(/\s+/g, " ").toLocaleLowerCase("pt-BR");
    const existente = newAttrs[attrIndex].options.find((o) => chave(o.label || "") === chave(value));
    if (existente) {
      setOpcaoRepetida({ ...opcaoRepetida, [attrIndex]: existente.label });
      return;
    }
    newAttrs[attrIndex] = {
      ...newAttrs[attrIndex],
      options: [
        ...newAttrs[attrIndex].options,
        {
          id: crypto.randomUUID(),
          label: value,
          price: price,
          price_applies_per_quantity: true,
          stock: 0,
          is_required: false,
          position: newAttrs[attrIndex].options.length,
          image_id: null,
          minimum_stock: 0,
          reorder_point: 0,
        },
      ],
    };
    setAttributes(newAttrs);
    setOptionInputs({ ...optionInputs, [attrIndex]: "" });
    setOptionPrices({ ...optionPrices, [attrIndex]: 0 });
  };

  const removeOption = (attrIndex: number, optionIndex: number) => {
    const newAttrs = [...attributes];
    newAttrs[attrIndex].options.splice(optionIndex, 1);
    newAttrs[attrIndex].options = newAttrs[attrIndex].options.map((opt, idx) => ({ ...opt, position: idx }));
    setAttributes(newAttrs);
  };

  const moveOption = (attrIndex: number, fromIndex: number, toIndex: number) => {
    if (fromIndex === toIndex) return;
    const newAttrs = [...attributes];
    const options = [...newAttrs[attrIndex].options];
    const [moved] = options.splice(fromIndex, 1);
    options.splice(toIndex, 0, moved);
    newAttrs[attrIndex].options = options.map((opt, idx) => ({ ...opt, position: idx }));
    setAttributes(newAttrs);
  };
  
  const updateOptionPrice = (attrIndex: number, optionIndex: number, newPrice: number) => {
    const newAttrs = [...attributes];
    newAttrs[attrIndex].options[optionIndex].price = newPrice;
    setAttributes(newAttrs);
  }

  /* A cor da bolinha desta opção. Vazio devolve para o automático — o
     dicionário volta a adivinhar pelo nome. */
  const updateOptionSwatch = (attrIndex: number, optionIndex: number, swatch: string | null) => {
    const newAttrs = [...attributes];
    newAttrs[attrIndex].options[optionIndex].swatch = swatch;
    setAttributes(newAttrs);
  };

  const updateOptionRequired = (attrIndex: number, optionIndex: number, required: boolean) => {
    const newAttrs = [...attributes];
    newAttrs[attrIndex].options[optionIndex].is_required = required;
    setAttributes(newAttrs);
  };

  const updateOptionPriceAppliesPerQuantity = (
    attrIndex: number,
    optionIndex: number,
    appliesPerQuantity: boolean
  ) => {
    const newAttrs = [...attributes];
    newAttrs[attrIndex].options[optionIndex].price_applies_per_quantity = appliesPerQuantity;
    setAttributes(newAttrs);
  };

  /* No produto por m² a opção diz em que se multiplica; o campo antigo
     acompanha, para o código que ainda lê só ele. */
  const updateOptionPriceUnit = (attrIndex: number, optionIndex: number, unit: UnidadeDoAdicional) => {
    const newAttrs = [...attributes];
    newAttrs[attrIndex].options[optionIndex].price_unit = unit;
    newAttrs[attrIndex].options[optionIndex].price_applies_per_quantity = multiplicaNaQuantidade(unit);
    setAttributes(newAttrs);
  };

  const updateOptionStock = (attrIndex: number, optionIndex: number, stock: number) => {
    const newAttrs = [...attributes];
    newAttrs[attrIndex].options[optionIndex].stock = Math.max(0, stock);
    setAttributes(newAttrs);
  };

  const updateOptionMinimumStock = (attrIndex: number, optionIndex: number, minimumStock: number) => {
    const newAttrs = [...attributes];
    newAttrs[attrIndex].options[optionIndex].minimum_stock = Math.max(0, minimumStock);
    setAttributes(newAttrs);
  };

  const updateOptionReorderPoint = (attrIndex: number, optionIndex: number, reorderPoint: number) => {
    const newAttrs = [...attributes];
    newAttrs[attrIndex].options[optionIndex].reorder_point = Math.max(0, reorderPoint);
    setAttributes(newAttrs);
  };

  const updateOptionImage = (attrIndex: number, optionIndex: number, imageId: string) => {
    const newAttrs = [...attributes];
    newAttrs[attrIndex].options[optionIndex].image_id = imageId || null;
    setAttributes(newAttrs);
  };

  const updateOptionMaterial = (attrIndex: number, optionIndex: number, materialId: string) => {
    const newAttrs = [...attributes];
    const option = newAttrs[attrIndex].options[optionIndex];
    option.material_id = materialId || null;
    if (!materialId) {
      option.material_qty = 0;
    } else if (!option.material_qty || option.material_qty <= 0) {
      option.material_qty = 1;
    }
    setAttributes(newAttrs);
  };

  const updateOptionMaterialQty = (attrIndex: number, optionIndex: number, qty: number) => {
    const newAttrs = [...attributes];
    newAttrs[attrIndex].options[optionIndex].material_qty = Math.max(0, qty);
    setAttributes(newAttrs);
  };

  function combinationSignature(combination: Record<string, string>) {
    return Object.entries(combination)
      .map(([key, value]) => [key.trim().toLowerCase(), (value || "").trim().toLowerCase()] as const)
      .sort((a, b) => a[0].localeCompare(b[0]))
      .map(([key, value]) => `${key}:${value}`)
      .join("|");
  }

  const generatedCombinations = useMemo(() => {
    const validAttributes = attributes
      .map((attribute) => ({
        name: (attribute.name || "").trim(),
        options: (attribute.options || [])
          .map((option) => (option.label || "").trim())
          .filter(Boolean),
      }))
      .filter((attribute) => attribute.name && attribute.options.length > 0);

    if (!validAttributes.length) return [] as Record<string, string>[];

    const combinations: Record<string, string>[] = [];
    function walk(index: number, current: Record<string, string>) {
      if (index >= validAttributes.length) {
        combinations.push({ ...current });
        return;
      }
      const attribute = validAttributes[index];
      for (const label of attribute.options) {
        walk(index + 1, { ...current, [attribute.name]: label });
      }
    }
    walk(0, {});
    return combinations;
  }, [attributes]);

  useEffect(() => {
    if (inventoryScope !== "variant") return;
    const existingBySignature = new Map(
      (variations || []).map((variation) => [combinationSignature(variation.combination || {}), variation])
    );
    const nextVariations = generatedCombinations.map((combination) => {
      const signature = combinationSignature(combination);
      const existing = existingBySignature.get(signature);
      return {
        id: existing?.id,
        combination,
        sku: existing?.sku || "",
        /* Preço/custo por combinação foram aposentados: nenhum canal de venda
           os usava — quem precifica é o adicional de cada opção. */
        price: null,
        stock: Number(existing?.stock) || 0,
        cost_adjustment: 0,
      };
    });
    const currentComparable = (variations || []).map((variation) => ({
      combination: variation.combination || {},
      sku: variation.sku || "",
      price: variation.price ?? null,
      stock: Number(variation.stock) || 0,
      cost_adjustment: Number(variation.cost_adjustment) || 0,
    }));
    const nextComparable = nextVariations.map((variation) => ({
      combination: variation.combination || {},
      sku: variation.sku || "",
      price: variation.price ?? null,
      stock: Number(variation.stock) || 0,
      cost_adjustment: Number(variation.cost_adjustment) || 0,
    }));
    if (JSON.stringify(currentComparable) !== JSON.stringify(nextComparable)) {
      setVariations(nextVariations);
    }
  }, [generatedCombinations, inventoryScope, setVariations, variations]);

  const updateVariation = (index: number, patch: Partial<ProductVariation>) => {
    const next = [...variations];
    const current = next[index];
    if (!current) return;
    next[index] = { ...current, ...patch };
    setVariations(next);
  };

  return (
    <div className="space-y-8">
      {/* Passo 1: Definir Atributos e Opções */}
      <div className="ks-surface p-6">
        <div className="mb-6 border-b border-[var(--ks-color-border-subtle)] pb-4">
           <h3 className="text-base font-semibold text-[var(--ks-color-text-primary)] flex items-center gap-2">
             Defina as Variações
           </h3>
           <p className="text-sm text-[var(--ks-color-text-muted)] mt-1">
             Crie características (ex: Tamanho, Cor) e suas opções. Cada opção pode ter um preço adicional.
           </p>
        </div>
        
        <div className="flex gap-4 items-end mb-6 p-4 bg-[var(--ks-color-bg-soft)] rounded-lg border border-[var(--ks-color-border-subtle)]">
          <div className="flex-1">
            <Input 
              label="Nome da Característica"
              placeholder="Ex: Tamanho, Cor, Acabamento" 
              value={newAttrName}
              onChange={e => setNewAttrName(e.target.value)}
              onKeyDown={e => e.key === 'Enter' && (e.preventDefault(), addAttribute())}
              className="bg-white"
            />
          </div>
          <Button onClick={addAttribute} type="button" variant="secondary" className="mb-[2px] bg-white border border-[var(--ks-color-border-subtle)] hover:bg-slate-50 text-[var(--ks-color-text-primary)]">
            <Plus className="w-4 h-4 mr-2" /> Criar
          </Button>
        </div>

        <div className="space-y-4">
          {attributes.map((attr, idx) => (
            <div key={idx} className="bg-white p-5 rounded-xl border border-[var(--ks-color-border-subtle)] shadow-sm hover:border-[var(--ks-color-primary)] transition-colors group">
              <div className="flex items-center justify-between mb-4 border-b border-dashed border-slate-100 pb-3">
                <div className="flex flex-col gap-2">
                  {editingAttributeIndex === idx ? (
                    <div className="flex items-center gap-2">
                      <input
                        value={editingAttributeName}
                        onChange={(e) => setEditingAttributeName(e.target.value)}
                        onKeyDown={(e) => {
                          if (e.key === "Enter") {
                            e.preventDefault();
                            saveAttributeName();
                          }
                        }}
                        className="h-8 px-3 text-sm bg-white border border-[var(--ks-color-border-subtle)] rounded-md focus:outline-none focus:ring-2 focus:ring-[var(--ks-color-primary)] focus:border-transparent"
                      />
                      <button
                        type="button"
                        onClick={saveAttributeName}
                        className="h-8 w-8 flex items-center justify-center rounded-full bg-emerald-50 text-emerald-600 hover:bg-emerald-100 hover:text-emerald-700 transition-colors"
                        aria-label="Salvar nome"
                      >
                        <Check className="w-4 h-4" />
                      </button>
                    </div>
                  ) : (
                    <div className="flex items-center gap-2">
                      <span className="font-semibold text-lg text-[var(--ks-color-text-primary)]">{attr.name}</span>
                      <button
                        type="button"
                        onClick={() => startEditAttributeName(idx)}
                        className="h-7 w-7 flex items-center justify-center rounded-full bg-slate-100 text-slate-500 hover:bg-slate-200 hover:text-slate-700 transition-colors"
                        aria-label="Editar nome"
                      >
                        <Pencil className="w-3.5 h-3.5" />
                      </button>
                      <span className="text-xs px-2 py-0.5 bg-slate-100 text-slate-500 rounded-full">
                        {attr.options.length} opções
                      </span>
                      {/^quantidades?$/i.test(attr.name.trim()) && (
                        <span className="text-[11px] px-2 py-0.5 bg-amber-50 text-amber-700 rounded-full">
                          Para preço por lote (100 un, 500 un…), a aba “Preço por quantidade” calcula sozinha
                        </span>
                      )}
                    </div>
                  )}
                  <div className="flex flex-wrap items-center gap-3 text-[11px] text-slate-500">
                    <div className="flex items-center gap-2">
                      <span>Múltipla escolha</span>
                      <Switch
                        checked={Boolean(attr.allow_multiple)}
                        /* Com estoque por combinação, duas opções marcadas no mesmo
                           atributo deixariam a baixa sem saber qual combinação usar —
                           então aqui só se DESLIGA; ligar é bloqueado. */
                        disabled={inventoryScope === "variant" && !attr.allow_multiple}
                        onCheckedChange={(checked) => updateAttribute(idx, { allow_multiple: checked })}
                        className="scale-75 origin-left"
                      />
                      {inventoryScope === "variant" && (
                        <span className="text-[10px] text-slate-400">
                          {attr.allow_multiple
                            ? "incompatível com estoque por combinação — desligue"
                            : "indisponível com estoque por combinação"}
                        </span>
                      )}
                    </div>
                    <div className="flex items-center gap-2">
                      <span>Obrigatória</span>
                      <Switch
                        checked={Boolean(attr.is_required)}
                        onCheckedChange={(checked) => updateAttribute(idx, { is_required: checked })}
                        className="scale-75 origin-left"
                      />
                    </div>
                    <div className="flex items-center gap-2">
                      <span>Mostrar na loja</span>
                      <Switch
                        checked={attr.show_in_store !== false}
                        onCheckedChange={(checked) => updateAttribute(idx, { show_in_store: checked })}
                        className="scale-75 origin-left"
                      />
                      {attr.show_in_store === false && (
                        <span className="text-[10px] text-slate-400">o cliente não vê; o dado continua guardado</span>
                      )}
                    </div>
                    <div className="flex items-center gap-2">
                      <span>Na vitrine</span>
                      <div className="w-[168px]">
                        <CustomSelect
                          options={ESTILOS_DA_VITRINE}
                          value={attr.display_style || ""}
                          onChange={(value) => updateAttribute(idx, { display_style: value || null })}
                          size="sm"
                        />
                      </div>
                    </div>
                  </div>

                  {/*
                    Esconder um obrigatório de várias opções deixa a escolha em
                    branco no pedido: ninguém tem como adivinhar qual delas era.
                    Com uma opção só, o sistema marca por conta e o pedido sai
                    completo do mesmo jeito.
                  */}
                  {attr.show_in_store === false && attr.is_required && attr.options.length > 1 && (
                    <div className="rounded-lg border border-rose-200 bg-rose-50 px-3 py-2 text-[11px] text-rose-800">
                      <strong>“{attr.name}”</strong> é obrigatória e tem {attr.options.length} opções, mas está fora da
                      loja: o cliente compra sem escolher e o pedido chega sem essa informação. Ou deixe de ser
                      obrigatória, ou volte para a vitrine.
                    </div>
                  )}

                  {/* A sugestão, não a decisão: quem tira da vitrine é o lojista. */}
                  {attr.show_in_store !== false && pareceCampoTecnico(attr.name, attr.options.length) && (
                    <div className="flex flex-wrap items-center gap-2 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-[11px] text-amber-800">
                      <span>
                        <strong>“{attr.name}”</strong> parece um campo de planilha, não uma escolha do cliente — e hoje
                        aparece na loja como um quadradinho de selecionar.
                      </span>
                      <button
                        type="button"
                        onClick={() => updateAttribute(idx, { show_in_store: false })}
                        className="rounded-md border border-amber-300 bg-white px-2 py-1 font-semibold text-amber-800 hover:bg-amber-100"
                      >
                        Tirar da loja
                      </button>
                    </div>
                  )}
                </div>
                <div className="flex items-center gap-2">
                  <button
                    type="button"
                    onClick={() => moveAttribute(idx, idx - 1)}
                    className="h-8 w-8 flex items-center justify-center rounded-full bg-slate-100 text-slate-500 hover:bg-slate-200 hover:text-slate-700 transition-colors disabled:opacity-40"
                    aria-label="Mover para cima"
                    disabled={idx === 0}
                  >
                    <ChevronUp className="w-4 h-4" />
                  </button>
                  <button
                    type="button"
                    onClick={() => moveAttribute(idx, idx + 1)}
                    className="h-8 w-8 flex items-center justify-center rounded-full bg-slate-100 text-slate-500 hover:bg-slate-200 hover:text-slate-700 transition-colors disabled:opacity-40"
                    aria-label="Mover para baixo"
                    disabled={idx === attributes.length - 1}
                  >
                    <ChevronDown className="w-4 h-4" />
                  </button>
                  <button
                    type="button"
                    onClick={() => removeAttribute(idx)}
                    className="h-8 w-8 flex items-center justify-center rounded-full bg-rose-50 text-rose-600 hover:bg-rose-100 hover:text-rose-700 transition-colors"
                    aria-label="Excluir característica"
                  >
                    <Trash2 className="w-4 h-4" />
                  </button>
                </div>
              </div>
              
              <div className="space-y-4">
                {/* Lista de Opções Existentes */}
                {attr.options.length > 0 && (
                  <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-3 mb-4">
                    {attr.options.map((opt, optIdx) => (
                      <div
                        key={optIdx}
                        draggable
                        onDragStart={() => setDraggedOption({ attrIndex: idx, optionIndex: optIdx })}
                        onDragOver={(e) => e.preventDefault()}
                        onDragEnd={() => setDraggedOption(null)}
                        onDrop={() => {
                          if (!draggedOption) return;
                          if (draggedOption.attrIndex !== idx) return;
                          moveOption(idx, draggedOption.optionIndex, optIdx);
                          setDraggedOption(null);
                        }}
                        className="flex flex-col gap-2 bg-slate-50 p-2 rounded-lg border border-slate-100 cursor-grab active:cursor-grabbing"
                      >
                        <div className="flex items-center justify-between gap-3">
                          <span className="flex min-w-0 items-center gap-2">
                            {/* A bolinha aparece quando este atributo vai virar cor na
                                vitrine. Clicar escolhe à mão; o X devolve para o
                                automático, que adivinha pelo nome. */}
                            {mostraCor(attr) && (
                              <span className="relative inline-flex shrink-0 items-center">
                                <input
                                  type="color"
                                  value={opt.swatch || corSugerida(opt.label) || "#cccccc"}
                                  onChange={(event) => updateOptionSwatch(idx, optIdx, event.target.value)}
                                  className="h-6 w-6 cursor-pointer rounded-full border border-slate-300 bg-transparent p-0 [&::-webkit-color-swatch-wrapper]:p-0.5 [&::-webkit-color-swatch]:rounded-full [&::-webkit-color-swatch]:border-0"
                                  title={
                                    opt.swatch
                                      ? "Cor escolhida à mão — clique para trocar"
                                      : corSugerida(opt.label)
                                        ? `A loja já reconhece “${opt.label}” — clique para trocar`
                                        : "Escolher a cor desta opção"
                                  }
                                />
                                {opt.swatch && (
                                  <button
                                    type="button"
                                    onClick={() => updateOptionSwatch(idx, optIdx, null)}
                                    className="absolute -right-1.5 -top-1.5 flex h-3.5 w-3.5 items-center justify-center rounded-full bg-slate-500 text-white hover:bg-slate-700"
                                    title="Voltar ao automático"
                                  >
                                    <X className="h-2.5 w-2.5" />
                                  </button>
                                )}
                              </span>
                            )}
                            <span className="truncate font-medium text-sm text-slate-700">{opt.label}</span>
                          </span>
                          <button onClick={() => removeOption(idx, optIdx)} className="text-slate-400 hover:text-red-500 transition-colors p-1">
                            <X className="w-4 h-4" />
                          </button>
                        </div>
                        <div className="flex flex-wrap items-center justify-between gap-2">
                          <div className="flex items-center gap-2 text-[10px] text-slate-500">
                            <span>Obrigatório</span>
                            <Switch
                              checked={Boolean(opt.is_required)}
                              onCheckedChange={(checked) => updateOptionRequired(idx, optIdx, checked)}
                              className="scale-75 origin-left"
                            />
                          </div>
                          <div className="flex items-center gap-1 bg-white px-2 py-1 rounded border border-slate-200">
                            <span className="text-[10px] text-slate-400">+R$</span>
                            <CurrencyInput 
                              value={opt.price} 
                              onChange={(val) => updateOptionPrice(idx, optIdx, val)}
                              className="h-6 w-20 border-0 p-0 text-right text-sm focus-visible:ring-0"
                            />
                          </div>
                        </div>
                        {vendidoPorMedida(unitType) ? (
                          /* Produto por m²: "quantidade" seria ambíguo (peças ou
                             metros?). Aqui o lojista diz com todas as letras. */
                          <div className="flex flex-wrap items-center gap-2 text-[10px] text-slate-500">
                            <span>Cobrado</span>
                            <select
                              value={unidadeDoAdicional(opt, unitType)}
                              onChange={(e) => updateOptionPriceUnit(idx, optIdx, e.target.value as UnidadeDoAdicional)}
                              className="h-6 rounded border border-slate-200 bg-white px-1 text-[11px] text-slate-700"
                              title={`Em que este adicional se multiplica num produto vendido por ${nomeDaMedida(unitType)}`}
                            >
                              <option value="measure">
                                por {nomeDaMedida(unitType)} (multiplica pela {unitType === "square_meter" ? "área" : "metragem"})
                              </option>
                              <option value="piece">por peça</option>
                              <option value="order">uma vez no pedido</option>
                            </select>
                          </div>
                        ) : (
                          <div className="flex items-center gap-2 text-[10px] text-slate-500">
                            <span>Multiplica na quantidade</span>
                            <Switch
                              checked={opt.price_applies_per_quantity !== false}
                              onCheckedChange={(checked) => updateOptionPriceAppliesPerQuantity(idx, optIdx, checked)}
                              className="scale-75 origin-left"
                            />
                            <span className="text-[10px] text-slate-400">
                              {opt.price_applies_per_quantity === false ? "cobrado uma vez" : "cobrado por quantidade"}
                            </span>
                          </div>
                        )}
                        <div className="space-y-1">
                          {/* Os campos de estoque por opção só existem quando é essa a regra
                              que controla o estoque — fora dela eram números inertes que
                              ficavam gravados mentindo. */}
                          {inventoryScope === "option" && (
                            <div className="grid grid-cols-3 gap-2">
                              <div>
                                <label className="text-[10px] text-slate-500">Estoque</label>
                                <EntradaDecimal
                                  valor={opt.stock ?? 0}
                                  aoMudar={(n) => updateOptionStock(idx, optIdx, Math.max(0, n))}
                                  casas={3}
                                  aria-label="Estoque da opção"
                                  className="h-8 text-xs"
                                />
                                {Number(opt.minimum_stock ?? 0) > 0 && Number(opt.stock ?? 0) <= Number(opt.minimum_stock ?? 0) && (
                                  <span className="inline-block mt-1 rounded-full bg-red-50 px-2 py-0.5 text-[10px] font-semibold text-red-600">
                                    Repor{Number(opt.reorder_point ?? 0) > 0 ? ` até ${opt.reorder_point}` : ""}
                                  </span>
                                )}
                              </div>
                              <div>
                                <label className="text-[10px] text-slate-500">Mínimo</label>
                                <EntradaDecimal
                                  valor={opt.minimum_stock ?? 0}
                                  aoMudar={(n) => updateOptionMinimumStock(idx, optIdx, Math.max(0, n))}
                                  casas={3}
                                  aria-label="Estoque mínimo da opção"
                                  className="h-8 text-xs"
                                />
                              </div>
                              <div>
                                <label className="text-[10px] text-slate-500">Reposição</label>
                                <EntradaDecimal
                                  valor={opt.reorder_point ?? 0}
                                  aoMudar={(n) => updateOptionReorderPoint(idx, optIdx, Math.max(0, n))}
                                  casas={3}
                                  aria-label="Ponto de reposição da opção"
                                  className="h-8 text-xs"
                                />
                              </div>
                            </div>
                          )}
                          <label className="text-[10px] text-slate-500">Imagem vinculada</label>
                          <CustomSelect
                            options={imageSelectOptions}
                            value={opt.image_id || ""}
                            onChange={(value) => updateOptionImage(idx, optIdx, value)}
                            placeholder="Sem vínculo"
                            searchable={productImages.length > 6}
                            className="space-y-1 [&>div>button]:h-8 [&>div>button]:min-h-8 [&>div>button]:rounded-md [&>div>button]:px-2 [&>div>button]:py-1.5 [&>div>button]:text-xs"
                          />
                          {/* Receita da opção: escolher esta opção baixa o insumo
                              vinculado na venda (e o cancelamento devolve). */}
                          <label className="text-[10px] text-slate-500">Consome insumo</label>
                          <CustomSelect
                            options={insumoOptions}
                            value={opt.material_id || ""}
                            onChange={(value) => updateOptionMaterial(idx, optIdx, value)}
                            placeholder="Não consome insumo"
                            searchable={insumos.length > 6}
                            className="space-y-1 [&>div>button]:h-8 [&>div>button]:min-h-8 [&>div>button]:rounded-md [&>div>button]:px-2 [&>div>button]:py-1.5 [&>div>button]:text-xs"
                          />
                          {opt.material_id && (
                            <div className="flex items-center gap-2">
                              <label className="text-[10px] text-slate-500 whitespace-nowrap">Qtd por peça</label>
                              <EntradaDecimal
                                valor={opt.material_qty ?? 1}
                                aoMudar={(n) => updateOptionMaterialQty(idx, optIdx, n)}
                                className="h-8 w-24 text-xs"
                              />
                            </div>
                          )}
                          {estoqueNovo && opt.material_id ? (
                            <p className="text-[10px] leading-snug text-slate-400">Sai do estoque só quando esta opção é escolhida (aparece na Composição).</p>
                          ) : null}
                        </div>
                      </div>
                    ))}
                  </div>
                )}
                
                {/* Adicionar Nova Opção */}
                <div className="flex flex-col sm:flex-row gap-3 sm:items-end bg-slate-50/50 p-3 rounded-lg border border-dashed border-slate-200">
                  <div className="flex-1 w-full">
                    <label className="text-xs text-slate-500 mb-1 block">Nova Opção</label>
                    <span className="text-[11px] text-slate-400 block mb-2">Ex: Premium, Fosco, Glitter</span>
                    <input
                      type="text"
                      className="h-9 w-full px-3 text-sm bg-white border border-[var(--ks-color-border-subtle)] rounded-md focus:outline-none focus:ring-2 focus:ring-[var(--ks-color-primary)] focus:border-transparent transition-all placeholder:text-slate-400 placeholder:italic"
                      placeholder="Digite a opção"
                      value={optionInputs[idx] || ""}
                      onChange={(e) => {
                        setOptionInputs({ ...optionInputs, [idx]: e.target.value });
                        if (opcaoRepetida[idx]) setOpcaoRepetida({ ...opcaoRepetida, [idx]: "" });
                      }}
                      onKeyDown={(e) => {
                        if (e.key === 'Enter') {
                          addOption(idx, e);
                        }
                      }}
                    />
                  </div>
                  <div className="w-full sm:w-32">
                    <label className="text-xs text-slate-500 mb-1 block">Preço Adicional</label>
                    <div className="relative">
                      <span className="absolute left-2 top-1/2 -translate-y-1/2 text-xs text-slate-400">R$</span>
                      <CurrencyInput
                        value={optionPrices[idx] || 0}
                        onChange={(val) => setOptionPrices({ ...optionPrices, [idx]: val })}
                        className="h-9 pl-7 bg-white"
                      />
                    </div>
                  </div>
                  <div className="w-full sm:w-auto relative z-10 pointer-events-auto">
                    <Button
                      size="sm"
                      type="button"
                      variant="secondary"
                      onClick={(e) => addOption(idx, e)}
                      disabled={!optionInputs[idx]?.trim()}
                      className="h-9 px-4 w-full sm:w-auto"
                    >
                      Adicionar
                    </Button>
                  </div>
                </div>
                {opcaoRepetida[idx] ? (
                  <p role="alert" data-opcao-repetida className="mt-2 text-xs font-medium text-[var(--ks-color-danger,#B42318)]">
                    &quot;{opcaoRepetida[idx]}&quot; já é uma opção desta variação. Para mudar o preço ou a foto dela, edite na lista acima.
                  </p>
                ) : null}
              </div>
            </div>
          ))}
          
          {attributes.length === 0 && (
             <div className="text-center py-12 text-[var(--ks-color-text-muted)] border-2 border-dashed border-[var(--ks-color-border-subtle)] rounded-xl bg-[var(--ks-color-bg-soft)]">
               <div className="w-12 h-12 bg-slate-100 rounded-full flex items-center justify-center mx-auto mb-3">
                 <Plus className="w-6 h-6 text-slate-400" />
               </div>
               <p className="font-medium text-[var(--ks-color-text-primary)] mb-1">Nenhum atributo definido</p>
              <p className="text-sm max-w-xs mx-auto">Adicione características como &quot;Tamanho&quot; ou &quot;Cor&quot; acima.</p>
             </div>
          )}
        </div>
      </div>

      {inventoryScope === "variant" && (
        <div className="ks-surface p-6">
          <div className="mb-6 border-b border-[var(--ks-color-border-subtle)] pb-4">
            <h3 className="text-base font-semibold text-[var(--ks-color-text-primary)]">Estoque por Combinação</h3>
            <p className="text-sm text-[var(--ks-color-text-muted)] mt-1">
              Cada linha representa uma combinação completa de atributos e possui estoque próprio.
            </p>
          </div>

          {variations.length === 0 ? (
            <div className="text-center py-8 text-slate-500 border border-dashed border-[var(--ks-color-border-subtle)] rounded-xl">
              Defina atributos e opções para gerar combinações.
            </div>
          ) : (
            <div className="space-y-3">
              {variations.map((variation, index) => (
                <div key={combinationSignature(variation.combination || {})} className="grid grid-cols-1 lg:grid-cols-[minmax(0,1fr)_160px_140px] gap-3 items-end rounded-xl border border-[var(--ks-color-border-subtle)] p-3">
                  <div>
                    <div className="text-xs text-slate-500 uppercase tracking-wider font-medium">Combinação</div>
                    <div className="text-sm font-medium text-slate-700">
                      {Object.entries(variation.combination || {})
                        .map(([name, label]) => `${name}: ${label}`)
                        .join(" / ")}
                    </div>
                  </div>
                  <Input
                    label="SKU"
                    value={variation.sku || ""}
                    onChange={(event) => updateVariation(index, { sku: event.target.value })}
                  />
                  {/* Combinação já salva: o saldo é o do extrato (vendas e
                      ajustes) e o salvar não o regrava mais. Mudar é pelo
                      histórico de estoque do produto. Só a combinação nova
                      recebe o saldo inicial aqui. */}
                  <EntradaDecimal
                    label="Estoque"
                    valor={variation.stock ?? 0}
                    casas={3}
                    disabled={Boolean(variation.id)}
                    description={variation.id ? "Saldo de agora. Para mudar, use o histórico de estoque do produto." : undefined}
                    aoMudar={(n) => updateVariation(index, { stock: Math.max(0, n) })}
                  />
                </div>
              ))}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

