"use client";

import { useEffect, useState } from "react";
import { X, Save, Loader2, AlertTriangle } from "lucide-react";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { InfoTooltip } from "@/components/ui/info-tooltip";
import { CustomSelect } from "@/components/ui/custom-select";
import { formatMoneyInput, parseMoneyInput, formatMoney } from "@/utils/formatters";
import { numeroDoTexto, textoDecimalValido, textoDoNumero } from "@/components/ui/campo-decimal";
import {
  FORMATOS, conteudoDaEmbalagem, formatoValido, type FormatoDeCompra,
} from "@/lib/precificacao/formato-de-compra";

/**
 * O modal de insumo — o mesmo no cadastro de insumos e no assistente de
 * precificação.
 *
 * O assistente tinha uma versão resumida dentro de um dropdown; a página de
 * insumos, a completa. Duas telas cadastrando a mesma coisa por caminhos
 * diferentes é onde a incoerência mora: um modal só, os dois lugares.
 */

export type InsumoParaEditar = {
  id: string;
  name: string;
  unit: string;
  cost_per_unit: number;
  waste_pct_default: number;
  purchase_format?: string | null;
  roll_width_m?: number | null;
  roll_length_m?: number | null;
  package_qty?: number | null;
  sheet_width_m?: number | null;
  sheet_height_m?: number | null;
  /* Serviço modelado como insumo (corte terceirizado): entra no custo, não
     se separa nem baixa estoque. */
  is_service?: boolean | null;
};

/* Exportada porque a listagem de insumos rotula a unidade pela mesma tabela. */
export const UNIDADES_DE_INSUMO = [
  { value: "un", label: "Unidade (un)" },
  { value: "m", label: "Metro Linear (m)" },
  { value: "m2", label: "Metro Quadrado (m²)" },
  { value: "kg", label: "Quilograma (kg)" },
  { value: "l", label: "Litro (l)" },
  { value: "ml", label: "Mililitro (ml)" },
  { value: "folha", label: "Folha" },
];

const numeroDoCampo = (v: string) => Number(v.replace(",", ".")) || 0;
const campoDoNumero = (n: number | null | undefined) =>
  n != null && n > 0 ? String(n).replace(".", ",") : "";

const qtdEnxuta = (n: number) =>
  new Intl.NumberFormat("pt-BR", { maximumFractionDigits: 3 }).format(n || 0);

const FORM_VAZIO = {
  name: "", unit: "un", cost_per_unit: "0,00", waste_pct_default: "0", is_service: false,
  formato: "unidade", largura: "", comprimento: "", conteudo: "",
  folha_l: "", folha_a: "", preco_embalagem: "",
};

/* Especificação da embalagem a partir do formulário (strings da tela). */
function specDoForm(f: typeof FORM_VAZIO) {
  return {
    formato: formatoValido(f.formato),
    larguraM: numeroDoCampo(f.largura),
    comprimentoM: numeroDoCampo(f.comprimento),
    conteudoDaEmbalagem: numeroDoCampo(f.conteudo),
    folhaLarguraM: numeroDoCampo(f.folha_l),
    folhaAlturaM: numeroDoCampo(f.folha_a),
  };
}

export function ModalDeInsumo({ aberta, insumo, nomeInicial, aoFechar, aoSalvar }: {
  aberta: boolean;
  /** Presente = edição; ausente = insumo novo. */
  insumo?: InsumoParaEditar | null;
  /** Pré-preenche o nome no cadastro (a busca que não achou vira o nome). */
  nomeInicial?: string;
  aoFechar: () => void;
  /** Recebe a linha que o banco devolveu, já com id. */
  aoSalvar: (salvo: InsumoParaEditar) => void;
}) {
  const [form, setForm] = useState({ ...FORM_VAZIO });
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState("");

  useEffect(() => {
    if (!aberta) return;
    setError("");
    if (insumo) {
      setForm({
        name: insumo.name,
        unit: insumo.unit,
        cost_per_unit: formatMoneyInput(insumo.cost_per_unit),
        waste_pct_default: textoDoNumero(insumo.waste_pct_default ?? 0),
        is_service: insumo.is_service === true,
        formato: formatoValido(insumo.purchase_format),
        largura: campoDoNumero(insumo.roll_width_m),
        comprimento: campoDoNumero(insumo.roll_length_m),
        conteudo: campoDoNumero(insumo.package_qty),
        folha_l: campoDoNumero(insumo.sheet_width_m),
        folha_a: campoDoNumero(insumo.sheet_height_m),
        preco_embalagem: "",
      });
    } else {
      setForm({ ...FORM_VAZIO, name: nomeInicial ?? "" });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [aberta]);

  const salvar = async (e: React.FormEvent) => {
    e.preventDefault();
    setSaving(true);
    setError("");
    try {
      /* Formato de compra: o custo unitário pode vir derivado do preço da
         embalagem — a conta é do sistema, não da calculadora. */
      const spec = specDoForm(form);
      const conteudo = conteudoDaEmbalagem(spec);
      const precoEmb = parseMoneyInput(form.preco_embalagem);
      const costVal =
        spec.formato !== "unidade" && precoEmb > 0 && conteudo > 0
          ? Math.round((precoEmb / conteudo) * 10000) / 10000
          : parseMoneyInput(form.cost_per_unit);

      const payload = {
        name: form.name,
        unit: form.unit,
        cost_per_unit: costVal,
        waste_pct_default: numeroDoTexto(form.waste_pct_default),
        is_service: form.is_service,
        purchase_format: spec.formato,
        roll_width_m: spec.larguraM || null,
        roll_length_m: spec.comprimentoM || null,
        package_qty: spec.conteudoDaEmbalagem || null,
        sheet_width_m: spec.folhaLarguraM || null,
        sheet_height_m: spec.folhaAlturaM || null,
      };
      const res = await fetch("/api/production/materials", {
        method: insumo ? "PUT" : "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(insumo ? { ...payload, id: insumo.id } : payload),
      });
      const json = await res.json().catch(() => null);
      if (!res.ok) throw new Error(json?.error || "Erro ao salvar.");
      aoSalvar((json?.data ?? json) as InsumoParaEditar);
      aoFechar();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Erro ao salvar.");
    } finally {
      setSaving(false);
    }
  };

  if (!aberta) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4 animate-in fade-in">
      <div className="bg-white rounded-xl shadow-xl w-full max-w-md overflow-hidden animate-in zoom-in-95 duration-200">
        <div className="flex items-center justify-between p-4 border-b bg-slate-50/50">
          <h2 className="text-lg font-semibold text-slate-800">
            {insumo ? "Editar Insumo" : "Novo Insumo"}
          </h2>
          <Button size="icon" variant="ghost" onClick={aoFechar}>
            <X className="h-4 w-4" />
          </Button>
        </div>

        <form onSubmit={salvar} className="p-6 space-y-4 max-h-[80vh] overflow-y-auto">
          <div className="space-y-2">
            <label className="text-sm font-medium text-slate-700">Nome do Material</label>
            <Input
              required
              value={form.name}
              onChange={(e) => setForm({ ...form, name: e.target.value })}
              placeholder="Ex: MDF 15mm Branco"
            />
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <label className="text-sm font-medium text-slate-700 inline-flex items-center">Como você compra?<InfoTooltip text="O formato da embalagem: bobina, resma, chapa, caixa… O sistema converte para a unidade de consumo e calcula o custo unitário sozinho — sem calculadora." /></label>
              <CustomSelect
                options={(Object.keys(FORMATOS) as FormatoDeCompra[]).map((f) => ({ value: f, label: FORMATOS[f].rotulo }))}
                value={form.formato}
                onChange={(val) => {
                  const f = formatoValido(val);
                  /* Trocar o formato sugere a unidade de consumo coerente
                     — sugestão: dá para trocar depois. */
                  setForm({ ...form, formato: f, unit: f === "unidade" ? form.unit : FORMATOS[f].unidadeSugerida });
                }}
                placeholder="Selecione..."
              />
            </div>
            <div className="space-y-2">
              <label className="text-sm font-medium text-slate-700 inline-flex items-center">Unidade de consumo<InfoTooltip text="A unidade em que a ficha técnica gasta o insumo: m² para lona, folha para papel, ml para tinta, metro para torsal. É nela que o estoque baixa." /></label>
              <CustomSelect
                options={UNIDADES_DE_INSUMO}
                value={form.unit}
                onChange={(val) => setForm({ ...form, unit: val })}
                placeholder="Selecione..."
              />
            </div>
          </div>

          {/* Os campos da embalagem, no idioma de cada formato. */}
          {form.formato === "bobina" && (
            <div className="grid grid-cols-2 gap-4">
              <CampoDeSpec rotulo="Largura da bobina (m)" valor={form.largura}
                aoMudar={(v) => setForm({ ...form, largura: v })} placeholder="1,60"
                dica="A largura fixa do rolo. É ela que calcula a perda de rodagem na precificação e a baixa real no estoque — a peça ocupa a largura inteira da bobina." />
              <CampoDeSpec rotulo="Comprimento (m)" valor={form.comprimento}
                aoMudar={(v) => setForm({ ...form, comprimento: v })} placeholder="50" />
            </div>
          )}
          {form.formato === "rolo" && (
            <CampoDeSpec rotulo="Metros por rolo" valor={form.comprimento}
              aoMudar={(v) => setForm({ ...form, comprimento: v })} placeholder="500" />
          )}
          {form.formato === "chapa" && (
            <div className="grid grid-cols-2 gap-4">
              <CampoDeSpec rotulo="Largura da chapa (m)" valor={form.folha_l}
                aoMudar={(v) => setForm({ ...form, folha_l: v })} placeholder="1,22" />
              <CampoDeSpec rotulo="Altura da chapa (m)" valor={form.folha_a}
                aoMudar={(v) => setForm({ ...form, folha_a: v })} placeholder="2,44" />
            </div>
          )}
          {(form.formato === "resma" || form.formato === "caixa" ||
            form.formato === "galao" || form.formato === "pacote") && (
            <CampoDeSpec
              rotulo={form.formato === "resma" ? "Folhas por resma"
                : form.formato === "caixa" ? "Unidades por caixa"
                : form.formato === "galao" ? `Conteúdo por galão (${form.unit})`
                : "Peso por pacote (kg)"}
              valor={form.conteudo}
              aoMudar={(v) => setForm({ ...form, conteudo: v })}
              placeholder={form.formato === "resma" ? "500" : form.formato === "caixa" ? "36" : "1"}
            />
          )}

          {form.formato === "unidade" ? (
            <div className="space-y-2">
              <label className="text-sm font-medium text-slate-700 inline-flex items-center">Custo Unitário<InfoTooltip text="Quanto custa UMA unidade de consumo. Nas entradas de estoque este valor vira a média ponderada do que você realmente pagou." /></label>
              <Input
                value={form.cost_per_unit}
                onChange={(e) => setForm({ ...form, cost_per_unit: formatMoneyInput(e.target.value) })}
                placeholder="0,00"
              />
            </div>
          ) : (
            <div className="space-y-2">
              <label className="text-sm font-medium text-slate-700">
                Preço de 1 {FORMATOS[formatoValido(form.formato)].embalagem}
              </label>
              <Input
                value={form.preco_embalagem}
                onChange={(e) => setForm({ ...form, preco_embalagem: formatMoneyInput(e.target.value) })}
                placeholder="0,00"
              />
              {(() => {
                /* A conta mastigada, na hora: a resma de 500 por R$ 45
                   vira R$ 0,09 a folha sem calculadora. */
                const conteudo = conteudoDaEmbalagem(specDoForm(form));
                const preco = parseMoneyInput(form.preco_embalagem);
                if (conteudo > 0 && preco > 0) {
                  return (
                    <p className="text-xs text-slate-500">
                      1 {FORMATOS[formatoValido(form.formato)].embalagem} = {qtdEnxuta(conteudo)} {form.unit} →{" "}
                      <strong>{formatMoney(preco / conteudo)}</strong> por {form.unit}
                    </p>
                  );
                }
                if (preco > 0) {
                  return <p className="text-xs text-amber-600">Preencha a embalagem acima para o custo sair sozinho.</p>;
                }
                return insumo
                  ? <p className="text-xs text-slate-500">Sem preço novo, o custo atual ({formatMoney(parseMoneyInput(form.cost_per_unit))}/{form.unit}) fica como está.</p>
                  : null;
              })()}
            </div>
          )}

          <label className="flex items-start gap-2 rounded-lg border border-slate-200 px-3 py-2 cursor-pointer">
            <input
              type="checkbox"
              checked={form.is_service}
              onChange={(e) => setForm({ ...form, is_service: e.target.checked })}
              className="mt-0.5"
            />
            <span className="text-sm text-slate-700">
              <span className="font-medium">É um serviço, não um material</span>
              <span className="block text-xs text-slate-500">
                Corte terceirizado, impressão de fora, arte cobrada à parte. Entra no custo do produto, mas não aparece no checklist de separação nem baixa estoque.
              </span>
            </span>
          </label>

          <div className="space-y-2">
            <div className="flex items-center justify-between">
              <label className="text-sm font-medium text-slate-700 inline-flex items-center">
                Perda Padrão (%)
                <InfoTooltip text="Margem de segurança para quebras ou sobras no corte. Para insumo em bobina, a precificação calcula a perda de rodagem sozinha a partir da largura — este valor fica como sugestão para os demais casos." />
              </label>
              <span className="text-xs text-slate-400">Opcional</span>
            </div>
            <div className="relative">
              <Input
                inputMode="decimal"
                value={form.waste_pct_default}
                onChange={(e) => { if (textoDecimalValido(e.target.value)) setForm({ ...form, waste_pct_default: e.target.value }); }}
                placeholder="0"
                className="pr-8"
              />
              <span className="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 text-sm">%</span>
            </div>
          </div>

          {error && (
            <div className="text-sm text-red-600 bg-red-50 p-3 rounded-md flex items-center gap-2">
              <AlertTriangle className="h-4 w-4" />
              {error}
            </div>
          )}

          <div className="flex justify-end gap-3 pt-4 border-t mt-6">
            <Button type="button" variant="ghost" onClick={aoFechar}>
              Cancelar
            </Button>
            <Button type="submit" disabled={saving}>
              {saving ? <Loader2 className="h-4 w-4 animate-spin mr-2" /> : <Save className="h-4 w-4 mr-2" />}
              Salvar
            </Button>
          </div>
        </form>
      </div>
    </div>
  );
}

function CampoDeSpec({ rotulo, valor, aoMudar, placeholder, dica }: {
  rotulo: string; valor: string; aoMudar: (v: string) => void; placeholder?: string; dica?: string;
}) {
  return (
    <div className="space-y-2">
      <label className="text-sm font-medium text-slate-700 inline-flex items-center">
        {rotulo}
        {dica && <InfoTooltip text={dica} />}
      </label>
      <Input inputMode="decimal" value={valor} placeholder={placeholder}
        onChange={(e) => aoMudar(e.target.value)} />
    </div>
  );
}
