/* ============================================================
   wizard.jsx — Shell do fluxo comercial (Etapas 1–6)
   ============================================================ */
function Wizard({ onCommit, onPaid, onExit, resume }) {
  // mapeia a etapa salva do pipeline -> passo do wizard para retomar
  const stageToStep = { reuniao: 1, proposta: 3, aceite: 4, pagamento: 6, contrato: 6, projeto: 6 };
  const startStep = resume ? (stageToStep[resume.stage] || 1) : 1;

  const [step, setStep] = React.useState(startStep);
  const [maxStep, setMaxStep] = React.useState(startStep);
  const [dealId, setDealId] = React.useState(resume ? resume.id : null);
  const [toast, setToast] = React.useState('');

  const [cliente, setCliente] = React.useState(
    resume ? { ...{ nome: '', empresa: '', doc: '', whatsapp: '', email: '', endereco: '' }, ...resume.cliente }
           : { nome: '', empresa: '', doc: '', whatsapp: '', email: '', endereco: '' });
  const [items, setItems] = React.useState(resume && resume.items ? resume.items.map(i => ({ ...i })) : []);
  const [pagamento, setPagamento] = React.useState(resume && resume.pagamento ? resume.pagamento : 'pix');
  const [obsGeral, setObsGeral] = React.useState(resume && resume.obsGeral ? resume.obsGeral : '');
  const [aceite, setAceite] = React.useState({ aceito: false, nome: '', cpf: '', assinado: false });
  const [pixCfg, setPixCfg] = React.useState({ ...window.PIX_DEFAULT });
  const createdAtRef = React.useRef(resume && resume.createdAt ? resume.createdAt : Date.now());
  const tokenRef = React.useRef(resume && resume.shareToken ? resume.shareToken : null);

  const total = items.reduce((s, i) => s + (Number(i.preco) || 0), 0);
  const recorrente = items.filter(i => i.tipo === 'recorrente').reduce((s, i) => s + (Number(i.preco) || 0), 0);

  const scrollRef = React.useRef(null);
  const go = (n) => { setStep(n); setMaxStep(m => Math.max(m, n)); if (scrollRef.current) scrollRef.current.scrollTop = 0; };
  const flash = (m) => { setToast(m); setTimeout(() => setToast(''), 2200); };

  React.useEffect(() => { if (resume) flash('Retomando · ' + (resume.cliente && resume.cliente.nome || 'cliente')); }, []);

  /* ----- serviços ----- */
  const toggleService = (svc) => {
    setItems(prev => prev.find(i => i.id === svc.id)
      ? prev.filter(i => i.id !== svc.id)
      : [...prev, { id: svc.id, nome: svc.nome, tipo: svc.tipo, cat: svc.cat, preco: svc.preco, prazo: svc.prazo, obs: '' }]);
  };
  const editItem = (id, patch) => setItems(prev => prev.map(i => i.id === id ? { ...i, ...patch } : i));
  const removeItem = (id) => setItems(prev => prev.filter(i => i.id !== id));

  const buildDeal = (stage) => ({
    id: dealId || window.uid(),
    cliente: { ...cliente },
    items: items.map(i => ({ ...i })),
    total, recorrente, pagamento, obsGeral,
    stage,
    createdAt: createdAtRef.current,
    updatedAt: Date.now(),
    ...(tokenRef.current ? { shareToken: tokenRef.current } : {}),
  });

  /* ----- gerar link do cliente (assina + paga pelo próprio aparelho) ----- */
  // fallbacks locais — funcionam mesmo se um data.js antigo estiver em cache no servidor
  const genToken = () => (typeof window.shareCode === 'function')
    ? window.shareCode()
    : (typeof window.shareToken === 'function' ? window.shareToken()
       : (Math.random().toString(36).slice(2) + Date.now().toString(36)).slice(0, 12));
  const encShare = (obj) => {
    if (typeof window.encodeShare === 'function') return window.encodeShare(obj);
    try {
      const b64 = btoa(unescape(encodeURIComponent(JSON.stringify(obj))));
      return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
    } catch (e) { return ''; }
  };
  const sendClientLink = async () => {
    if (!cliente.nome.trim()) { flash('Informe o nome do cliente.'); return null; }
    if (items.length === 0) { flash('Adicione ao menos um serviço.'); return null; }
    if (!tokenRef.current) tokenRef.current = genToken();
    const deal = buildDeal('proposta');
    setDealId(deal.id);
    // aguarda de fato a gravação na nuvem (se houver), para o link já achar o registro
    let cloudOk = true;
    try { await Promise.resolve(onCommit(deal)); }
    catch (e) { cloudOk = false; console.warn('Falha ao salvar na nuvem antes de gerar link', e); }
    const base = location.origin + location.pathname;
    if (cloudOk) {
      // link curto: só o código; os dados são buscados na nuvem
      flash('Link gerado · negócio em Proposta Enviada ✓');
      return base + '?c=' + encodeURIComponent(tokenRef.current);
    }
    // sem nuvem: embute os dados no link (maior, porém funcional)
    const enc = encShare({
      id: deal.id, cliente: deal.cliente, items: deal.items, total: deal.total,
      recorrente: deal.recorrente, pagamento: deal.pagamento, obsGeral: deal.obsGeral,
    });
    flash('Link gerado (dados no próprio link)');
    return base + '?p=' + encodeURIComponent(deal.id) + '&t=' + encodeURIComponent(tokenRef.current) + '&d=' + encodeURIComponent(enc);
  };

  /* ----- validações de avanço ----- */
  const next = () => {
    if (step === 1) {
      if (!cliente.nome.trim()) return flash('Informe ao menos o nome do cliente.');
      return go(2);
    }
    if (step === 3) {
      if (!pagamento) return flash('Selecione a forma de pagamento.');
      return go(4);
    }
    if (step === 4) {
      if (!aceite.aceito) return flash('É necessário marcar o aceite dos termos.');
      if (!aceite.nome.trim()) return flash('Informe o nome de quem aceita.');
      const deal = buildDeal('aceite');
      setDealId(deal.id);
      onCommit(deal);
      flash('Aceite registrado no pipeline ✓');
      return go(5);
    }
    if (step === 5) return go(6);
  };

  const finishPayment = () => {
    if (dealId) onPaid(dealId);
    flash('Pagamento confirmado ✓');
    setTimeout(() => onExit('pipeline'), 700);
  };

  /* ----- salvar progresso numa etapa anterior do pipeline ----- */
  const stageForStep = { 1: 'reuniao', 2: 'proposta', 3: 'proposta' };
  const saveProgress = () => {
    if (!cliente.nome.trim()) return flash('Informe o nome do cliente para salvar.');
    if (step >= 3 && items.length === 0) return flash('Selecione ao menos um serviço para salvar a proposta.');
    const stage = stageForStep[step] || 'proposta';
    const deal = buildDeal(stage);
    setDealId(deal.id);
    onCommit(deal);
    const nome = (window.PIPELINE_STAGES.find(s => s.id === stage) || {}).nome;
    flash((dealId ? 'Atualizado' : 'Salvo') + ' no pipeline · ' + nome + ' ✓');
  };
  const showSave = step === 1 || step === 3;

  /* ----- footer CTA por etapa ----- */
  const footer = () => {
    if (step === 2) return null; // o carrinho controla o avanço
    const cfg = {
      1: { label: 'Continuar', icon: 'arrowR', variant: 'primary' },
      3: { label: 'Gerar termo de aceite', icon: 'doc', variant: 'primary' },
      4: { label: 'Confirmar aceite', icon: 'check', variant: 'yellow' },
      5: { label: 'Ir para pagamento', icon: 'arrowR', variant: 'primary' },
    }[step];
    return (
      <div className="wiz-foot">
        <Button variant="subtle" icon="arrowL" style={{ marginRight: 'auto' }} onClick={() => step > 1 ? go(step - 1) : onExit('pipeline')}>
          {step > 1 ? 'Voltar' : 'Sair'}
        </Button>
        {showSave && (
          <Button variant="ghost" icon="layers" onClick={saveProgress}>Salvar no pipeline</Button>
        )}
        {step === 6 ? (
          <Button size="lg" variant="yellow" icon="check" onClick={finishPayment}>Já realizei o pagamento</Button>
        ) : cfg ? (
          <Button size="lg" variant={cfg.variant} iconR={cfg.icon === 'arrowR' ? 'arrowR' : null} icon={cfg.icon !== 'arrowR' ? cfg.icon : null} onClick={next}>
            {cfg.label}
          </Button>
        ) : null}
      </div>
    );
  };

  return (
    <div className="wizard">
      <Stepper step={step} maxStep={maxStep} onJump={go} />
      <div className="wiz-scroll" ref={scrollRef}>
        {step === 1 && <StepCadastro cliente={cliente} setCliente={setCliente} />}
        {step === 2 && (
          <StepServicos items={items} toggleService={toggleService} editItem={editItem} removeItem={removeItem}
            total={total} recorrente={recorrente} cliente={cliente} onAdvance={() => go(3)} />
        )}
        {step === 3 && (
          <StepResumo cliente={cliente} items={items} total={total} recorrente={recorrente}
            pagamento={pagamento} setPagamento={setPagamento} obsGeral={obsGeral} setObsGeral={setObsGeral} />
        )}
        {step === 4 && (
          <StepAceite cliente={cliente} items={items} total={total} recorrente={recorrente}
            pagamento={pagamento} obsGeral={obsGeral} aceite={aceite} setAceite={setAceite} onClientLink={sendClientLink} />
        )}
        {step === 5 && <StepCompartilhar cliente={cliente} items={items} total={total} pagamento={pagamento} assinaturaImg={aceite.assinaturaImg} />}
        {step === 6 && <StepPagamento total={total} pixCfg={pixCfg} setPixCfg={setPixCfg} />}
      </div>
      {footer()}
      {toast && <div className="toast fade-up">{toast}</div>}
    </div>
  );
}

Object.assign(window, { Wizard });
