/* global React, ReactDOM, MATERIALS, PRINTERS, FINISHING_PRESETS, PLATFORM_PRESETS, CD3D, fmtBRL, fmtNum, fmtPct, cdStorage */
const STEP_useState = React.useState;
const STEP_reverseCalc = window.CD3D.reverseCalc;

const STEPS = [
  { id: 0, label: "Material",    short: "MAT" },
  { id: 1, label: "Impressão",   short: "PRT" },
  { id: 2, label: "Mão de Obra", short: "LAB" },
  { id: 3, label: "Preço & Venda", short: "PRC" }
];

// ====================== UI Atoms ======================
function Field({ label, hint, children, full, req }) {
  return (
    <div className={"field" + (full ? " full" : "")}>
      <label>
        {label}{req && <span className="req">*</span>}
        {hint && <span className="help" data-tip={hint}>?</span>}
      </label>
      {children}
    </div>
  );
}

function NumInput({ value, onChange, min = 0, step = "any", max, suffix, prefix }) {
  const wrap = (el) => suffix ? (
    <div className="input-suffix" style={{ position: "relative" }}>{el}<span className="suffix">{suffix}</span></div>
  ) : prefix ? (
    <div className="input-prefix" style={{ position: "relative" }}>{el}<span className="prefix">{prefix}</span></div>
  ) : el;
  return wrap(
    <input
      type="number"
      className="input"
      value={value ?? ""}
      min={min}
      max={max}
      step={step}
      onChange={(e) => onChange(e.target.value === "" ? 0 : parseFloat(e.target.value))}
    />
  );
}

function TimeInput({ hours, minutes, onHours, onMinutes }) {
  return (
    <div className="time-row">
      <NumInput value={hours} onChange={onHours} suffix="h" />
      <NumInput value={minutes} onChange={onMinutes} max={59} suffix="min" />
    </div>
  );
}

function Switch({ on, onChange }) {
  return <button className={"switch" + (on ? " on" : "")} onClick={() => onChange(!on)} aria-pressed={on} />;
}

// ====================== Step 1: Material ======================
function StepMaterial({ s, set, advanced }) {
  const fdmMaterials = MATERIALS.filter(m => m.tech === "FDM");
  const resinMaterials = MATERIALS.filter(m => m.tech === "Resina");

  const applyMaterial = (m) => {
    set({ materialId: m.id, spoolCost: m.price, printerWatts: m.tech === "Resina" ? 60 : s.printerWatts, failureRate: m.waste });
  };

  return (
    <div>
      <div className="panel-header">
        <h2><span className="panel-num">01.</span> Material da Peça</h2>
        <span className="mode-tag">{advanced ? "Modo Avançado" : "Modo Simples"}</span>
      </div>
      <div className="panel-body">
        <div style={{ marginBottom: 16 }}>
          <label style={{ fontFamily: "var(--mono)", fontSize: 11, textTransform: "uppercase", color: "var(--text-dim)", letterSpacing: ".05em", marginBottom: 8, display: "block" }}>
            Biblioteca de Materiais
          </label>
          <div className="material-grid">
            {fdmMaterials.map(m => (
              <button key={m.id} className={"material-chip" + (s.materialId === m.id ? " active" : "")} onClick={() => applyMaterial(m)}>
                <span className="swatch" style={{ background: m.color }}></span>
                <span className="name">{m.name}</span>
                <span className="meta">R$ {m.price}/kg · {m.watts}W</span>
              </button>
            ))}
            {resinMaterials.map(m => (
              <button key={m.id} className={"material-chip" + (s.materialId === m.id ? " active" : "")} onClick={() => applyMaterial(m)}>
                <span className="swatch" style={{ background: m.color }}></span>
                <span className="name">{m.name}</span>
                <span className="meta">R$ {m.price}/kg · {m.watts}W</span>
              </button>
            ))}
          </div>
        </div>

        <div className="fgrid">
          <Field label="Peso da Peça" hint="Peso do objeto sem suportes, em gramas." req>
            <NumInput value={s.pieceWeight} onChange={(v) => set({ pieceWeight: v })} suffix="g" />
          </Field>
          <Field label="Peso dos Suportes" hint="Material adicional usado em suportes/balsa.">
            <NumInput value={s.supportWeight} onChange={(v) => set({ supportWeight: v })} suffix="g" />
          </Field>
          <Field label="Custo do Rolo" hint="Preço do rolo cheio do filamento.">
            <NumInput value={s.spoolCost} onChange={(v) => set({ spoolCost: v })} prefix="R$" />
          </Field>
          <Field label="Peso do Rolo" hint="Capacidade do rolo (geralmente 1000g).">
            <NumInput value={s.spoolWeight} onChange={(v) => set({ spoolWeight: v })} suffix="g" />
          </Field>
        </div>

        {advanced && (
          <div className="adv-section">
            <div style={{ fontFamily: "var(--mono)", fontSize: 11, textTransform: "uppercase", color: "var(--text-dim)", letterSpacing: ".05em", marginBottom: 10 }}>
              Multimaterial e Refugo
            </div>
            <div className="fgrid">
              <Field label="Trocas de Cor / Filamento" hint="Quantas trocas (AMS/MMU) durante a impressão. Cada troca consome material e tempo.">
                <NumInput value={s.filamentChanges} onChange={(v) => set({ filamentChanges: v })} suffix="x" />
              </Field>
              <Field label="Tempo por Troca" hint="Minutos por troca de filamento.">
                <NumInput value={s.changeMinutes} onChange={(v) => set({ changeMinutes: v })} suffix="min" />
              </Field>
              <Field label="Taxa de Falha" hint="% de peças que falham e precisam ser reimpressas. Aumenta o consumo de material.">
                <NumInput value={s.failureRate} onChange={(v) => set({ failureRate: v })} suffix="%" max={50} />
              </Field>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

// ====================== Step 2: Print ======================
function StepPrint({ s, set, advanced }) {
  const handlePrinter = (e) => {
    const val = e.target.value;
    if (val === "custom") return;
    const [group, name] = val.split("|");
    const grp = PRINTERS.find(g => g.group === group);
    const p = grp?.items.find(it => it.name === name);
    if (p) set({ printerName: `${group} ${name}`, printerWatts: p.watts, printerPrice: p.price });
  };

  const currentPrinterValue = (() => {
    for (const g of PRINTERS) {
      for (const it of g.items) {
        if (s.printerName === `${g.group} ${it.name}`) return `${g.group}|${it.name}`;
      }
    }
    return "custom";
  })();

  return (
    <div>
      <div className="panel-header">
        <h2><span className="panel-num">02.</span> Configuração de Impressão</h2>
        <span className="mode-tag">Energia + Tempo</span>
      </div>
      <div className="panel-body">
        <div className="fgrid">
          <Field label="Modelo da Impressora" hint="Selecione um modelo ou escolha 'Personalizado'." full>
            <select className="select" value={currentPrinterValue} onChange={handlePrinter}>
              {PRINTERS.map(g => (
                <optgroup key={g.group} label={g.group}>
                  {g.items.map(it => (
                    <option key={it.name} value={`${g.group}|${it.name}`}>{it.name} — {it.watts}W</option>
                  ))}
                </optgroup>
              ))}
              <option value="custom">Personalizado</option>
            </select>
          </Field>
          <Field label="Tempo de Impressão" hint="Tempo total estimado pelo slicer." req>
            <TimeInput hours={s.printHours} minutes={s.printMinutes}
              onHours={(v) => set({ printHours: v })} onMinutes={(v) => set({ printMinutes: v })} />
          </Field>
          <Field label="Consumo (Watts)" hint="Potência média da impressora em uso.">
            <NumInput value={s.printerWatts} onChange={(v) => set({ printerWatts: v })} suffix="W" />
          </Field>
          <Field label="Tarifa de Energia" hint="Preço do kWh na sua conta de luz.">
            <NumInput value={s.energyRate} onChange={(v) => set({ energyRate: v })} prefix="R$" step="0.01" />
          </Field>
          <Field label="Peças no Lote" hint="Quantas peças cabem em uma única impressão. O setup é diluído entre elas.">
            <NumInput value={s.batchPieces} onChange={(v) => set({ batchPieces: v })} min={1} suffix="pç" />
          </Field>
        </div>

        {advanced && (
          <div className="adv-section">
            <div style={{ fontFamily: "var(--mono)", fontSize: 11, textTransform: "uppercase", color: "var(--text-dim)", letterSpacing: ".05em", marginBottom: 10 }}>
              Depreciação da Impressora
            </div>
            <div className="fgrid">
              <Field label="Valor da Impressora" hint="Quanto custou a impressora.">
                <NumInput value={s.printerPrice} onChange={(v) => set({ printerPrice: v })} prefix="R$" />
              </Field>
              <Field label="Vida Útil Estimada" hint="Horas até manutenção pesada/troca. Padrão: 5000h.">
                <NumInput value={s.printerLifeHours} onChange={(v) => set({ printerLifeHours: v })} suffix="h" />
              </Field>
              <Field label="Setup do Lote" hint="Minutos de preparação por impressão (calibração, limpeza, troca de plataforma).">
                <NumInput value={s.bedSetupMinutes} onChange={(v) => set({ bedSetupMinutes: v })} suffix="min" />
              </Field>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

// ====================== Step 3: Labor ======================
function StepLabor({ s, set, advanced }) {
  return (
    <div>
      <div className="panel-header">
        <h2><span className="panel-num">03.</span> Mão de Obra & Pós-Processo</h2>
        <span className="mode-tag">Seu Tempo</span>
      </div>
      <div className="panel-body">
        <div className="fgrid">
          <Field label="Valor da sua Hora" hint="Quanto você cobra por hora de trabalho." req>
            <NumInput value={s.hourlyRate} onChange={(v) => set({ hourlyRate: v })} prefix="R$" suffix="/h" />
          </Field>
          <Field label="Acabamento" hint="Preset de acabamento aplicado por peça.">
            <select className="select" value={s.finishingId}
              onChange={(e) => {
                const p = FINISHING_PRESETS.find(x => x.id === e.target.value);
                set({ finishingId: p.id, finishingMinutes: p.minutes });
              }}>
              {FINISHING_PRESETS.map(p => (
                <option key={p.id} value={p.id}>{p.name} ({p.minutes}min)</option>
              ))}
            </select>
          </Field>
          <Field label="Tempo de Acabamento" hint="Lixa, primer, pintura, montagem (por peça).">
            <NumInput value={s.finishingMinutes} onChange={(v) => set({ finishingMinutes: v })} suffix="min" />
          </Field>
          <Field label="Embalagem por Peça" hint="Caixa, plástico-bolha, etiqueta.">
            <NumInput value={s.packagingCost} onChange={(v) => set({ packagingCost: v })} prefix="R$" step="0.01" />
          </Field>
          {advanced && (
            <Field label="Tempo de Design" hint="Horas de modelagem 3D (diluído na quantidade).">
              <NumInput value={s.designHours} onChange={(v) => set({ designHours: v })} suffix="h" step="0.1" />
            </Field>
          )}
        </div>
      </div>
    </div>
  );
}

// ====================== Step 4: Pricing ======================
function StepPricing({ s, set, advanced, calc }) {
  const [reverseTarget, setReverseTarget] = STEP_useState("");
  const reverse = reverseTarget ? STEP_reverseCalc(s, parseFloat(reverseTarget)) : null;

  return (
    <div>
      <div className="panel-header">
        <h2><span className="panel-num">04.</span> Preço & Venda</h2>
        <span className="mode-tag">Margem + Plataforma</span>
      </div>
      <div className="panel-body">
        <div className="fgrid">
          <Field label="Quantidade" hint="Total de peças neste pedido.">
            <NumInput value={s.quantity} onChange={(v) => set({ quantity: v })} min={1} suffix="pç" />
          </Field>
          <Field label="Margem de Lucro" hint="Lucro sobre o custo de produção.">
            <NumInput value={s.profitMargin} onChange={(v) => set({ profitMargin: v })} suffix="%" />
          </Field>
          <Field label="Plataforma de Venda" hint="A taxa é aplicada por cima para você receber o líquido desejado." full>
            <select className="select" value={s.platformId}
              onChange={(e) => {
                const p = PLATFORM_PRESETS.find(x => x.id === e.target.value);
                set({ platformId: p.id, platformFee: p.fee });
              }}>
              {PLATFORM_PRESETS.map(p => (
                <option key={p.id} value={p.id}>{p.name} ({p.fee}%)</option>
              ))}
            </select>
          </Field>
          {advanced && (
            <>
              <Field label="Taxa Personalizada" hint="Sobrescreve o preset de plataforma.">
                <NumInput value={s.platformFee} onChange={(v) => set({ platformFee: v })} suffix="%" />
              </Field>
              <Field label="Imposto" hint="ISS, Simples Nacional, etc.">
                <NumInput value={s.taxRate} onChange={(v) => set({ taxRate: v })} suffix="%" />
              </Field>
              <Field label="Frete" hint="Custo do frete (cliente paga ou embute no preço).">
                <NumInput value={s.shippingCost} onChange={(v) => set({ shippingCost: v })} prefix="R$" />
              </Field>
              <Field label="Frete embutido no preço" hint="Se ligado, o frete é somado ao preço final.">
                <div className="toggle-row" style={{ marginTop: 0 }}>
                  <span className="toggle-label">{s.shippingIncluded ? "Sim, embutido" : "Não, separado"}</span>
                  <Switch on={s.shippingIncluded} onChange={(v) => set({ shippingIncluded: v })} />
                </div>
              </Field>
            </>
          )}
        </div>

        {advanced && (
          <div className="reverse-card">
            <h4>↩ Calculadora Reversa: Quanto cobrar para...</h4>
            <div style={{ display: "grid", gridTemplateColumns: "1fr auto", gap: 10, alignItems: "end" }}>
              <Field label="Quero cobrar (preço final por peça)">
                <NumInput value={reverseTarget} onChange={(v) => setReverseTarget(v)} prefix="R$" />
              </Field>
              {reverse && (
                <div style={{ textAlign: "right" }}>
                  <div className="reverse-result">{fmtPct(reverse.margin)}</div>
                  <div className="reverse-sub">margem · lucro: {fmtBRL.format(reverse.profit)}</div>
                </div>
              )}
            </div>
          </div>
        )}

        <div className="adv-section">
          <div style={{ fontFamily: "var(--mono)", fontSize: 11, textTransform: "uppercase", color: "var(--text-dim)", letterSpacing: ".05em", marginBottom: 10 }}>
            Dados do Orçamento (opcional)
          </div>
          <div className="fgrid">
            <Field label="Cliente">
              <input className="input" value={s.clientName} onChange={(e) => set({ clientName: e.target.value })} placeholder="Ex: João Silva" />
            </Field>
            <Field label="Projeto">
              <input className="input" value={s.projectName} onChange={(e) => set({ projectName: e.target.value })} placeholder="Ex: Miniatura D&D" />
            </Field>
            <Field label="Validade (dias)">
              <NumInput value={s.validityDays} onChange={(v) => set({ validityDays: v })} suffix="dias" />
            </Field>
            <Field label="Nº Orçamento">
              <input className="input" value={s.quoteNumber} readOnly />
            </Field>
            <Field label="Observações" full>
              <textarea className="textarea" rows={2} value={s.observations}
                onChange={(e) => set({ observations: e.target.value })}
                placeholder="Detalhes sobre o projeto, condições especiais..."></textarea>
            </Field>
          </div>
        </div>
      </div>
    </div>
  );
}

window.CD3D_Steps = { StepMaterial, StepPrint, StepLabor, StepPricing, STEPS };
window.CD3D_UI = { Field, NumInput, TimeInput, Switch };
