const { useEffect, useRef, useState } = React;

const styles = {
  bgLayer: {
    position: 'fixed',
    inset: 0,
    background: 'var(--bg)',
    backgroundImage: 'radial-gradient(circle at 20% 10%, rgba(46,143,216,.08) 0%, transparent 50%), radial-gradient(circle at 80% 90%, rgba(46,143,216,.06) 0%, transparent 50%)',
    zIndex: 0
  },
  page: {
    position: 'relative',
    zIndex: 1,
    width: '100%',
    minHeight: '100dvh',
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'flex-start',
    padding: '16px',
    fontFamily: "'Outfit', sans-serif",
    color: 'var(--text)',
    lineHeight: 1.5
  },
  appShell: {
    width: '100%',
    maxWidth: '440px',
    paddingTop: '8px',
    minWidth: 0
  },
  card: {
    background: 'var(--bg-card)',
    borderRadius: 'var(--radius)',
    padding: '24px 20px',
    boxShadow: 'var(--shadow-lg)',
    marginBottom: '16px',
    boxSizing: 'border-box',
    minWidth: 0
  },
  stepContent: {
    display: 'flex',
    flexDirection: 'column',
    gap: '0'
  },
  title: { fontSize: '1.75rem', lineHeight: 1.15, marginBottom: '12px', textAlign: 'center', color: 'var(--primary-dark)', fontWeight: 800, letterSpacing: '-0.02em' },
  subtitle: { fontSize: '0.95rem', color: 'var(--text-muted)', marginBottom: '18px', textAlign: 'center' },
  label: { fontSize: '0.78rem', fontWeight: 600, marginBottom: '6px', display: 'block', color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.06em' },
  hint: { fontSize: '0.8rem', color: 'var(--text-muted)', marginBottom: '6px' },
  error: { color: '#dc2626', fontSize: '0.82rem', marginTop: '4px', fontWeight: 600 },
  info: { color: 'var(--text)', fontSize: '0.95rem', marginTop: '8px' },
  good: { color: 'var(--success)', fontSize: '0.95rem', marginTop: '8px', fontWeight: 600 },
  warn: { color: 'var(--primary)', fontSize: '0.95rem', marginTop: '8px', fontWeight: 600 },
  button: {
    width: '100%',
    height: '54px',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: '8px',
    border: 'none',
    borderRadius: 'var(--radius)',
    background: 'var(--primary)',
    color: '#fff',
    fontFamily: "'Outfit', sans-serif",
    fontSize: '0.95rem',
    fontWeight: 600,
    cursor: 'pointer',
    marginTop: '10px',
    padding: '0 16px',
    boxShadow: '0 4px 16px rgba(26,111,181,.3)',
    WebkitTapHighlightColor: 'transparent',
    transition: 'all .2s ease'
  },
  secondaryButton: {
    width: '100%',
    height: '54px',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: '8px',
    border: '1.5px solid var(--border)',
    borderRadius: 'var(--radius)',
    background: 'var(--bg-card)',
    color: 'var(--primary)',
    fontFamily: "'Outfit', sans-serif",
    fontSize: '0.95rem',
    fontWeight: 600,
    cursor: 'pointer',
    marginTop: '10px',
    padding: '0 16px',
    boxShadow: 'var(--shadow-sm)',
    WebkitTapHighlightColor: 'transparent',
    transition: 'all .2s ease'
  },
  map: {
    width: '100%',
    height: '280px',
    border: '1.5px solid var(--border)',
    borderRadius: 'var(--radius)',
    marginTop: '10px'
  },
  choiceWrap: {
    display: 'flex',
    flexWrap: 'wrap',
    gap: '8px',
    marginBottom: '12px'
  },
  choiceButton: {
    flex: '1',
    minWidth: 'calc(50% - 4px)',
    height: '44px',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: '6px',
    fontFamily: "'Outfit', sans-serif",
    fontSize: '0.85rem',
    fontWeight: 500,
    color: 'var(--text-muted)',
    background: 'var(--input-bg)',
    border: '1.5px solid var(--border)',
    borderRadius: 'var(--radius-sm)',
    cursor: 'pointer',
    transition: 'all .2s ease',
    WebkitTapHighlightColor: 'transparent',
    userSelect: 'none'
  },
  choiceButtonActive: {
    background: 'var(--primary)',
    borderColor: 'var(--primary)',
    color: '#fff',
    boxShadow: '0 2px 8px rgba(26,111,181,.25)'
  },
  modalOverlay: {
    position: 'fixed',
    inset: 0,
    background: 'rgba(0,0,0,0.45)',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    padding: '16px',
    zIndex: 50
  },
  modalCard: {
    width: '100%',
    maxWidth: '440px',
    background: 'var(--bg-card)',
    borderRadius: 'var(--radius)',
    border: '1px solid var(--border)',
    padding: '24px 20px',
    boxShadow: 'var(--shadow-lg)'
  },
  uploadZone: {
    width: '100%',
    maxWidth: '100%',
    minWidth: 0,
    boxSizing: 'border-box',
    border: '2px dashed var(--border)',
    borderRadius: 'var(--radius)',
    padding: '24px 18px',
    textAlign: 'center',
    background: 'var(--input-bg)',
    cursor: 'pointer'
  },
  revealBlock: {
    animation: 'fadeUp .4s ease both'
  },
  privacyBanner: {
    marginTop: '14px',
    marginBottom: '8px',
    padding: '14px 18px',
    borderRadius: 'var(--radius-sm)',
    border: '1.5px solid var(--border)',
    background: 'var(--primary-light)',
    color: 'var(--text)',
    fontSize: '0.88rem',
    lineHeight: 1.45,
    textAlign: 'center'
  },
  emailProviderRow: {
    display: 'flex',
    flexWrap: 'wrap',
    gap: '8px',
    marginTop: '10px',
    width: '100%'
  },
  emailProviderButton: {
    flex: '1',
    minWidth: 'calc(50% - 4px)',
    height: '44px',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: '6px',
    fontFamily: "'Outfit', sans-serif",
    fontSize: '0.85rem',
    fontWeight: 500,
    color: 'var(--text-muted)',
    background: 'var(--input-bg)',
    border: '1.5px solid var(--border)',
    borderRadius: 'var(--radius-sm)',
    cursor: 'pointer',
    transition: 'all .2s ease',
    WebkitTapHighlightColor: 'transparent'
  },
  emailProviderButtonActive: {
    background: 'var(--primary)',
    borderColor: 'var(--primary)',
    color: '#fff',
    boxShadow: '0 2px 8px rgba(26,111,181,.25)'
  },
  emailSkipLink: {
    display: 'block',
    width: '100%',
    marginTop: '10px',
    padding: '10px',
    fontFamily: "'Outfit', sans-serif",
    fontSize: '0.82rem',
    fontWeight: 500,
    color: 'var(--text-muted)',
    background: 'none',
    border: 'none',
    cursor: 'pointer',
    textDecoration: 'underline',
    textUnderlineOffset: '2px',
    WebkitTapHighlightColor: 'transparent',
    textAlign: 'center'
  }
};

function onlyDigits(v) {
  return String(v || '').replace(/\D/g, '');
}

function maskCpf(value) {
  const d = onlyDigits(value).slice(0, 11);
  if (d.length <= 3) return d;
  if (d.length <= 6) return `${d.slice(0, 3)}.${d.slice(3)}`;
  if (d.length <= 9) return `${d.slice(0, 3)}.${d.slice(3, 6)}.${d.slice(6)}`;
  return `${d.slice(0, 3)}.${d.slice(3, 6)}.${d.slice(6, 9)}-${d.slice(9, 11)}`;
}

function maskPhone(value) {
  const d = onlyDigits(value).slice(0, 11);
  if (d.length <= 2) return d;
  if (d.length <= 6) return `(${d.slice(0, 2)}) ${d.slice(2)}`;
  if (d.length <= 10) return `(${d.slice(0, 2)}) ${d.slice(2, 6)}-${d.slice(6)}`;
  return `(${d.slice(0, 2)}) ${d.slice(2, 7)}-${d.slice(7, 11)}`;
}

function maskCep(value) {
  const d = onlyDigits(value).slice(0, 8);
  if (d.length <= 5) return d;
  return `${d.slice(0, 5)}-${d.slice(5, 8)}`;
}

function isEmailValid(value) {
  const email = String(value || '').trim();
  return /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(email);
}

/** API MK: data_nascimento "YYYY-MM-DD" -> exibição DD/MM/AAAA */
function nascimentoApiToBr(value) {
  const s = String(value || '').trim();
  const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(s);
  if (!m) return '';
  return `${m[3]}/${m[2]}/${m[1]}`;
}

/**
 * Só o nosso Express (/api/*). A verificação de CPF: browser -> POST /api/mk/score-decision-cpf -> server.js -> API MK :5087.
 * Use a mesma origem do Node (abra pelo `node server.js`) para não precisar de CORS. Se usar Live Server em outra porta,
 * preencha meta app-api-base com a URL do Node (ex. http://IP:5173).
 */
function appApiUrl(path) {
  const p = path.startsWith('/') ? path : `/${path}`;
  if (typeof window === 'undefined') return p;
  const win =
    typeof window.__APP_API_BASE__ === 'string'
      ? window.__APP_API_BASE__.trim()
      : '';
  const metaEl = document.querySelector('meta[name="app-api-base"]');
  const meta = metaEl ? String(metaEl.getAttribute('content') || '').trim() : '';
  const base = (win || meta).replace(/\/$/, '');
  return base ? `${base}${p}` : p;
}

const PESSOAS_RANGE_OPTIONS = [
  { id: 'so-eu', label: 'So eu' },
  { id: '2-3', label: '2 a 3 pessoas' },
  { id: '4+', label: '4 ou mais' }
];

const USO_OPTIONS = [
  { id: 'redes-sociais', label: 'Redes sociais e navegacao' },
  { id: 'trabalho-estudo', label: 'Trabalho e estudo' },
  { id: 'jogos', label: 'Jogos online' },
  { id: 'streaming', label: 'Videos, lives e streaming' }
];

function formatPlanPrice(vlrFinal) {
  const n = Number(vlrFinal);
  if (!Number.isFinite(n)) return 'Consulte';
  return n.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' }) + '/mes';
}

const mm = {
  cpf: maskCpf,
  cep: maskCep,
  phone: maskPhone
};

const EMAIL_PRESETS = {
  gmail: '@gmail.com',
  outlook: '@outlook.com',
  hotmail: '@hotmail.com'
};

const DEFAULT_MAP_CENTER = { lat: -20.0753, lng: -44.5763 }; // Itauna/MG

function emailLocalFromValue(cadEmail, provider) {
  if (!cadEmail) return '';
  if (provider === 'custom') return cadEmail;
  const at = cadEmail.indexOf('@');
  if (at === -1) return cadEmail.replace(/@/g, '');
  return cadEmail.slice(0, at).replace(/@/g, '');
}

function InputField({
  id,
  label,
  hint,
  value,
  onChange,
  onBlur,
  placeholder,
  readOnly,
  type,
  inputMode,
  inputClassName,
  error,
  fieldSize,
  inputRef
}) {
  const safeId =
    id ||
    `fld-${label
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/(^-|-$)/g, '')}`;
  const hintId = hint ? `${safeId}-hint` : null;
  const errorId = error ? `${safeId}-error` : null;
  const describedBy = [hintId, errorId].filter(Boolean).join(' ') || undefined;
  const filled = value && String(value).trim().length > 0;

  return (
    <div className="form-group">
      <label htmlFor={safeId} className="form-label">{label}</label>
      <input
        id={safeId}
        ref={inputRef}
        className={`form-input${filled && !error ? ' filled' : ''}${error ? ' has-error' : ''}${readOnly ? ' readonly' : ''}${inputClassName ? ` ${inputClassName}` : ''}`}
        value={value}
        onChange={onChange}
        onBlur={onBlur}
        placeholder={placeholder || ''}
        readOnly={readOnly}
        type={type || 'text'}
        inputMode={inputMode}
        aria-invalid={error ? 'true' : 'false'}
        aria-describedby={describedBy}
      />
      {hint ? <div id={hintId} className="form-hint">{hint}</div> : null}
      {error ? <div id={errorId} className="form-error">{error}</div> : null}
    </div>
  );
}

function useIsMobileViewport(query = '(max-width: 600px)') {
  const [matches, setMatches] = useState(() =>
    typeof window !== 'undefined' && typeof window.matchMedia === 'function'
      ? window.matchMedia(query).matches
      : false
  );
  useEffect(() => {
    if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return;
    const mql = window.matchMedia(query);
    const onChange = () => setMatches(mql.matches);
    if (mql.addEventListener) mql.addEventListener('change', onChange);
    else if (mql.addListener) mql.addListener(onChange);
    return () => {
      if (mql.removeEventListener) mql.removeEventListener('change', onChange);
      else if (mql.removeListener) mql.removeListener(onChange);
    };
  }, [query]);
  return matches;
}

function useSignaturePadLibReady() {
  const [ready, setReady] = useState(
    typeof window !== 'undefined' && !!window.SignaturePad
  );
  useEffect(() => {
    if (typeof window === 'undefined' || window.SignaturePad || ready) return;
    const id = setInterval(() => {
      if (window.SignaturePad) {
        setReady(true);
        clearInterval(id);
      }
    }, 120);
    return () => clearInterval(id);
  }, [ready]);
  return ready;
}

function DesktopSignaturePad({ onChange, height = 180 }) {
  const canvasRef = useRef(null);
  const padRef = useRef(null);
  const [isEmpty, setIsEmpty] = useState(true);
  const libReady = useSignaturePadLibReady();

  useEffect(() => {
    if (!libReady) return;
    const canvas = canvasRef.current;
    if (!canvas) return;

    const resize = () => {
      const ratio = Math.max(window.devicePixelRatio || 1, 1);
      canvas.width = canvas.offsetWidth * ratio;
      canvas.height = canvas.offsetHeight * ratio;
      canvas.getContext('2d').scale(ratio, ratio);
      if (padRef.current) {
        padRef.current.clear();
        setIsEmpty(true);
        onChange(null);
      }
    };

    const pad = new window.SignaturePad(canvas, {
      backgroundColor: 'rgb(255, 255, 255)',
      penColor: 'rgb(28, 58, 82)',
      minWidth: 0.8,
      maxWidth: 2.5
    });
    padRef.current = pad;
    resize();
    window.addEventListener('resize', resize);

    const onEnd = () => {
      if (pad.isEmpty()) {
        setIsEmpty(true);
        onChange(null);
        return;
      }
      setIsEmpty(false);
      canvas.toBlob((blob) => onChange(blob), 'image/png');
    };
    pad.addEventListener('endStroke', onEnd);

    return () => {
      window.removeEventListener('resize', resize);
      pad.removeEventListener('endStroke', onEnd);
      try { pad.off(); } catch (_) {}
    };
  }, [libReady, onChange]);

  function clear() {
    if (padRef.current) padRef.current.clear();
    setIsEmpty(true);
    onChange(null);
  }

  return (
    <div>
      <canvas
        ref={canvasRef}
        style={{
          width: '100%',
          height: `${height}px`,
          border: '1.5px solid var(--border)',
          borderRadius: 'var(--radius-sm)',
          background: '#fff',
          touchAction: 'none',
          display: 'block',
          cursor: 'crosshair'
        }}
      />
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '8px', gap: '8px' }}>
        <p style={{ ...styles.hint, margin: 0 }}>
          {isEmpty ? 'Assine dentro do quadro acima.' : 'Assinatura capturada.'}
        </p>
        <button
          type="button"
          onClick={clear}
          style={{ ...styles.secondaryButton, marginTop: 0, padding: '8px 14px', width: 'auto' }}
        >
          Limpar
        </button>
      </div>
    </div>
  );
}

function MobileSignatureModal({ initialDataUrl, onCancel, onConfirm }) {
  const canvasRef = useRef(null);
  const padRef = useRef(null);
  const [isEmpty, setIsEmpty] = useState(!initialDataUrl);
  const libReady = useSignaturePadLibReady();

  useEffect(() => {
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.body.style.overflow = prev;
    };
  }, []);

  useEffect(() => {
    if (!libReady) return;
    const canvas = canvasRef.current;
    if (!canvas) return;

    const restoreOrClear = () => {
      const pad = padRef.current;
      if (!pad) return;
      if (initialDataUrl) {
        try {
          pad.fromDataURL(initialDataUrl, { ratio: 1 });
          setIsEmpty(pad.isEmpty());
          return;
        } catch (_) {}
      }
      pad.clear();
      setIsEmpty(true);
    };

    const resize = () => {
      const ratio = Math.max(window.devicePixelRatio || 1, 1);
      canvas.width = canvas.offsetWidth * ratio;
      canvas.height = canvas.offsetHeight * ratio;
      canvas.getContext('2d').scale(ratio, ratio);
      restoreOrClear();
    };

    const pad = new window.SignaturePad(canvas, {
      backgroundColor: 'rgb(255, 255, 255)',
      penColor: 'rgb(28, 58, 82)',
      minWidth: 1,
      maxWidth: 3
    });
    padRef.current = pad;
    resize();
    window.addEventListener('resize', resize);
    window.addEventListener('orientationchange', resize);

    const onEnd = () => setIsEmpty(pad.isEmpty());
    pad.addEventListener('endStroke', onEnd);

    return () => {
      window.removeEventListener('resize', resize);
      window.removeEventListener('orientationchange', resize);
      pad.removeEventListener('endStroke', onEnd);
      try { pad.off(); } catch (_) {}
    };
  }, [libReady, initialDataUrl]);

  function clearPad() {
    if (padRef.current) padRef.current.clear();
    setIsEmpty(true);
  }

  function confirm() {
    const pad = padRef.current;
    const canvas = canvasRef.current;
    if (!pad || !canvas || pad.isEmpty()) return;
    const dataUrl = canvas.toDataURL('image/png');
    canvas.toBlob((blob) => {
      if (!blob) return;
      onConfirm(blob, dataUrl);
    }, 'image/png');
  }

  return (
    <div
      style={{
        position: 'fixed',
        inset: 0,
        zIndex: 9999,
        background: '#fff',
        display: 'flex',
        flexDirection: 'column'
      }}
    >
      <div
        style={{
          padding: '12px 16px',
          borderBottom: '1.5px solid var(--border)',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          gap: '8px'
        }}
      >
        <strong style={{ color: 'var(--primary-dark)', fontSize: '1rem' }}>
          Sua assinatura
        </strong>
        <span style={{ ...styles.hint, margin: 0 }}>Use o dedo para assinar</span>
      </div>

      <div style={{ flex: 1, padding: '8px', display: 'flex', minHeight: 0 }}>
        <canvas
          ref={canvasRef}
          style={{
            flex: 1,
            width: '100%',
            height: '100%',
            border: '1.5px dashed var(--border)',
            borderRadius: 'var(--radius-sm)',
            background: '#fff',
            touchAction: 'none',
            display: 'block',
            cursor: 'crosshair'
          }}
        />
      </div>

      <div
        style={{
          padding: '12px 16px calc(12px + env(safe-area-inset-bottom)) 16px',
          borderTop: '1.5px solid var(--border)',
          display: 'grid',
          gridTemplateColumns: '1fr 1fr 1fr',
          gap: '8px'
        }}
      >
        <button
          type="button"
          onClick={onCancel}
          style={{ ...styles.secondaryButton, marginTop: 0 }}
        >
          Voltar
        </button>
        <button
          type="button"
          onClick={clearPad}
          style={{ ...styles.secondaryButton, marginTop: 0 }}
        >
          Limpar
        </button>
        <button
          type="button"
          onClick={confirm}
          disabled={isEmpty}
          style={{
            ...styles.button,
            marginTop: 0,
            opacity: isEmpty ? 0.6 : 1,
            cursor: isEmpty ? 'not-allowed' : 'pointer'
          }}
        >
          Continuar
        </button>
      </div>
    </div>
  );
}

function MobileSignaturePad({ onChange }) {
  const [thumbDataUrl, setThumbDataUrl] = useState(null);
  const [overlayOpen, setOverlayOpen] = useState(false);

  function handleConfirm(blob, dataUrl) {
    setThumbDataUrl(dataUrl);
    onChange(blob);
    setOverlayOpen(false);
  }

  function clearOutside() {
    setThumbDataUrl(null);
    onChange(null);
  }

  return (
    <div>
      {thumbDataUrl ? (
        <div style={{ marginBottom: '8px' }}>
          <img
            src={thumbDataUrl}
            alt="Assinatura"
            style={{
              width: '100%',
              maxHeight: '140px',
              objectFit: 'contain',
              border: '1.5px solid var(--border)',
              borderRadius: 'var(--radius-sm)',
              background: '#fff',
              padding: '4px'
            }}
          />
        </div>
      ) : null}

      <button
        type="button"
        onClick={() => setOverlayOpen(true)}
        style={{ ...styles.button, marginTop: 0 }}
      >
        {thumbDataUrl ? 'Refazer assinatura' : 'Assinar'}
      </button>

      {thumbDataUrl ? (
        <button
          type="button"
          onClick={clearOutside}
          style={{ ...styles.secondaryButton, marginTop: '8px' }}
        >
          Limpar
        </button>
      ) : (
        <p style={{ ...styles.hint, marginTop: '8px' }}>
          Toque em "Assinar" para abrir a tela cheia.
        </p>
      )}

      {overlayOpen ? (
        <MobileSignatureModal
          initialDataUrl={thumbDataUrl}
          onCancel={() => setOverlayOpen(false)}
          onConfirm={handleConfirm}
        />
      ) : null}
    </div>
  );
}

function SignaturePadField({ onChange, height = 180 }) {
  const isMobile = useIsMobileViewport();
  return isMobile ? (
    <MobileSignaturePad onChange={onChange} />
  ) : (
    <DesktopSignaturePad onChange={onChange} height={height} />
  );
}

function SelfieCapture({ onChange }) {
  const [mode, setMode] = useState(null); // 'camera' | 'upload' | null
  const [previewUrl, setPreviewUrl] = useState(null);
  const [cameraError, setCameraError] = useState('');
  const videoRef = useRef(null);
  const streamRef = useRef(null);
  const fileInputRef = useRef(null);

  function stopCamera() {
    if (streamRef.current) {
      streamRef.current.getTracks().forEach((t) => t.stop());
      streamRef.current = null;
    }
  }

  useEffect(() => {
    return () => {
      stopCamera();
      if (previewUrl) URL.revokeObjectURL(previewUrl);
    };
  }, [previewUrl]);

  async function startCamera() {
    setCameraError('');
    setMode('camera');
    try {
      const stream = await navigator.mediaDevices.getUserMedia({
        video: { facingMode: 'user', width: { ideal: 1280 }, height: { ideal: 720 } },
        audio: false
      });
      streamRef.current = stream;
      if (videoRef.current) videoRef.current.srcObject = stream;
    } catch (_err) {
      setCameraError('Nao foi possivel acessar a camera. Tente enviar uma foto.');
      setMode(null);
    }
  }

  function capturePhoto() {
    const video = videoRef.current;
    if (!video) return;
    const canvas = document.createElement('canvas');
    canvas.width = video.videoWidth || 720;
    canvas.height = video.videoHeight || 960;
    canvas.getContext('2d').drawImage(video, 0, 0);
    canvas.toBlob(
      (blob) => {
        if (!blob) return;
        if (previewUrl) URL.revokeObjectURL(previewUrl);
        const url = URL.createObjectURL(blob);
        setPreviewUrl(url);
        onChange(blob);
        stopCamera();
        setMode(null);
      },
      'image/jpeg',
      0.9
    );
  }

  function handleFile(e) {
    const file = e.target.files && e.target.files[0];
    if (!file) return;
    if (previewUrl) URL.revokeObjectURL(previewUrl);
    const url = URL.createObjectURL(file);
    setPreviewUrl(url);
    onChange(file);
    setMode('upload');
  }

  function reset() {
    stopCamera();
    if (previewUrl) URL.revokeObjectURL(previewUrl);
    setPreviewUrl(null);
    setMode(null);
    onChange(null);
    if (fileInputRef.current) fileInputRef.current.value = '';
  }

  if (previewUrl) {
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: '10px', alignItems: 'stretch' }}>
        <img
          src={previewUrl}
          alt="Selfie"
          style={{
            width: '100%',
            maxHeight: '320px',
            objectFit: 'cover',
            borderRadius: 'var(--radius-sm)',
            border: '1.5px solid var(--border)',
            background: '#000'
          }}
        />
        <button type="button" onClick={reset} style={{ ...styles.secondaryButton, marginTop: 0 }}>
          Tirar outra
        </button>
      </div>
    );
  }

  if (mode === 'camera') {
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
        <video
          ref={videoRef}
          autoPlay
          playsInline
          muted
          style={{
            width: '100%',
            maxHeight: '420px',
            borderRadius: 'var(--radius-sm)',
            transform: 'scaleX(-1)',
            background: '#000'
          }}
        />
        <div style={{ display: 'flex', gap: '8px' }}>
          <button
            type="button"
            onClick={capturePhoto}
            style={{ ...styles.button, flex: 1, marginTop: 0 }}
          >
            Capturar
          </button>
          <button
            type="button"
            onClick={reset}
            style={{ ...styles.secondaryButton, flex: 1, marginTop: 0 }}
          >
            Cancelar
          </button>
        </div>
      </div>
    );
  }

  return (
    <div>
      <div style={{ display: 'flex', gap: '8px' }}>
        <button
          type="button"
          onClick={startCamera}
          style={{ ...styles.button, flex: 1, marginTop: 0 }}
        >
          Usar camera
        </button>
        <button
          type="button"
          onClick={() => fileInputRef.current && fileInputRef.current.click()}
          style={{ ...styles.secondaryButton, flex: 1, marginTop: 0 }}
        >
          Enviar foto
        </button>
      </div>
      {cameraError ? (
        <p style={{ ...styles.warn, marginTop: '8px' }}>{cameraError}</p>
      ) : (
        <p style={{ ...styles.hint, marginTop: '8px' }}>
          Segure seu documento (RG ou CNH) ao lado do rosto, em foto bem iluminada.
        </p>
      )}
      <input
        ref={fileInputRef}
        type="file"
        accept="image/*"
        capture="user"
        style={{ display: 'none' }}
        onChange={handleFile}
      />
    </div>
  );
}

function CadastroForm() {
  const [formData, setFormData] = useState({
    cadDoc: '',
    cadNome: '',
    cadNascimento: '',
    cadEmail: '',
    cadFone: '',
    cadCEP: '',
    cadLogradouro: '',
    cadNumero: '',
    cadLocalTipo: '',
    cadApartamento: '',
    cadComplemento: '',
    cadBairro: '',
    cadCidade: '',
    cadUF: '',
    plano: '',
    cadAddressProof: null
  });

  const [serasaStatus, setSerasaStatus] = useState(null);
  const [currentStep, setCurrentStep] = useState(1);
  const [showManualAddress, setShowManualAddress] = useState(false);
  const [addressLoading, setAddressLoading] = useState(false);
  const [addressMsg, setAddressMsg] = useState('');
  const [mapMessage, setMapMessage] = useState('');
  const [selectedCoords, setSelectedCoords] = useState(null);
  const [planSelectionMode, setPlanSelectionMode] = useState(null); // null | help | alone
  const [assistantAnswers, setAssistantAnswers] = useState({
    pessoasRange: '',
    uso: '',
    beneficio: 'TANTO_FAZ'
  });
  const [plansCatalog, setPlansCatalog] = useState([]);
  const [plansLoading, setPlansLoading] = useState(false);
  const [plansError, setPlansError] = useState('');
  const [planRecLoading, setPlanRecLoading] = useState(false);
  const [planRecError, setPlanRecError] = useState('');
  const [planRecData, setPlanRecData] = useState(null);
  const [touched, setTouched] = useState({});
  const [emailReady, setEmailReady] = useState(false);
  const [showPhoneField, setShowPhoneField] = useState(false);
  const [emailSkipped, setEmailSkipped] = useState(false);
  const [showEmailSkipModal, setShowEmailSkipModal] = useState(false);
  const [submitted, setSubmitted] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [leafletReady, setLeafletReady] = useState(false);
  const [isDragOver, setIsDragOver] = useState(false);
  const [emailProvider, setEmailProviderState] = useState('gmail'); // gmail | outlook | hotmail | custom
  const [hasWhatsApp, setHasWhatsApp] = useState(null); // null = não respondeu, true/false
  const [showWhatsAppModal, setShowWhatsAppModal] = useState(false);
  const [whatsAppAttention, setWhatsAppAttention] = useState(false);
  const [showMapModal, setShowMapModal] = useState(false);
  const [mapPickedAddress, setMapPickedAddress] = useState(null);
  const [locationLoading, setLocationLoading] = useState(false);
  const [locationError, setLocationError] = useState('');
  const [highlightManualAddressField, setHighlightManualAddressField] = useState(false);
  const [cpfConsultLoading, setCpfConsultLoading] = useState(false);
  const [cpfConsultError, setCpfConsultError] = useState('');
  const [submitError, setSubmitError] = useState('');
  const [submitDebugMode, setSubmitDebugMode] = useState(false);
  const [proofPreviewUrl, setProofPreviewUrl] = useState(null);

  useEffect(() => {
    const file = formData.cadAddressProof;
    if (!file || !file.type || !file.type.startsWith('image/')) {
      setProofPreviewUrl(null);
      return;
    }
    const url = URL.createObjectURL(file);
    setProofPreviewUrl(url);
    return () => URL.revokeObjectURL(url);
  }, [formData.cadAddressProof]);

  const [aceiteStep, setAceiteStep] = useState(false);
  const [aceiteSelfie, setAceiteSelfie] = useState(null);
  const [aceiteAssinatura, setAceiteAssinatura] = useState(null);
  const [aceiteLoading, setAceiteLoading] = useState(false);
  const [aceiteError, setAceiteError] = useState('');
  const [aceiteDebugMode, setAceiteDebugMode] = useState(false);

  const [aceiteContract, setAceiteContract] = useState(null);
  const [aceiteContractLoading, setAceiteContractLoading] = useState(false);
  const [aceiteContractError, setAceiteContractError] = useState('');
  const [aceiteContractDebugMode, setAceiteContractDebugMode] = useState(false);
  const contractRequestStartedRef = useRef(false);

  // Selfie verification (Gemini)
  const [selfieVerifying, setSelfieVerifying] = useState(false);
  const [selfieVerified, setSelfieVerified] = useState(false);
  const [selfieManualReview, setSelfieManualReview] = useState(false);
  const [selfieVerifyMsg, setSelfieVerifyMsg] = useState('');
  const [selfieRetryCount, setSelfieRetryCount] = useState(0);

  // Address proof verification (Gemini)
  const [addrVerifying, setAddrVerifying] = useState(false);
  const [addrVerified, setAddrVerified] = useState(false);
  const [addrVerifyMsg, setAddrVerifyMsg] = useState('');
  const [addrRetryCount, setAddrRetryCount] = useState(0);

  // Viability check (painel-score)
  const [viabChecking, setViabChecking] = useState(false);
  const [viabResult, setViabResult] = useState(null); // 'VIÁVEL' | 'NÃO VIÁVEL' | 'ANÁLISE NECESSÁRIA' | null
  const [viabMsg, setViabMsg] = useState('');
  const [viabCaixas, setViabCaixas] = useState(null);
  const viabCheckedRef = useRef(''); // evita re-checar o mesmo endereço

  // Connection + OS scheduling
  const [codigoCliente, setCodigoCliente] = useState(null);
  const [conexaoStep, setConexaoStep] = useState(false);
  const [conexaoLoading, setConexaoLoading] = useState(false);
  const [conexaoError, setConexaoError] = useState('');
  const [conexaoData, setConexaoData] = useState(null);
  const [agendaStep, setAgendaStep] = useState(false);
  const [vagasLoading, setVagasLoading] = useState(false);
  const [vagasError, setVagasError] = useState('');
  const [vagasOpcoes, setVagasOpcoes] = useState([]);
  const [vagaSelecionada, setVagaSelecionada] = useState(null);
  const [agendarLoading, setAgendarLoading] = useState(false);
  const [agendarError, setAgendarError] = useState('');
  const [osAgendada, setOsAgendada] = useState(false);

  const mapRef = useRef(null);
  const mapInstanceRef = useRef(null);
  const markerRef = useRef(null);
  const fileInputRef = useRef(null);
  const whatsappToggleRef = useRef(null);
  const logradouroInputRef = useRef(null);
  const scoreAbortRef = useRef(null);

  const hasPlanStep = serasaStatus === 'approved';
  const planStep = hasPlanStep ? 3 : null;
  const documentStep = hasPlanStep ? 4 : 3;
  const reviewStep = hasPlanStep ? 5 : 4;
  const totalSteps = reviewStep;

  const currentStepLabel = (() => {
    if (currentStep === 1) return 'Meus dados';
    if (currentStep === 2) return 'Meu endereco';
    if (hasPlanStep && currentStep === 3) return 'Meu plano';
    if (currentStep === documentStep) return 'Meu comprovante';
    if (currentStep === reviewStep) return 'Conferir dados';
    return 'Cadastro';
  })();

  const assistantReady =
    !!assistantAnswers.pessoasRange &&
    !!assistantAnswers.uso &&
    !!planRecData?.recommended;
  const suggestedPlan = planRecData?.recommended || null;
  const benefitOptions = planRecData?.benefit_options || [];
  const planAssistantAvailable =
    !emailSkipped && isEmailValid(formData.cadEmail) && hasWhatsApp === true;
  const effectivePlanMode =
    planSelectionMode === 'help' && !planAssistantAvailable ? 'alone' : planSelectionMode;
  const showIdentityDetails = !!serasaStatus;
  const showEmail = showIdentityDetails;
  const showPhone = showEmail && (isEmailValid(formData.cadEmail) || emailSkipped);
  const showPrivacyBanner = currentStep === 1 && formData.cadDoc.length < 14;
  const showAdvanceToAddressButton = showPhone && formData.cadDoc.length === 14;

  const addressBaseReady = onlyDigits(formData.cadCEP).length === 8 || showManualAddress;
  const showLogradouro = addressBaseReady;
  const showBairro = addressBaseReady;
  const showNumero = addressBaseReady;
  const showTipoLocal = addressBaseReady;
  const showApartamento = addressBaseReady && formData.cadLocalTipo === 'predio';
  const showCidade = addressBaseReady;
  const showUF = addressBaseReady;

  const errors = {
    cadDoc:
      formData.cadDoc.length === 0
        ? 'Digite o seu CPF.'
        : formData.cadDoc.length !== 14
          ? 'Faltam numeros no CPF. Exemplo: 000.000.000-00.'
          : null,
    cadEmail:
      emailSkipped
        ? null
        : !formData.cadEmail
        ? 'Digite seu e-mail para contato.'
        : isEmailValid(formData.cadEmail)
          ? null
          : 'Esse e-mail parece incompleto. Confira por favor.',
    cadFone: (() => {
      const d = onlyDigits(formData.cadFone);
      if (!d) return 'Digite um telefone para contato.';
      if (d.length < 10) return 'Faltam numeros no telefone.';
      return null;
    })(),
    cadCEP:
      !formData.cadCEP && !showManualAddress
        ? 'Digite o CEP.'
        : formData.cadCEP && onlyDigits(formData.cadCEP).length !== 8
          ? 'CEP incompleto. Exemplo: 00000-000.'
          : null
  };

  function setField(field, value) {
    setSubmitted(false);
    if (field === 'cadEmail') {
      setEmailReady(false);
      setEmailSkipped(false);
      setShowPhoneField(false);
    }
    // Resetar viabilidade quando endereço muda
    if (['cadLogradouro', 'cadNumero', 'cadBairro', 'cadCidade', 'cadUF', 'cadCEP'].includes(field)) {
      setViabResult(null);
      setViabMsg('');
      setViabCaixas(null);
    }
    setFormData((prev) => ({ ...prev, [field]: value }));
  }

  function extractLocalForSwitch(cadEmail, fromProvider) {
    if (!cadEmail) return '';
    if (fromProvider === 'custom') {
      const at = cadEmail.indexOf('@');
      if (at === -1) return cadEmail.replace(/@/g, '');
      return cadEmail.slice(0, at).replace(/@/g, '');
    }
    return emailLocalFromValue(cadEmail, fromProvider);
  }

  function setEmailProvider(next) {
    setSubmitted(false);
    setEmailSkipped(false);
    setShowPhoneField(false);
    setEmailReady(false);
    if (next === 'custom') {
      setEmailProviderState('custom');
      const local = extractLocalForSwitch(formData.cadEmail, emailProvider);
      setFormData((prev) => ({ ...prev, cadEmail: local }));
      return;
    }
    setEmailProviderState(next);
    const local = extractLocalForSwitch(formData.cadEmail, emailProvider);
    const clean = local.replace(/@/g, '');
    const suffix = EMAIL_PRESETS[next];
    setFormData((prev) => ({ ...prev, cadEmail: clean ? clean + suffix : '' }));
  }

  function handleEmailLocalChange(e) {
    let v = e.target.value;
    if (v.includes('@')) {
      v = v.split('@')[0];
    }
    v = v.replace(/@/g, '');
    const suffix = EMAIL_PRESETS[emailProvider];
    setField('cadEmail', v ? v + suffix : '');
  }

  function touchField(field) {
    setTouched((prev) => ({ ...prev, [field]: true }));
  }

  function getInlineError(field) {
    return touched[field] ? errors[field] : null;
  }

  const emailFieldError = getInlineError('cadEmail');
  const emailFieldFilled =
    emailProvider === 'custom'
      ? !!String(formData.cadEmail || '').trim()
      : !!emailLocalFromValue(formData.cadEmail, emailProvider).trim();
  const emailCanAdvance = isEmailValid(formData.cadEmail);

  async function fetchScoreDecision(maskedCpf) {
    scoreAbortRef.current?.abort();
    const ac = new AbortController();
    scoreAbortRef.current = ac;

    const digits = onlyDigits(maskedCpf);
    if (digits.length !== 11) return;

    setCpfConsultLoading(true);
    setCpfConsultError('');

    try {
      const r = await fetch(appApiUrl('/api/mk/score-decision-cpf'), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ cpf: digits, force: 0 }),
        signal: ac.signal
      });
      const data = await r.json().catch(() => ({}));

      if (scoreAbortRef.current !== ac) return;

      if (!r.ok) {
        setSerasaStatus(null);
        setFormData((prev) => ({ ...prev, cadNome: '', cadNascimento: '' }));
        setCpfConsultError(
          data.error || data.message || 'Nao foi possivel consultar o CPF. Tente de novo.'
        );
        return;
      }

      const approved = data.approved === true;
      setSerasaStatus(approved ? 'approved' : 'rejected');
      const nome = String(data.nome_cliente || data.nome || '').trim();
      const cadNascimento = nascimentoApiToBr(data.data_nascimento);
      setFormData((prev) => ({
        ...prev,
        cadNome: nome,
        cadNascimento
      }));
    } catch (e) {
      if (e.name === 'AbortError') return;
      if (scoreAbortRef.current !== ac) return;
      setSerasaStatus(null);
      setFormData((prev) => ({ ...prev, cadNome: '', cadNascimento: '' }));
      setCpfConsultError('Erro de conexao. Verifique a internet e tente de novo.');
    } finally {
      if (scoreAbortRef.current === ac) {
        setCpfConsultLoading(false);
      }
    }
  }

  function handleCpfChange(e) {
    const masked = mm.cpf(e.target.value);
    setField('cadDoc', masked);
    if (masked.length === 14) {
      fetchScoreDecision(masked);
    } else {
      scoreAbortRef.current?.abort();
      scoreAbortRef.current = null;
      setCpfConsultLoading(false);
      setCpfConsultError('');
      setSerasaStatus(null);
      setFormData((prev) => ({ ...prev, cadNome: '', cadNascimento: '' }));
    }
  }

  function handlePhoneChange(e) {
    setField('cadFone', mm.phone(e.target.value));
  }

  async function lookupCepByApi(cepDigits) {
    setAddressLoading(true);
    setAddressMsg('');
    try {
      const r1 = await fetch(`https://viacep.com.br/ws/${cepDigits}/json/`);
      const j1 = await r1.json();
      if (!j1.erro) {
        setFormData((prev) => ({
          ...prev,
          cadLogradouro: j1.logradouro || prev.cadLogradouro,
          cadBairro: j1.bairro || prev.cadBairro,
          cadCidade: j1.localidade || prev.cadCidade,
          cadUF: j1.uf || prev.cadUF
        }));
        setAddressMsg('Endereco preenchido automaticamente para facilitar.');
        return;
      }
      const r2 = await fetch(`https://brasilapi.com.br/api/cep/v1/${cepDigits}`);
      if (r2.ok) {
        const j2 = await r2.json();
        setFormData((prev) => ({
          ...prev,
          cadLogradouro: j2.street || prev.cadLogradouro,
          cadBairro: j2.neighborhood || prev.cadBairro,
          cadCidade: j2.city || prev.cadCidade,
          cadUF: j2.state || prev.cadUF
        }));
        setAddressMsg('Endereco preenchido automaticamente para facilitar.');
      } else {
        setAddressMsg('Nao encontrei esse CEP. Pode continuar preenchendo manualmente.');
      }
    } catch (err) {
      setAddressMsg('Nao consegui consultar o CEP agora. Pode continuar preenchendo manualmente.');
    } finally {
      setAddressLoading(false);
    }
  }

  function handleCepChange(e) {
    const masked = mm.cep(e.target.value);
    setField('cadCEP', masked);
    const cepDigits = onlyDigits(masked);
    if (cepDigits.length === 8) lookupCepByApi(cepDigits);
  }

  function applyAddressFromMapResult(result) {
    if (!result) return;
    const { street, suburb, city, state, postcode } = result;
    setFormData((prev) => ({
      ...prev,
      cadLogradouro: street || prev.cadLogradouro,
      cadBairro: suburb || prev.cadBairro,
      cadCidade: city || prev.cadCidade,
      cadUF: state || prev.cadUF
    }));
    if (postcode && postcode.length === 8) {
      const m = maskCep(postcode);
      setField('cadCEP', m);
      lookupCepByApi(postcode);
    }
  }

  async function reverseGeocode(lat, lng) {
    try {
      const params = new URLSearchParams({ lat: String(lat), lng: String(lng) });
      const resp = await fetch(
        appApiUrl(`/api/public/reverse-geocode?${params.toString()}`)
      );
      if (!resp.ok) return null;
      const data = await resp.json();
      const result = {
        street: data?.street || '',
        suburb: data?.suburb || '',
        city: data?.city || '',
        state: data?.state || '',
        postcode: data?.postcode ? String(data.postcode).replace(/\D/g, '') : ''
      };
      setMapPickedAddress(result);
      return result;
    } catch (err) {
      setMapPickedAddress(null);
      return null;
    }
  }

  function confirmMapAddress() {
    if (!mapPickedAddress) return;
    applyAddressFromMapResult(mapPickedAddress);
    closeMapModal();
    setShowManualAddress(true);
    setMapMessage('Endereco preenchido pelo mapa.');
  }

  function closeMapModal() {
    setShowMapModal(false);
    setMapPickedAddress(null);
    if (mapInstanceRef.current?.remove) {
      mapInstanceRef.current.remove();
    }
    mapInstanceRef.current = null;
    markerRef.current = null;
  }

  function handleUseMyLocation() {
    setLocationError('');
    setLocationLoading(true);
    setMapMessage('');
    if (!navigator.geolocation) {
      setLocationLoading(false);
      setLocationError('Nao foi possivel buscar sua localizacao neste aparelho.');
      return;
    }
    navigator.geolocation.getCurrentPosition(
      async (pos) => {
        const coords = {
          lat: pos.coords.latitude,
          lng: pos.coords.longitude
        };
        setSelectedCoords(coords);
        const result = await reverseGeocode(coords.lat, coords.lng);
        setLocationLoading(false);
        if (result) {
          applyAddressFromMapResult(result);
          setShowManualAddress(true);
          setMapPickedAddress(null);
          setMapMessage('Endereco preenchido usando sua localizacao.');
        } else {
          setLocationError('Nao foi possivel converter sua localizacao em endereco.');
        }
      },
      () => {
        setLocationLoading(false);
        setLocationError('Nao conseguimos acessar sua localizacao. Verifique a permissao do navegador.');
      },
      { enableHighAccuracy: true, timeout: 8000 }
    );
  }

  function loadLeaflet() {
    if (window.L && window.L.map) {
      setLeafletReady(true);
      return Promise.resolve();
    }

    return new Promise((resolve, reject) => {
      const cssId = 'leaflet-css';
      if (!document.getElementById(cssId)) {
        const link = document.createElement('link');
        link.id = cssId;
        link.rel = 'stylesheet';
        link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
        document.head.appendChild(link);
      }

      const existing = document.getElementById('leaflet-sdk');
      if (existing) {
        existing.addEventListener('load', () => {
          setLeafletReady(true);
          resolve();
        });
        existing.addEventListener('error', () => reject(new Error('Falha ao carregar Leaflet.')));
        return;
      }

      const script = document.createElement('script');
      script.id = 'leaflet-sdk';
      script.async = true;
      script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';
      script.onload = () => {
        setLeafletReady(true);
        resolve();
      };
      script.onerror = () => reject(new Error('Falha ao carregar Leaflet.'));
      document.body.appendChild(script);
    });
  }

  function startMapAt(lat, lng) {
    if (!mapRef.current || !window.L) return;

    if (!mapInstanceRef.current) {
      mapInstanceRef.current = window.L.map(mapRef.current, {
        zoomControl: true
      }).setView([lat, lng], 16);

      window.L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; OpenStreetMap contributors'
      }).addTo(mapInstanceRef.current);

      markerRef.current = window.L.marker([lat, lng]).addTo(mapInstanceRef.current);

      mapInstanceRef.current.on('click', (event) => {
        const clicked = {
          lat: event.latlng.lat,
          lng: event.latlng.lng
        };
        markerRef.current.setLatLng([clicked.lat, clicked.lng]);
        setSelectedCoords(clicked);
        setMapMessage('Local selecionado no mapa. Estamos preenchendo seu endereco.');
        reverseGeocode(clicked.lat, clicked.lng);
      });
    } else {
      mapInstanceRef.current.setView([lat, lng], mapInstanceRef.current.getZoom() || 16);
      markerRef.current.setLatLng([lat, lng]);
    }
  }

  useEffect(() => {
    if (!showMapModal) return;

    let cancelled = false;

    loadLeaflet()
      .then(() => {
        if (cancelled) return;
        if (!navigator.geolocation) {
          setMapMessage('Seu navegador nao permite geolocalizacao. Mapa centralizado em Itauna/MG para voce marcar o ponto.');
          startMapAt(DEFAULT_MAP_CENTER.lat, DEFAULT_MAP_CENTER.lng);
          return;
        }

        navigator.geolocation.getCurrentPosition(
          (pos) => {
            if (cancelled) return;
            const coords = {
              lat: pos.coords.latitude,
              lng: pos.coords.longitude
            };
            setSelectedCoords(coords);
            setMapMessage('Local detectado. Se precisar, toque em outro ponto do mapa.');
            startMapAt(coords.lat, coords.lng);
            reverseGeocode(coords.lat, coords.lng);
          },
          () => {
            setMapMessage('Nao foi possivel usar sua localizacao. Mapa centralizado em Itauna/MG para voce marcar o ponto.');
            startMapAt(DEFAULT_MAP_CENTER.lat, DEFAULT_MAP_CENTER.lng);
          },
          { enableHighAccuracy: true, timeout: 8000 }
        );
      })
      .catch(() => {
        setMapMessage(
          'Nao foi possivel carregar o mapa OpenStreet agora. Enquanto isso, preencha o endereco nos campos abaixo.'
        );
      });

    return () => {
      cancelled = true;
    };
  }, [showMapModal]);

  useEffect(() => {
    if (showMapModal && mapInstanceRef.current?.invalidateSize) {
      setTimeout(() => mapInstanceRef.current.invalidateSize(), 100);
    }
  }, [showMapModal]);

  const identificationOk = !errors.cadDoc && !errors.cadEmail && !errors.cadFone && !!serasaStatus;
  const addressOk =
    !errors.cadCEP &&
    !!formData.cadLogradouro &&
    !!formData.cadNumero &&
    !!formData.cadLocalTipo &&
    (formData.cadLocalTipo !== 'predio' || !!formData.cadApartamento) &&
    !!formData.cadBairro &&
    !!formData.cadCidade &&
    !!formData.cadUF;
  const planOk = serasaStatus !== 'approved' || !!formData.plano;
  const documentOk = !!formData.cadAddressProof;

  // --- Viability check (defined after addressOk so it can reference it) ---
  async function checkViability() {
    setViabChecking(true);
    setViabResult(null);
    setViabMsg('');
    setViabCaixas(null);
    try {
      const coords = selectedCoords;
      const body = {
        street: formData.cadLogradouro,
        number: formData.cadNumero,
        district: formData.cadBairro,
        city: formData.cadCidade,
        uf: formData.cadUF,
        cep: formData.cadCEP
      };
      if (coords) {
        body.lat = coords.lat;
        body.lon = coords.lng;
      }
      const r = await fetch(appApiUrl('/api/mk/check-viability'), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body)
      });
      const data = await r.json().catch(() => ({}));
      const viability = data.viability || '';
      setViabResult(viability);
      setViabCaixas(data.caixas || null);

      if (viability === 'VIÁVEL') {
        setViabMsg('');
      } else if (viability === 'NÃO VIÁVEL') {
        setViabMsg(
          'Infelizmente, ainda não temos cobertura disponível no seu endereço. ' +
          'Seu cadastro será registrado e entraremos em contato quando a cobertura chegar na sua região.'
        );
      } else if (viability === 'ANÁLISE NECESSÁRIA') {
        setViabMsg(
          'Não foi possível confirmar a cobertura automaticamente. ' +
          'Seu cadastro será analisado pela equipe técnica. Você pode prosseguir.'
        );
      } else {
        setViabResult('ERRO');
        setViabMsg('');
      }
    } catch (_e) {
      setViabResult('ERRO');
      setViabMsg('');
    } finally {
      setViabChecking(false);
    }
  }

  // Auto-verifica viabilidade quando o endereço fica completo
  useEffect(() => {
    if (currentStep !== 2) return;
    if (!addressOk) return;
    if (viabChecking) return;
    const addrKey = [formData.cadLogradouro, formData.cadNumero, formData.cadBairro, formData.cadCidade, formData.cadUF, formData.cadCEP].join('|');
    if (addrKey === viabCheckedRef.current && viabResult) return;
    viabCheckedRef.current = addrKey;
    checkViability();
  }, [currentStep, addressOk, formData.cadLogradouro, formData.cadNumero, formData.cadBairro, formData.cadCidade, formData.cadUF, formData.cadCEP]);

  function goToAddress() {
    if (!identificationOk) return;
    if (hasWhatsApp === null) {
      setShowWhatsAppModal(true);
      return;
    }
    setCurrentStep(2);
  }

  function guideToWhatsAppToggle(nextValue) {
    setHasWhatsApp(nextValue);
    setShowWhatsAppModal(false);
    setWhatsAppAttention(true);
    setTimeout(() => setWhatsAppAttention(false), 1200);
    setTimeout(() => whatsappToggleRef.current?.focus(), 30);
  }

  function goAfterAddress() {
    if (!addressOk) return;
    // Se ainda está verificando, aguarda
    if (viabChecking) return;
    // Se não viável, bloqueia avanço
    if (viabResult === 'NÃO VIÁVEL') return;
    if (hasPlanStep) setCurrentStep(planStep);
    else setCurrentStep(documentStep);
  }

  function goToDocument() {
    if (!planOk) return;
    setCurrentStep(documentStep);
  }

  function goToReview() {
    if (!documentOk) return;
    // Se é imagem, precisa ter verificado o endereço
    if (formData.cadAddressProof?.type?.startsWith('image/') && !addrVerified) return;
    setCurrentStep(reviewStep);
  }

  async function loadPlansCatalog() {
    setPlansLoading(true);
    setPlansError('');
    try {
      const r = await fetch(appApiUrl('/api/mk/crm-products-pf-benefits'));
      const data = await r.json().catch(() => ({}));
      if (!r.ok) {
        setPlansError(data.error || data.message || 'Nao foi possivel carregar os planos agora.');
        return;
      }
      setPlansCatalog(Array.isArray(data.items) ? data.items : []);
    } catch (_e) {
      setPlansError('Erro de conexao ao carregar os planos.');
    } finally {
      setPlansLoading(false);
    }
  }

  async function requestPlanRecommendation() {
    if (!assistantAnswers.pessoasRange || !assistantAnswers.uso) {
      setPlanRecData(null);
      return;
    }
    setPlanRecLoading(true);
    setPlanRecError('');
    try {
      const r = await fetch(appApiUrl('/api/mk/plan-assistant/recommend'), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          resposta_pessoas: assistantAnswers.pessoasRange,
          resposta_uso: assistantAnswers.uso,
          resposta_beneficio: assistantAnswers.beneficio || 'TANTO_FAZ'
        })
      });
      const data = await r.json().catch(() => ({}));
      if (!r.ok) {
        setPlanRecData(null);
        setPlanRecError(
          data.error || data.message || 'Nao foi possivel calcular a sugestao de plano agora.'
        );
        return;
      }
      setPlanRecData(data);
    } catch (_e) {
      setPlanRecData(null);
      setPlanRecError('Erro de conexao ao calcular sugestao.');
    } finally {
      setPlanRecLoading(false);
    }
  }

  useEffect(() => {
    if (hasPlanStep && currentStep === planStep && plansCatalog.length === 0 && !plansLoading) {
      loadPlansCatalog();
    }
  }, [hasPlanStep, currentStep, planStep, plansCatalog.length, plansLoading]);

  useEffect(() => {
    if (planSelectionMode !== 'help' || !planAssistantAvailable) return;
    requestPlanRecommendation();
  }, [
    planSelectionMode,
    planAssistantAvailable,
    assistantAnswers.pessoasRange,
    assistantAnswers.uso,
    assistantAnswers.beneficio
  ]);

  function handleFile(e) {
    const file = e.target.files && e.target.files[0] ? e.target.files[0] : null;
    setField('cadAddressProof', file);
    if (file && file.type && file.type.startsWith('image/')) {
      verifyAddress(file);
    } else {
      // PDF ou outro formato — não verifica com Gemini
      setAddrVerified(true);
      setAddrVerifyMsg('');
    }
  }

  function handleDropFile(e) {
    e.preventDefault();
    setIsDragOver(false);
    const file = e.dataTransfer?.files?.[0];
    if (!file) return;
    setField('cadAddressProof', file);
    if (file.type && file.type.startsWith('image/')) {
      verifyAddress(file);
    } else {
      setAddrVerified(true);
      setAddrVerifyMsg('');
    }
  }

  async function submitForm() {
    if (!documentOk) return;
    setSubmitError('');
    setSubmitDebugMode(false);
    setIsSubmitting(true);
    try {
      const r = await fetch(appApiUrl('/api/mk/register-client'), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          doc: formData.cadDoc,
          nome: formData.cadNome,
          email: formData.cadEmail,
          fone: formData.cadFone,
          cep: formData.cadCEP,
          numero: formData.cadNumero,
          logradouro: formData.cadLogradouro,
          bairro: formData.cadBairro,
          cidade: formData.cadCidade,
          uf: formData.cadUF,
          complemento: formData.cadComplemento,
          apartamento: formData.cadApartamento
        })
      });
      const data = await r.json().catch(() => ({}));
      if (!r.ok) {
        setSubmitError(
          data.error ||
            data.message ||
            'Nao foi possivel concluir o cadastro no sistema. Tente de novo ou entre em contato.'
        );
        return;
      }
      setSubmitDebugMode(data.debug === true);
      if (data.codigoCliente) setCodigoCliente(data.codigoCliente);
      if (hasPlanStep) {
        setAceiteError('');
        setAceiteSelfie(null);
        setAceiteAssinatura(null);
        setAceiteContract(null);
        setAceiteContractError('');
        setAceiteContractDebugMode(false);
        contractRequestStartedRef.current = false;
        setAceiteStep(true);
      } else {
        setSubmitted(true);
      }
    } catch (e) {
      setSubmitError('Erro de conexao. Verifique a internet e tente de novo.');
    } finally {
      setIsSubmitting(false);
    }
  }

  async function createContract() {
    if (contractRequestStartedRef.current) return;
    contractRequestStartedRef.current = true;
    setAceiteContractError('');
    setAceiteContractLoading(true);
    try {
      const r = await fetch(appApiUrl('/api/mk/novo-contrato'), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          codigoCliente: codigoCliente || '',
          codigoPlanoAcesso: formData.plano,
          emailCliente: formData.cadEmail || ''
        })
      });
      const data = await r.json().catch(() => ({}));
      if (!r.ok || data.status !== 'OK' || !data.contrato) {
        setAceiteContractError(
          data.mensagem ||
            data.error ||
            data.message ||
            'Nao foi possivel gerar o contrato agora.'
        );
        contractRequestStartedRef.current = false;
        return;
      }
      setAceiteContractDebugMode(data.debug === true);
      setAceiteContract(String(data.contrato));
    } catch (_e) {
      setAceiteContractError('Erro de conexao ao gerar o contrato. Tente de novo.');
      contractRequestStartedRef.current = false;
    } finally {
      setAceiteContractLoading(false);
    }
  }

  useEffect(() => {
    if (!aceiteStep) return;
    if (aceiteContract) return;
    if (contractRequestStartedRef.current) return;
    createContract();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [aceiteStep]);

  // --- Selfie verification (Gemini) ---
  async function verifySelfie(blob) {
    if (!blob) return;
    setSelfieVerifying(true);
    setSelfieVerified(false);
    setSelfieVerifyMsg('');
    try {
      const fd = new FormData();
      fd.append('selfie', blob, 'selfie.jpg');
      const r = await fetch(appApiUrl('/api/mk/verify-selfie'), {
        method: 'POST',
        body: fd
      });
      const data = await r.json().catch(() => ({}));
      if (data.verified) {
        setSelfieVerified(true);
        setSelfieVerifyMsg('');
      } else if (data.retry) {
        const reason = data.reason;
        const mp = data.match_percent;
        const conf = data.confidence;
        // 2ª+ tentativa e resultado incerto (não é claramente outra pessoa)
        const isUncertain = selfieRetryCount >= 1
          && reason === 'face_document_mismatch'
          && mp != null && mp >= 25 && mp < 55;

        if (isUncertain) {
          // Deixa seguir mas avisa que vai pra revisão manual
          setSelfieVerified(true);
          setSelfieManualReview(true);
          setSelfieVerifyMsg(
            'A verificação automática não teve certeza. Sua foto será revisada manualmente pela equipe. ' +
            'Você pode prosseguir com a assinatura.'
          );
        } else {
          setSelfieVerified(false);
          let msg = '';
          if (reason === 'face_not_visible') {
            msg = 'Nao conseguimos ver seu rosto na foto. ';
            msg += 'Vá para um local bem iluminado (perto de uma janela, por exemplo), ';
            msg += 'segure o documento aberto ao lado do rosto e olhe diretamente para a câmera. ';
            msg += 'Certifique-se de que seu rosto inteiro aparece na foto, sem cortes.';
          } else if (reason === 'document_not_readable') {
            msg = 'O documento na foto não está legível. ';
            msg += 'Abra o documento na página da sua foto (RG ou CNH) e segure ao lado do rosto. ';
            msg += 'Procure um local claro, sem sombras sobre o documento. ';
            msg += 'Mantenha a mão firme ou apoie o braço para evitar tremor.';
          } else if (reason === 'face_document_mismatch') {
            msg = 'O rosto na foto não parece corresponder à foto do documento. ';
            msg += 'Certifique-se de que é o MESMO documento que é seu (RG ou CNH original). ';
            msg += 'Segure o documento aberto com a foto visível ao lado do seu rosto. ';
            msg += 'Tire a foto de frente, com boa luz, sem óculos escuros.';
          } else if (reason === 'quality_poor') {
            msg = 'A foto está escura ou tremida. ';
            msg += 'Vá para um local bem iluminado, de preferência com luz natural (perto de uma janela). ';
            msg += 'Evite luz atrás de você (contra-luz). ';
            msg += 'Apoie o braço em uma superfície para manter a mão firme ao tirar a foto.';
          } else {
            msg = 'Não foi possível verificar sua foto. ';
            msg += 'Tire outra foto em um local bem iluminado, segurando o documento (RG ou CNH) aberto ao lado do rosto. ';
            msg += 'Olhe para a câmera e mantenha a mão firme.';
          }
          setSelfieVerifyMsg(msg);
          setSelfieRetryCount((c) => c + 1);
        }
      } else {
        // Gemini not configured or error — let through
        setSelfieVerified(true);
      }
    } catch (_e) {
      // Network error — let through, don't block
      setSelfieVerified(true);
    } finally {
      setSelfieVerifying(false);
    }
  }

  function handleSelfieChange(blob) {
    setAceiteSelfie(blob);
    setSelfieVerified(false);
    setSelfieManualReview(false);
    setSelfieVerifyMsg('');
    if (blob) verifySelfie(blob);
  }

  // --- Address proof verification ---
  async function verifyAddress(file) {
    setAddrVerifying(true);
    setAddrVerified(false);
    setAddrVerifyMsg('');
    try {
      const fd = new FormData();
      fd.append('comprovante', file);
      fd.append('address', JSON.stringify({
        logradouro: formData.cadLogradouro,
        numero: formData.cadNumero,
        bairro: formData.cadBairro,
        cidade: formData.cadCidade,
        uf: formData.cadUF,
        cep: formData.cadCEP
      }));
      const r = await fetch(appApiUrl('/api/mk/verify-address'), {
        method: 'POST',
        body: fd
      });
      const data = await r.json().catch(() => ({}));
      if (data.verified) {
        setAddrVerified(true);
        setAddrVerifyMsg('');
      } else if (data.retry) {
        setAddrVerified(false);
        const reason = data.reason;
        let msg = '';
        if (reason === 'address_not_visible') {
          msg = 'Não conseguimos ver um endereço no documento. ';
          msg += 'Envie uma foto de uma conta (água, luz, telefone ou internet) onde o endereço esteja visível.';
        } else if (reason === 'address_not_readable') {
          msg = 'O endereço no documento não está legível. ';
          msg += 'Tire uma foto mais nítida, com boa iluminação, sem sombras sobre o texto.';
        } else if (reason === 'not_a_utility_bill') {
          msg = 'O documento enviado não parece ser uma conta de serviço. ';
          msg += 'Envie uma foto de conta de água, luz, telefone ou internet no seu nome.';
        } else if (reason === 'address_mismatch') {
          msg = 'O endereço no documento não corresponde ao endereço que você preencheu. ';
          msg += 'Verifique se o endereço do formulário está correto e envie um comprovante do mesmo endereço.';
          if (data.extracted_address) {
            msg += ` Endereço lido no documento: ${data.extracted_address}`;
          }
        } else {
          msg = 'Não foi possível verificar o comprovante. ';
          msg += 'Envie uma foto nítida de uma conta (água, luz, telefone ou internet) no seu nome.';
        }
        setAddrVerifyMsg(msg);
        setAddrRetryCount((c) => c + 1);
      } else {
        // Gemini not configured or error — let through
        setAddrVerified(true);
      }
    } catch (_e) {
      // Network error — let through
      setAddrVerified(true);
    } finally {
      setAddrVerifying(false);
    }
  }

  // --- Connection creation ---
  async function criarConexao() {
    setConexaoLoading(true);
    setConexaoError('');
    try {
      const r = await fetch(appApiUrl('/api/mk/criar-conexao-os'), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          codcontrato: Number(aceiteContract),
          caixa_identificacao: formData.cadNumero || '',
          cd_cliente: codigoCliente
        })
      });
      const data = await r.json().catch(() => ({}));
      if (!r.ok) {
        setConexaoError(data.error || data.message || 'Nao foi possivel criar a conexao.');
        return;
      }
      setConexaoData(data.connection || data);
      setConexaoStep(false);
      setAgendaStep(true);
      // Buscar vagas automaticamente
      loadVagas(data.connection || data);
    } catch (_e) {
      setConexaoError('Erro de conexao ao criar a conexao. Tente de novo.');
    } finally {
      setConexaoLoading(false);
    }
  }

  // --- Load scheduling slots ---
  async function loadVagas(conn) {
    const codos = conn?.ordemServico?.codordemservico || conn?.codos || '';
    const codagendaGrupo = conn?.codagenda_grupo || '2';
    if (!codos) {
      setVagasError('Numero da OS nao encontrado. Tente agendar pelo telefone.');
      return;
    }
    setVagasLoading(true);
    setVagasError('');
    try {
      const params = new URLSearchParams({ codagenda_grupo: codagendaGrupo, codos: String(codos) });
      const r = await fetch(appApiUrl(`/api/mk/vagas-agenda?${params.toString()}`));
      const data = await r.json().catch(() => ({}));
      if (!r.ok) {
        setVagasError(data.error || data.message || 'Nao foi possivel buscar horarios.');
        return;
      }
      setVagasOpcoes(data.opcoes || []);
    } catch (_e) {
      setVagasError('Erro de conexao ao buscar horarios.');
    } finally {
      setVagasLoading(false);
    }
  }

  // --- Schedule OS ---
  async function agendarOs() {
    if (!vagaSelecionada) return;
    setAgendarLoading(true);
    setAgendarError('');
    try {
      const codos = conexaoData?.ordemServico?.codordemservico || conexaoData?.codos || '';
      const r = await fetch(appApiUrl('/api/mk/agendar-os'), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          codigoOS: String(codos),
          tecnico: vagaSelecionada.tecnico || '',
          data_hora_inicio: vagaSelecionada.data_hora_inicio || '',
          data_hora_fim: vagaSelecionada.data_hora_fim || ''
        })
      });
      const data = await r.json().catch(() => ({}));
      if (!r.ok) {
        setAgendarError(data.error || data.message || 'Nao foi possivel agendar.');
        return;
      }
      setOsAgendada(true);
    } catch (_e) {
      setAgendarError('Erro de conexao ao agendar. Tente de novo.');
    } finally {
      setAgendarLoading(false);
    }
  }

  // Auto-trigger connection creation when conexaoStep is entered
  useEffect(() => {
    if (!conexaoStep || agendaStep || conexaoLoading || conexaoData) return;
    criarConexao();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [conexaoStep]);

  async function submitAceite() {
    if (!aceiteSelfie || !aceiteAssinatura) return;
    if (!aceiteContract) {
      setAceiteError('O contrato ainda nao foi gerado. Aguarde um instante.');
      return;
    }
    setAceiteError('');
    setAceiteLoading(true);
    try {
      const fd = new FormData();
      fd.append('contrato', aceiteContract);
      fd.append('selfie', aceiteSelfie, 'selfie.jpg');
      fd.append('assinatura', aceiteAssinatura, 'assinatura.png');
      const r = await fetch(appApiUrl('/api/mk/aceite-selfie-assinatura'), {
        method: 'POST',
        body: fd
      });
      const data = await r.json().catch(() => ({}));
      if (!r.ok) {
        setAceiteError(
          data.error ||
            data.message ||
            'Nao foi possivel enviar a assinatura. Tente de novo.'
        );
        return;
      }
      setAceiteDebugMode(data.debug === true);
      setAceiteStep(false);
      // Se selfie foi verificada de verdade (não revisão manual), cria conexão e agenda OS
      // Se foi pra revisão manual, a equipe entra em contato depois pra agendar
      if (codigoCliente && aceiteContract && !selfieManualReview) {
        setConexaoStep(true);
      } else {
        setSubmitted(true);
      }
    } catch (_e) {
      setAceiteError('Erro de conexao. Verifique a internet e tente de novo.');
    } finally {
      setAceiteLoading(false);
    }
  }

  if (aceiteStep) {
    const contractReady = !!aceiteContract;
    const canSend =
      contractReady && !!aceiteSelfie && !!aceiteAssinatura && !aceiteLoading && (selfieVerified || !selfieVerifying);
    return (
      <>
        <style>{`
          :root {
            --bg: #dceefb;
            --bg-card: #ffffff;
            --primary: #1a6fb5;
            --primary-dark: #124d7e;
            --primary-light: #e8f4fd;
            --primary-glow: #2e8fd8;
            --text: #1c3a52;
            --text-muted: #5a7d99;
            --border: #b8d8f0;
            --radius: 14px;
            --radius-sm: 10px;
            --shadow-lg: 0 8px 32px rgba(26, 111, 181, 0.12);
          }
          *, *::before, *::after { box-sizing: border-box; }
          html, body, #root { width: 100%; max-width: 100%; overflow-x: hidden; margin: 0; padding: 0; }
          body { font-family: 'Outfit', sans-serif; }
          @keyframes fadeUp {
            from { opacity: 0; transform: translateY(12px); }
            to { opacity: 1; transform: translateY(0); }
          }
          @media (max-width: 600px) {
            .bg-desktop-only { display: none !important; }
            .card-mobile-clean {
              border: none !important; box-shadow: none !important;
              border-radius: 0 !important; padding: 16px 4px !important;
              background: transparent !important;
            }
          }
        `}</style>
        <div className="bg-desktop-only" style={styles.bgLayer} />
        <div className="mobile-bg-fallback" style={styles.page}>
          <div className="app-shell-mobile" style={styles.appShell}>
            <section
              className="card-mobile-clean"
              style={{ ...styles.card, animation: 'fadeUp .4s ease both' }}
            >
              <h1 style={styles.title}>Falta so a assinatura</h1>
              <p style={{ ...styles.info, textAlign: 'center' }}>
                Envie uma selfie segurando o documento e assine abaixo para aceitar o contrato.
              </p>

              {aceiteContractLoading ? (
                <p style={{ ...styles.hint, textAlign: 'center', marginTop: '14px' }}>
                  Gerando seu contrato...
                </p>
              ) : null}

              {aceiteContractError ? (
                <div style={{ marginTop: '14px', textAlign: 'center' }}>
                  <p style={{ ...styles.warn, color: 'var(--error)' }}>
                    Nao foi possivel criar o contrato: {aceiteContractError}
                  </p>
                  <button
                    type="button"
                    onClick={createContract}
                    style={{ ...styles.secondaryButton, marginTop: '8px' }}
                  >
                    Tentar de novo
                  </button>
                </div>
              ) : null}

              {contractReady ? (
                <>
                  <p style={{ ...styles.hint, marginTop: '12px', textAlign: 'center' }}>
                    Contrato <strong style={{ color: 'var(--primary-dark)' }}>{aceiteContract}</strong> gerado.
                  </p>
                  {aceiteContractDebugMode ? (
                    <p style={{ ...styles.warn, marginTop: '6px', textAlign: 'center' }}>
                      <strong>MK_API_DEBUG:</strong> numero simulado (WSMKNovoContrato nao foi chamado).
                    </p>
                  ) : null}

                  <div style={{ marginTop: '18px' }}>
                    <div style={styles.hint}>1. Selfie</div>
                    <SelfieCapture onChange={handleSelfieChange} />
                    {selfieVerifying && (
                      <p style={{ ...styles.hint, marginTop: '8px', color: 'var(--primary)' }}>
                        Verificando foto...
                      </p>
                    )}
                    {selfieVerified && aceiteSelfie && !selfieVerifying && (
                      <p style={{ ...styles.good, marginTop: '8px' }}>
                        Foto verificada! Pode assinar abaixo.
                      </p>
                    )}
                    {selfieVerifyMsg && !selfieVerifying && (
                      <div style={{
                        marginTop: '8px',
                        padding: '12px',
                        borderRadius: 'var(--radius-sm)',
                        border: selfieVerified
                          ? '1.5px solid #fde68a'
                          : '1.5px solid #fca5a5',
                        background: selfieVerified
                          ? '#fffbeb'
                          : '#fef2f2',
                        color: selfieVerified
                          ? '#92400e'
                          : '#991b1b',
                        fontSize: '0.88rem',
                        lineHeight: 1.45
                      }}>
                        {selfieVerifyMsg}
                      </div>
                    )}
                  </div>

                  <div style={{ marginTop: '22px' }}>
                    <div style={styles.hint}>2. Assinatura</div>
                    <SignaturePadField onChange={setAceiteAssinatura} height={180} />
                  </div>

                  {aceiteError ? (
                    <p style={{ ...styles.warn, marginTop: '14px', color: 'var(--error)' }}>
                      {aceiteError}
                    </p>
                  ) : null}

                  <button
                    type="button"
                    onClick={submitAceite}
                    disabled={!canSend}
                    style={{
                      ...styles.button,
                      marginTop: '18px',
                      opacity: canSend ? 1 : 0.6,
                      cursor: canSend ? 'pointer' : 'not-allowed'
                    }}
                  >
                    {aceiteLoading ? 'Enviando...' : 'Enviar e aceitar contrato'}
                  </button>

                  <p style={{ ...styles.hint, marginTop: '10px', textAlign: 'center' }}>
                    Seus dados sao enviados diretamente ao sistema da operadora.
                  </p>
                </>
              ) : null}
            </section>
          </div>
        </div>
      </>
    );
  }

  // --- Step: Criar conexao ---
  if (conexaoStep && !agendaStep) {
    return (
      <>
        <style>{`
          :root {
            --bg: #dceefb;
            --bg-card: #ffffff;
            --primary: #1a6fb5;
            --primary-dark: #124d7e;
            --primary-light: #e8f4fd;
            --primary-glow: #2e8fd8;
            --text: #1c3a52;
            --text-muted: #5a7d99;
            --border: #b8d8f0;
            --radius: 14px;
            --radius-sm: 10px;
            --shadow-lg: 0 8px 32px rgba(26, 111, 181, 0.12);
          }
          *, *::before, *::after { box-sizing: border-box; }
          html, body, #root { width: 100%; max-width: 100%; overflow-x: hidden; margin: 0; padding: 0; }
          body { font-family: 'Outfit', sans-serif; }
          @keyframes fadeUp {
            from { opacity: 0; transform: translateY(12px); }
            to { opacity: 1; transform: translateY(0); }
          }
          @media (max-width: 600px) {
            .bg-desktop-only { display: none !important; }
            .card-mobile-clean {
              border: none !important; box-shadow: none !important;
              border-radius: 0 !important; padding: 16px 4px !important;
              background: transparent !important;
            }
          }
        `}</style>
        <div className="bg-desktop-only" style={styles.bgLayer} />
        <div className="mobile-bg-fallback" style={styles.page}>
          <div className="app-shell-mobile" style={styles.appShell}>
            <section className="card-mobile-clean" style={{ ...styles.card, textAlign: 'center', animation: 'fadeUp .4s ease both' }}>
              <h1 style={styles.title}>Preparando sua conexao</h1>
              <p style={styles.info}>
                Estamos criando sua conexao e ordem de servico no sistema.
              </p>
              {conexaoLoading ? (
                <p style={{ ...styles.hint, marginTop: '14px' }}>Criando conexao...</p>
              ) : null}
              {conexaoError ? (
                <div style={{ marginTop: '14px' }}>
                  <p style={{ ...styles.warn, color: '#dc2626' }}>{conexaoError}</p>
                  <button type="button" onClick={criarConexao} style={{ ...styles.secondaryButton, marginTop: '8px' }}>
                    Tentar de novo
                  </button>
                </div>
              ) : null}
            </section>
          </div>
        </div>
      </>
    );
  }

  // --- Step: Agendar OS ---
  if (agendaStep) {
    return (
      <>
        <style>{`
          :root {
            --bg: #dceefb;
            --bg-card: #ffffff;
            --primary: #1a6fb5;
            --primary-dark: #124d7e;
            --primary-light: #e8f4fd;
            --primary-glow: #2e8fd8;
            --text: #1c3a52;
            --text-muted: #5a7d99;
            --border: #b8d8f0;
            --radius: 14px;
            --radius-sm: 10px;
            --shadow-lg: 0 8px 32px rgba(26, 111, 181, 0.12);
          }
          *, *::before, *::after { box-sizing: border-box; }
          html, body, #root { width: 100%; max-width: 100%; overflow-x: hidden; margin: 0; padding: 0; }
          body { font-family: 'Outfit', sans-serif; }
          @keyframes fadeUp {
            from { opacity: 0; transform: translateY(12px); }
            to { opacity: 1; transform: translateY(0); }
          }
          @media (max-width: 600px) {
            .bg-desktop-only { display: none !important; }
            .card-mobile-clean {
              border: none !important; box-shadow: none !important;
              border-radius: 0 !important; padding: 16px 4px !important;
              background: transparent !important;
            }
          }
        `}</style>
        <div className="bg-desktop-only" style={styles.bgLayer} />
        <div className="mobile-bg-fallback" style={styles.page}>
          <div className="app-shell-mobile" style={styles.appShell}>
            <section className="card-mobile-clean" style={{ ...styles.card, animation: 'fadeUp .4s ease both' }}>
              <h1 style={styles.title}>Agende a instalacao</h1>
              <p style={{ ...styles.info, textAlign: 'center' }}>
                Escolha o melhor horario para a visita do tecnico.
              </p>

              {vagasLoading ? (
                <p style={{ ...styles.hint, marginTop: '14px', textAlign: 'center' }}>Buscando horarios disponiveis...</p>
              ) : null}

              {vagasError ? (
                <div style={{ marginTop: '14px' }}>
                  <p style={{ ...styles.warn, color: '#dc2626' }}>{vagasError}</p>
                </div>
              ) : null}

              {!vagasLoading && vagasOpcoes.length > 0 ? (
                <div style={{ marginTop: '16px', display: 'flex', flexDirection: 'column', gap: '10px' }}>
                  {vagasOpcoes.map((v, i) => {
                    const sel = vagaSelecionada === v;
                    return (
                      <button
                        key={i}
                        type="button"
                        onClick={() => setVagaSelecionada(v)}
                        style={{
                          display: 'flex',
                          flexDirection: 'column',
                          alignItems: 'center',
                          gap: '2px',
                          padding: '14px 16px',
                          borderRadius: 'var(--radius-sm)',
                          border: sel ? '2px solid var(--primary)' : '1.5px solid var(--border)',
                          background: sel ? 'var(--primary-light)' : 'var(--bg-card)',
                          color: 'var(--text)',
                          fontFamily: "'Outfit', sans-serif",
                          fontSize: '0.92rem',
                          fontWeight: sel ? 700 : 500,
                          cursor: 'pointer',
                          transition: 'all .2s ease'
                        }}
                      >
                        <span>{v.label || v.data_hora_inicio || `Opcao ${i + 1}`}</span>
                        {v.tecnico_nome ? <span style={{ fontSize: '0.78rem', color: 'var(--text-muted)' }}>Tecnico: {v.tecnico_nome}</span> : null}
                      </button>
                    );
                  })}
                </div>
              ) : !vagasLoading && !vagasError ? (
                <p style={{ ...styles.hint, marginTop: '14px', textAlign: 'center' }}>Nenhum horario disponivel no momento.</p>
              ) : null}

              {agendarError ? (
                <p style={{ ...styles.warn, marginTop: '14px', color: '#dc2626' }}>{agendarError}</p>
              ) : null}

              {osAgendada ? (
                <div style={{ marginTop: '18px', textAlign: 'center' }}>
                  <p style={styles.good}>Instalacao agendada com sucesso!</p>
                  <button
                    type="button"
                    onClick={() => setSubmitted(true)}
                    style={{ ...styles.button, marginTop: '14px' }}
                  >
                    Concluir
                  </button>
                </div>
              ) : (
                <button
                  type="button"
                  onClick={agendarOs}
                  disabled={!vagaSelecionada || agendarLoading}
                  style={{
                    ...styles.button,
                    marginTop: '18px',
                    opacity: vagaSelecionada && !agendarLoading ? 1 : 0.6,
                    cursor: vagaSelecionada && !agendarLoading ? 'pointer' : 'not-allowed'
                  }}
                >
                  {agendarLoading ? 'Agendando...' : 'Confirmar agendamento'}
                </button>
              )}
            </section>
          </div>
        </div>
      </>
    );
  }

  if (submitted) {
    return (
      <>
        <style>{`
          :root {
            --bg: #dceefb;
            --bg-card: #ffffff;
            --primary: #1a6fb5;
            --primary-dark: #124d7e;
            --primary-light: #e8f4fd;
            --primary-glow: #2e8fd8;
            --text: #1c3a52;
            --text-muted: #5a7d99;
            --border: #b8d8f0;
            --radius: 14px;
            --radius-sm: 10px;
            --shadow-lg: 0 8px 32px rgba(26, 111, 181, 0.12);
          }
          *, *::before, *::after { box-sizing: border-box; }
          html, body, #root { width: 100%; max-width: 100%; overflow-x: hidden; margin: 0; padding: 0; }
          body { font-family: 'Outfit', sans-serif; }
          @keyframes fadeUp {
            from { opacity: 0; transform: translateY(12px); }
            to { opacity: 1; transform: translateY(0); }
          }
          @media (max-width: 600px) {
            .bg-desktop-only { display: none !important; }
            .card-mobile-clean {
              border: none !important; box-shadow: none !important;
              border-radius: 0 !important; padding: 16px 4px !important;
              background: transparent !important;
            }
          }
        `}</style>
        <div className="bg-desktop-only" style={styles.bgLayer} />
        <div className="mobile-bg-fallback" style={styles.page}>
          <div className="app-shell-mobile" style={styles.appShell}>
            <section className="card-mobile-clean" style={{ ...styles.card, textAlign: 'center', animation: 'fadeUp .4s ease both' }}>
              <h1 style={styles.title}>{osAgendada ? 'Tudo pronto!' : 'Quase la! Falta pouco!'}</h1>
              {osAgendada ? (
                <>
                  <p style={styles.good}>
                    Cadastro, contrato e instalacao agendados com sucesso!
                  </p>
                  <p style={{ ...styles.info, marginTop: '8px' }}>
                    Aguarde a visita do tecnico no horario escolhido. Se tiver duvida, entre em contato pelo WhatsApp 08002421000.
                  </p>
                </>
              ) : (
                <>
                  <p style={styles.info}>
                    Enviamos os proximos passos para o WhatsApp informado, com orientacoes para baixar o aplicativo
                    e assinar o contrato sem sair de casa.
                  </p>
                  <p style={{ ...styles.info, marginTop: '8px' }}>
                    Se tiver alguma duvida ou nao recebeu a mensagem, entre em contato pelo WhatsApp no telefone
                    08002421000.
                  </p>
                </>
              )}

              {submitDebugMode ? (
                <p style={{ ...styles.warn, marginTop: '14px', textAlign: 'left' }}>
                  <strong>MK_API_DEBUG:</strong> a API de endereco (5087) foi chamada; o CRM nao recebeu cadastro.
                  Parametros completos da chamada ao CRM estao no console do Node (inclui token).
                </p>
              ) : null}

              {aceiteDebugMode ? (
                <p style={{ ...styles.warn, marginTop: '10px', textAlign: 'left' }}>
                  <strong>MK_API_DEBUG:</strong> o aceite (selfie + assinatura) NAO foi enviado ao MK.
                  Curl equivalente e metadados dos arquivos estao no console do Node.
                </p>
              ) : null}

              <a
                href="https://wa.me/558002421000?text=Oi!%20Estou%20com%20duvida%20ou%20nao%20recebi%20a%20mensagem%20do%20cadastro."
                target="_blank"
                rel="noreferrer"
                style={{ textDecoration: 'none', display: 'block', marginTop: '16px' }}
              >
                <button type="button" style={styles.button}>
                  Entrar em contato
                </button>
              </a>

              <p style={{ ...styles.info, marginTop: '16px', marginBottom: '0' }}>
                O video abaixo e um passo a passo de como assinar o contrato.
              </p>

              <video
                src="./WhatsApp Video 2026-04-08 at 09.54.06.mp4"
                controls
                autoPlay
                muted
                loop
                playsInline
                style={{
                  width: '100%',
                  borderRadius: 'var(--radius)',
                  border: '1.5px solid var(--border)',
                  marginTop: '12px',
                  background: '#000'
                }}
              />

              <p style={{ ...styles.hint, marginTop: '10px' }}>
                Este video e apenas para desenvolvimento e nao representa o produto final.
              </p>
            </section>
          </div>
        </div>
      </>
    );
  }

  return (
    <>
      <style>{`
        :root {
          --bg: #dceefb;
          --bg-card: #ffffff;
          --primary: #1a6fb5;
          --primary-dark: #124d7e;
          --primary-light: #e8f4fd;
          --primary-glow: #2e8fd8;
          --text: #1c3a52;
          --text-muted: #5a7d99;
          --border: #b8d8f0;
          --border-focus: #2e8fd8;
          --input-bg: #f4faff;
          --success: #16a34a;
          --success-bg: #dcfce7;
          --error: #dc2626;
          --error-bg: #fef2f2;
          --radius: 14px;
          --radius-sm: 10px;
          --shadow-sm: 0 1px 3px rgba(26, 111, 181, 0.08);
          --shadow-md: 0 4px 16px rgba(26, 111, 181, 0.10);
          --shadow-lg: 0 8px 32px rgba(26, 111, 181, 0.12);
        }

        *, *::before, *::after { box-sizing: border-box; }

        html { font-size: 16px; -webkit-text-size-adjust: 100%; }
        html, body, #root { width: 100%; max-width: 100%; overflow-x: hidden; margin: 0; padding: 0; }
        body { font-family: 'Outfit', sans-serif; }

        @keyframes fadeUp {
          from { opacity: 0; transform: translateY(12px); }
          to { opacity: 1; transform: translateY(0); }
        }
        @keyframes manualFieldPulse {
          0% { box-shadow: 0 0 0 0 rgba(46, 143, 216, 0.35); border-color: var(--border-focus); }
          70% { box-shadow: 0 0 0 10px rgba(46, 143, 216, 0); border-color: var(--border-focus); }
          100% { box-shadow: 0 0 0 0 rgba(46, 143, 216, 0); border-color: var(--border-focus); }
        }

        /* ── Form inputs ── */
        .form-group { margin-bottom: 20px; }
        .form-group:last-child { margin-bottom: 0; }

        .form-label {
          display: block;
          font-size: 0.78rem;
          font-weight: 600;
          color: var(--text-muted);
          text-transform: uppercase;
          letter-spacing: 0.06em;
          margin-bottom: 6px;
        }

        .form-input {
          width: 100%;
          height: 52px;
          padding: 0 16px;
          font-family: 'Outfit', sans-serif;
          font-size: 1rem;
          font-weight: 500;
          color: var(--text);
          background: var(--input-bg);
          border: 1.5px solid var(--border);
          border-radius: var(--radius-sm);
          outline: none;
          transition: border-color 0.2s, box-shadow 0.2s;
          -webkit-appearance: none;
        }
        .form-input:focus {
          border-color: var(--border-focus);
          box-shadow: 0 0 0 3px rgba(46, 143, 216, 0.15);
        }
        .form-input::placeholder {
          color: var(--text-muted);
          font-weight: 400;
        }
        .form-input.filled {
          border-color: var(--success);
          background: var(--success-bg);
        }
        .form-input.manual-focus-target {
          border-color: var(--border-focus);
          box-shadow: 0 0 0 3px rgba(46, 143, 216, 0.15);
          animation: manualFieldPulse 1.2s ease-out 1;
        }
        .form-input.has-error {
          border-color: var(--error);
          background: var(--error-bg);
        }
        .form-input.readonly {
          background: #edf2f7;
          border-style: dashed;
          color: var(--text-muted);
        }

        .form-hint {
          font-size: 0.8rem;
          color: var(--text-muted);
          margin-top: 4px;
        }
        .form-error {
          font-size: 0.82rem;
          color: var(--error);
          font-weight: 600;
          margin-top: 4px;
        }

        /* ── Email joined input ── */
        .email-row {
          display: flex;
          align-items: stretch;
        }
        .email-row .form-input {
          border-top-right-radius: 0;
          border-bottom-right-radius: 0;
          border-right: none;
        }
        .email-domain {
          display: flex;
          align-items: center;
          padding: 0 14px;
          height: 52px;
          background: var(--primary-light);
          border: 1.5px solid var(--border);
          border-left: none;
          border-top-right-radius: var(--radius-sm);
          border-bottom-right-radius: var(--radius-sm);
          font-size: 0.88rem;
          font-weight: 600;
          color: var(--primary);
          white-space: nowrap;
        }

        /* ── Step dots ── */
        .step-indicator {
          display: inline-flex;
          align-items: center;
          gap: 8px;
          background: var(--bg-card);
          border: 1.5px solid var(--border);
          border-radius: 100px;
          padding: 8px 18px;
          font-size: 0.82rem;
          font-weight: 600;
          color: var(--text-muted);
          box-shadow: var(--shadow-sm);
        }
        .step-dots {
          display: flex;
          gap: 5px;
        }
        .step-dot {
          width: 8px;
          height: 8px;
          border-radius: 50%;
          background: var(--border);
          transition: all 0.3s ease;
        }
        .step-dot.active {
          background: var(--primary);
          width: 20px;
          border-radius: 100px;
        }
        .step-dot.done {
          background: var(--success);
        }

        /* ── Toggle switch ── */
        .toggle-row {
          display: flex;
          align-items: center;
          justify-content: space-between;
          gap: 12px;
          margin: 10px 0 6px;
          flex-wrap: nowrap;
          width: 100%;
        }
        .toggle-left {
          display: flex;
          align-items: center;
          gap: 10px;
          min-width: 0;
          flex: 1;
        }
        .wa-icon {
          width: 28px;
          height: 28px;
          border-radius: 999px;
          background: var(--border);
          color: #fff;
          display: inline-flex;
          align-items: center;
          justify-content: center;
          flex-shrink: 0;
          transition: background .16s ease;
        }
        .toggle-label-text {
          font-size: 0.9rem;
          font-weight: 600;
          color: var(--text);
          white-space: nowrap;
        }
        .wa-off { display: inline; }
        .wa-on { display: none; }
        .toggle-switch {
          -webkit-appearance: none;
          appearance: none;
          display: flex;
          align-items: center;
          justify-content: flex-start;
          width: 3.5rem;
          min-width: 3.5rem;
          height: 2rem;
          padding: .25rem;
          border: 1.5px solid var(--border);
          border-radius: 1rem;
          background: var(--input-bg);
          cursor: pointer;
          transition: background 120ms ease-in-out, border-color 120ms ease-in-out;
          flex-shrink: 0;
        }
        .toggle-switch::before {
          content: "";
          display: block;
          width: 1.25rem;
          height: 1.25rem;
          background: var(--border);
          border-radius: 1rem;
          transform: translateX(0);
          transition: transform 120ms ease-in-out, background 120ms ease-in-out;
        }
        .toggle-switch:checked {
          background: #25d366;
          border-color: #25d366;
        }
        .toggle-switch:checked::before {
          transform: translateX(1.5rem);
          background: #fff;
        }
        .toggle-row:has(.toggle-switch:checked) .wa-icon {
          background: #25d366;
          animation: waBuzz .25s cubic-bezier(.9, 0, .1, 1);
        }
        .toggle-row:has(.toggle-switch:checked) .wa-on { display: inline; }
        .toggle-row:has(.toggle-switch:checked) .wa-off { display: none; }
        .toggle-row.toggle-attention {
          outline: 3px solid #ffdd00;
          outline-offset: 3px;
          border-radius: var(--radius-sm);
          animation: waAttention .65s ease-out 2;
        }
        .toggle-switch:focus-visible {
          outline: 3px solid var(--border-focus) !important;
          outline-offset: 2px;
          box-shadow: 0 0 0 3px rgba(46,143,216,.25) !important;
        }
        @keyframes waBuzz {
          0%, 100% { transform: translateX(0%); }
          20% { transform: translateX(-5%); }
          40% { transform: translateX(5%); }
          60% { transform: translateX(-5%); }
          80% { transform: translateX(5%); }
        }
        @keyframes waAttention {
          0% { box-shadow: 0 0 0 0 rgba(255, 221, 0, .55); }
          100% { box-shadow: 0 0 0 12px rgba(255, 221, 0, 0); }
        }

        /* ── Button animations ── */
        @keyframes btnReady {
          0% { box-shadow: 0 0 0 0 rgba(26,111,181,.5); }
          60% { box-shadow: 0 0 0 10px rgba(26,111,181,0); }
          100% { box-shadow: 0 0 0 0 rgba(26,111,181,0); }
        }
        .btn-ready-pulse {
          animation: btnReady .65s ease-out 1;
        }

        /* ── Focus visible ── */
        button:focus-visible,
        select:focus-visible,
        [role="button"]:focus-visible {
          outline: 3px solid var(--border-focus) !important;
          outline-offset: 0;
          box-shadow: 0 0 0 3px rgba(46,143,216,.25) !important;
        }
        button:active { transform: scale(0.98); }

        /* ── Desktop tweaks ── */
        @media (min-width: 480px) {
          .form-wrapper-inner { padding: 32px 28px; }
          .provider-chips-grid { flex-wrap: nowrap !important; }
          .provider-chips-grid > * { min-width: auto !important; }
          .phone-block { margin-top: 14px; }
        }

        /* ── Responsive mobile ── */
        @media (max-width: 600px) {
          .bg-desktop-only { display: none !important; }
          .mobile-bg-fallback {
            background: var(--bg) !important;
            background-image: radial-gradient(circle at 20% 10%, rgba(46,143,216,.08) 0%, transparent 50%),
                              radial-gradient(circle at 80% 90%, rgba(46,143,216,.06) 0%, transparent 50%) !important;
            padding: 12px 8px 24px !important;
          }
          .app-shell-mobile, .app-shell-mobile * {
            min-width: 0 !important;
            max-width: 100% !important;
          }
          .row-desktop { flex-wrap: wrap !important; }
          .row-desktop > * { flex: 1 1 100% !important; min-width: 100% !important; }
          .toggle-row { width: 100% !important; justify-content: flex-start !important; }
          .toggle-left { flex: 1 1 auto !important; min-width: 0 !important; }
          .toggle-label-text { white-space: normal !important; overflow-wrap: anywhere; }
          .card-mobile-clean {
            border: none !important;
            box-shadow: none !important;
            border-radius: 0 !important;
            padding: 16px 4px !important;
            background: transparent !important;
          }
          section.sonik-card {
            background: transparent !important;
            border: none !important;
            box-shadow: none !important;
            padding: 0 4px !important;
          }
        }
      `}</style>
      <div className="bg-desktop-only" style={styles.bgLayer} />
      <div className="mobile-bg-fallback" style={styles.page}>
        <div className="app-shell-mobile" style={styles.appShell}>
      {showMapModal ? (
        <div style={{
          position: 'fixed',
          inset: 0,
          background: 'rgba(0,0,0,0.55)',
          display: 'flex',
          flexDirection: 'column',
          zIndex: 60,
          padding: '16px'
        }}>
          <div style={{
            flex: 1,
            display: 'flex',
            flexDirection: 'column',
            background: 'var(--bg-card)',
            borderRadius: 'var(--radius)',
            overflow: 'hidden',
            boxShadow: 'var(--shadow-lg)',
            maxWidth: '600px',
            width: '100%',
            margin: '0 auto',
            position: 'relative'
          }}>
            <div style={{
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'space-between',
              padding: '14px 16px',
              borderBottom: '1.5px solid var(--border)'
            }}>
              <span style={{ fontWeight: 700, fontSize: '1rem', color: 'var(--primary-dark)' }}>
                Toque no mapa para marcar sua casa
              </span>
              <button
                type="button"
                onClick={closeMapModal}
                style={{
                  width: '36px',
                  height: '36px',
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  border: '1.5px solid var(--border)',
                  borderRadius: '50%',
                  background: 'var(--input-bg)',
                  color: 'var(--text)',
                  fontSize: '1.1rem',
                  fontWeight: 700,
                  cursor: 'pointer',
                  lineHeight: 1
                }}
                aria-label="Fechar mapa"
              >
                ✕
              </button>
            </div>

            <div ref={mapRef} style={{ flex: 1, minHeight: '300px', width: '100%' }} />

            <div style={{ padding: '16px', borderTop: '1.5px solid var(--border)' }}>
              {!leafletReady && !mapMessage ? (
                <p style={{ ...styles.warn, margin: '0 0 10px' }}>
                  Mapa OpenStreet aguardando carregamento.
                </p>
              ) : null}

              {mapPickedAddress ? (
                <div style={{ animation: 'fadeUp .3s ease both', marginBottom: '12px' }}>
                  <p style={{ ...styles.info, margin: '0 0 4px', fontWeight: 600 }}>
                    {mapPickedAddress.street || 'Rua nao identificada'}
                    {mapPickedAddress.suburb ? ` — ${mapPickedAddress.suburb}` : ''}
                  </p>
                  {mapPickedAddress.city ? (
                    <p style={{ ...styles.hint, margin: '0 0 10px' }}>
                      {mapPickedAddress.city}{mapPickedAddress.state ? `/${mapPickedAddress.state}` : ''}
                    </p>
                  ) : null}
                  <p style={{ ...styles.info, margin: '0 0 10px', fontWeight: 600, color: 'var(--primary-dark)' }}>
                    E este o seu endereco?
                  </p>
                  <div style={{ display: 'flex', gap: '10px' }}>
                    <button type="button" className="btn-ready-pulse" style={{ ...styles.button, flex: 1, marginTop: 0 }} onClick={confirmMapAddress}>
                      Sim, usar este
                    </button>
                    <button
                      type="button"
                      style={{ ...styles.secondaryButton, flex: 1, marginTop: 0 }}
                      onClick={() => {
                        setMapPickedAddress(null);
                        setMapMessage('Toque em outro ponto do mapa.');
                      }}
                    >
                      Nao, outro local
                    </button>
                  </div>
                </div>
              ) : null}

              <button
                type="button"
                style={styles.emailSkipLink}
                onClick={() => {
                  closeMapModal();
                  setShowManualAddress(true);
                  setMapMessage('');
                  setHighlightManualAddressField(true);
                  setTimeout(() => {
                    logradouroInputRef.current?.focus();
                  }, 80);
                  setTimeout(() => {
                    setHighlightManualAddressField(false);
                  }, 1600);
                }}
              >
                Prefiro informar manualmente
              </button>
            </div>
          </div>
        </div>
      ) : null}

      {showEmailSkipModal ? (
        <div style={styles.modalOverlay}>
          <div style={styles.modalCard}>
            <h3 style={{ margin: '0 0 10px', fontSize: '1.25rem', fontWeight: 700, color: 'var(--primary-dark)' }}>Continuar sem e-mail?</h3>
            <p style={{ ...styles.info, marginTop: 0 }}>
              Se voce nao informar e-mail, nao sera possivel selecionar planos com aplicativos e beneficios digitais.
            </p>
            <p style={styles.warn}>
              Seus planos disponiveis ficarao limitados a opcoes somente de internet, sem beneficios extras que dependem de e-mail.
            </p>
            <button
              type="button"
              style={styles.button}
              onClick={() => {
                setEmailSkipped(true);
                setEmailReady(true);
                setShowPhoneField(true);
                setShowEmailSkipModal(false);
              }}
            >
              Entendi, continuar sem e-mail
            </button>
            <button type="button" style={styles.secondaryButton} onClick={() => setShowEmailSkipModal(false)}>
              Voltar e informar e-mail
            </button>
          </div>
        </div>
      ) : null}

      {showWhatsAppModal ? (
        <div style={styles.modalOverlay}>
          <div style={styles.modalCard}>
            <h3 style={{ margin: '0 0 10px', fontSize: '1.25rem', fontWeight: 700, color: 'var(--primary-dark)' }}>Voce tem WhatsApp nesse numero?</h3>
            <p style={{ ...styles.info, marginTop: 0 }}>
              Usar o WhatsApp deixa tudo mais rapido: a gente te avisa sobre a instalacao,
              envia boletos e tira duvidas ali mesmo, sem burocracia.
            </p>
            <button
              type="button"
              style={styles.button}
              onClick={() => guideToWhatsAppToggle(true)}
            >
              Sim, tenho WhatsApp!
            </button>
            <button
              type="button"
              style={styles.secondaryButton}
              onClick={() => guideToWhatsAppToggle(false)}
            >
              Continuar sem WhatsApp
            </button>
          </div>
        </div>
      ) : null}

      <div style={{ textAlign: 'center', marginBottom: '24px', animation: 'fadeUp .4s ease both' }}>
        <h1 style={styles.title}>Venha ser Sonik!</h1>
        {formData.cadDoc.length === 0 ? (
          <p style={styles.subtitle}>Digite seu CPF para iniciar seu cadastro.</p>
        ) : null}
        {formData.cadDoc.length > 0 ? (
          <div className="step-indicator">
            <div className="step-dots">
              {Array.from({ length: totalSteps }, (_, i) => {
                const stepNum = i + 1;
                const isActive = stepNum === currentStep;
                const isDone = stepNum < currentStep;
                return <div key={i} className={`step-dot${isActive ? ' active' : ''}${isDone ? ' done' : ''}`} />;
              })}
            </div>
            <span>{currentStepLabel}</span>
          </div>
        ) : null}
      </div>

      {currentStep === 1 && (
        <>
        <section className="sonik-card" style={{ ...styles.card, ...styles.revealBlock, animation: 'fadeUp .4s ease .1s both' }}>
          <div style={styles.stepContent}>
          <InputField
            label="CPF"
            value={formData.cadDoc}
            onChange={handleCpfChange}
            onBlur={() => touchField('cadDoc')}
            placeholder="000.000.000-00"
            inputMode="numeric"
            error={getInlineError('cadDoc')}
            fieldSize="md"
          />
          {cpfConsultLoading ? (
            <p style={{ ...styles.hint, marginTop: '-0.25rem' }}>Consultando CPF...</p>
          ) : null}
          {cpfConsultError ? (
            <p style={{ ...styles.warn, marginTop: '-0.25rem' }}>{cpfConsultError}</p>
          ) : null}

          {serasaStatus === 'rejected' ? (
            <p style={styles.warn}>Vamos continuar para finalizar seu cadastro com analise humana.</p>
          ) : null}

          {showIdentityDetails ? (
            <>
              <InputField label="Nome completo" value={formData.cadNome} readOnly placeholder="Sera preenchido automaticamente" />
              <InputField
                label="Data de nascimento"
                value={formData.cadNascimento}
                readOnly
                placeholder="Sera preenchido automaticamente"
              />
            </>
          ) : null}
          {showEmail ? (
            <>
              {emailProvider === 'custom' ? (
                <div className="form-group">
                  <label className="form-label" htmlFor="fld-e-mail">E-mail</label>
                  <input
                    id="fld-e-mail"
                    className={`form-input${emailFieldError ? ' has-error' : ''}`}
                    value={formData.cadEmail}
                    onChange={(e) => setField('cadEmail', e.target.value)}
                    onBlur={() => {
                      touchField('cadEmail');
                      setEmailReady(isEmailValid(formData.cadEmail));
                    }}
                    placeholder="exemplo@provedor.com.br"
                    type="text"
                    inputMode="email"
                    autoComplete="email"
                    aria-invalid={emailFieldError ? 'true' : 'false'}
                  />
                  {emailFieldError ? <div className="form-error">{emailFieldError}</div> : null}
                </div>
              ) : (
                <div className="form-group">
                  <label className="form-label" htmlFor="fld-email-local">E-mail</label>
                  <div className="email-row">
                    <input
                      id="fld-email-local"
                      className={`form-input${emailFieldError ? ' has-error' : ''}`}
                      value={emailLocalFromValue(formData.cadEmail, emailProvider)}
                      onChange={handleEmailLocalChange}
                      onBlur={() => {
                        touchField('cadEmail');
                        setEmailReady(isEmailValid(formData.cadEmail));
                      }}
                      placeholder="seu.email"
                      type="text"
                      inputMode="email"
                      autoComplete="email"
                      aria-invalid={emailFieldError ? 'true' : 'false'}
                    />
                    <div className="email-domain">{EMAIL_PRESETS[emailProvider]}</div>
                  </div>
                  {emailFieldError ? <div className="form-error">{emailFieldError}</div> : null}
                </div>
              )}
              <div className="provider-chips-grid" style={styles.emailProviderRow} role="group" aria-label="Provedor de e-mail">
                {['gmail', 'outlook', 'hotmail', 'custom'].map((key) => {
                  const isActive = emailProvider === key;
                  const label = key === 'gmail' ? 'Gmail' : key === 'outlook' ? 'Outlook' : key === 'hotmail' ? 'Hotmail' : 'Outro';
                  return (
                    <button
                      key={key}
                      type="button"
                      style={{
                        ...styles.emailProviderButton,
                        ...(isActive ? styles.emailProviderButtonActive : {})
                      }}
                      aria-pressed={isActive}
                      onClick={() => setEmailProvider(key)}
                    >
                      {label}
                    </button>
                  );
                })}
              </div>
              {!showPhone ? (
                <button
                  type="button"
                  style={styles.emailSkipLink}
                  onClick={() => setShowEmailSkipModal(true)}
                >
                  Nao quero informar e-mail
                </button>
              ) : null}
            </>
          ) : null}
          {showPhone ? (
            <div className="phone-block" style={{ ...styles.revealBlock, width: '100%' }}>
              <InputField
                label="Telefone / Celular"
                value={formData.cadFone}
                onChange={handlePhoneChange}
                onBlur={() => touchField('cadFone')}
                placeholder="(DDD) 00000-0000"
                type="tel"
                inputMode="tel"
                hint="Digite com DDD. Exemplo: (11) 99999-9999"
                error={getInlineError('cadFone')}
                fieldSize="md"
              />
              <div className={`toggle-row ${whatsAppAttention ? 'toggle-attention' : ''}`} style={{ margin: '0 0 14px', width: '100%' }}>
                <label htmlFor="whatsapp-toggle" className="toggle-left">
                  <span className="wa-icon" aria-hidden="true">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                      <path d="M12 2a10 10 0 0 0-8.66 15l-1.34 5 5.12-1.34A10 10 0 1 0 12 2Zm0 18a7.9 7.9 0 0 1-4-1.08l-.28-.16-2.56.67.67-2.5-.17-.28A8 8 0 1 1 12 20Zm4.34-5.74c-.24-.12-1.41-.7-1.63-.77-.22-.08-.38-.12-.54.12s-.62.77-.76.93c-.14.16-.27.18-.5.06-.24-.12-1-.37-1.9-1.18-.7-.63-1.17-1.4-1.31-1.64-.14-.24-.02-.36.1-.48.11-.11.24-.28.36-.42.12-.14.16-.24.24-.4.08-.16.04-.3-.02-.42-.06-.12-.54-1.3-.74-1.78-.2-.48-.4-.42-.54-.43h-.46c-.16 0-.42.06-.64.3-.22.24-.84.82-.84 2s.86 2.32.98 2.48c.12.16 1.68 2.56 4.07 3.58.57.24 1.02.39 1.37.49.58.18 1.1.16 1.52.1.46-.07 1.41-.58 1.61-1.14.2-.56.2-1.03.14-1.14-.06-.1-.22-.16-.46-.28Z" />
                    </svg>
                  </span>
                  <span className="toggle-label-text">
                    Tem WhatsApp? <span className="wa-off">Nao</span><span className="wa-on">Sim</span>
                  </span>
                </label>
                <input
                  type="checkbox"
                  id="whatsapp-toggle"
                  ref={whatsappToggleRef}
                  className="toggle-switch"
                  checked={hasWhatsApp === true}
                  onChange={(e) => setHasWhatsApp(e.target.checked)}
                  aria-label="Esse numero tem WhatsApp"
                />
              </div>
            </div>
          ) : null}

          {showAdvanceToAddressButton ? (
            <button type="button" className={identificationOk ? 'btn-ready-pulse' : undefined} style={{ ...styles.button, opacity: identificationOk ? 1 : 0.6, marginTop: '16px' }} onClick={goToAddress}>
              Informar endereco
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/><circle cx="12" cy="9" r="2.5"/></svg>
            </button>
          ) : null}
          </div>
        </section>
        {showPrivacyBanner ? (
          <p style={styles.privacyBanner} role="status">
            Seus dados sao protegidos e usados apenas para validar seu cadastro.
          </p>
        ) : null}
        </>
      )}

      {currentStep === 2 && (
        <section className="sonik-card" style={{ ...styles.card, ...styles.revealBlock, animation: 'fadeUp .4s ease .1s both' }}>
          <div style={styles.stepContent}>
          <InputField
            label="CEP"
            value={formData.cadCEP}
            onChange={handleCepChange}
            onBlur={() => {
              touchField('cadCEP');
              const cepDigits = onlyDigits(formData.cadCEP);
              if (cepDigits.length === 8) lookupCepByApi(cepDigits);
            }}
            placeholder="00000-000"
            inputMode="numeric"
            error={getInlineError('cadCEP')}
            fieldSize="sm"
          />

          {addressLoading ? <p style={{ ...styles.info, marginBottom: '10px' }}>Buscando endereco...</p> : null}
          {addressMsg ? <p style={{ ...styles.info, marginBottom: '10px' }}>{addressMsg}</p> : null}

          <button
            type="button"
            style={{
              ...styles.secondaryButton,
              marginBottom: '8px',
              ...(locationError
                ? { background: '#fee2e2', borderColor: '#ef4444', color: '#b91c1c' }
                : {})
            }}
            onClick={handleUseMyLocation}
          >
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><circle cx="12" cy="12" r="3"/><path d="M12 2v4m0 12v4m10-10h-4M6 12H2"/><circle cx="12" cy="12" r="8"/></svg>
            {locationLoading ? 'Buscando localizacao...' : 'Usar minha localizacao'}
          </button>
          {locationError ? (
            <p style={{ ...styles.error, marginTop: 0, marginBottom: '8px' }}>{locationError}</p>
          ) : null}

          <button
            type="button"
            style={{ ...styles.secondaryButton, marginBottom: '12px' }}
            onClick={() => {
              mapInstanceRef.current = null;
              markerRef.current = null;
              setMapPickedAddress(null);
              setMapMessage('');
              setShowMapModal(true);
            }}
          >
            Nao sei meu CEP / Minha rua nao tem CEP
          </button>

          {mapMessage ? <p style={{ ...styles.info, marginBottom: '10px' }}>{mapMessage}</p> : null}

          {showLogradouro ? (
            showNumero ? (
              <div className="row-desktop" style={{ display: 'flex', gap: '12px', width: '100%', alignItems: 'flex-end', marginBottom: '12px' }}>
                <div style={{ flex: '7 1 0', minWidth: 0 }}>
                  <InputField
                    label="Rua / Avenida"
                    value={formData.cadLogradouro}
                    onChange={(e) => setField('cadLogradouro', e.target.value)}
                    placeholder="Ex: Rua das Flores"
                    inputRef={logradouroInputRef}
                    inputClassName={highlightManualAddressField ? 'manual-focus-target' : ''}
                  />
                </div>
                <div style={{ flex: '3 1 0', minWidth: 0 }}>
                  <InputField
                    label="Numero"
                    value={formData.cadNumero}
                    onChange={(e) => setField('cadNumero', e.target.value)}
                    placeholder="Ex: 120"
                    inputMode="numeric"
                    fieldSize="xs"
                  />
                </div>
              </div>
            ) : (
              <InputField
                label="Rua / Avenida"
                value={formData.cadLogradouro}
                onChange={(e) => setField('cadLogradouro', e.target.value)}
                placeholder="Ex: Rua das Flores"
                inputRef={logradouroInputRef}
                inputClassName={highlightManualAddressField ? 'manual-focus-target' : ''}
              />
            )
          ) : null}
          {showBairro ? (
            <InputField
              label="Bairro"
              value={formData.cadBairro}
              onChange={(e) => setField('cadBairro', e.target.value)}
              placeholder="Ex: Centro"
            />
          ) : null}
          {showTipoLocal ? (
            <>
              <div style={{ ...styles.label, marginTop: '2px' }}>Tipo de local</div>
              <div style={styles.choiceWrap}>
                {[
                  { id: 'casa', label: 'Casa' },
                  { id: 'predio', label: 'Predio' },
                  { id: 'sitio', label: 'Sitio' },
                  { id: 'comercial', label: 'Comercial' },
                  { id: 'outro', label: 'Outro' }
                ].map((op) => (
                  <button
                    key={op.id}
                    type="button"
                    onClick={() => setField('cadLocalTipo', op.id)}
                    style={{
                      ...styles.choiceButton,
                      ...(formData.cadLocalTipo === op.id ? styles.choiceButtonActive : {})
                    }}
                  >
                    {op.label}
                  </button>
                ))}
              </div>
              {!formData.cadLocalTipo ? <p style={styles.error}>Escolha o tipo de local.</p> : null}
            </>
          ) : null}

          {showApartamento ? (
            <InputField
              label="Apartamento"
              value={formData.cadApartamento}
              onChange={(e) => setField('cadApartamento', e.target.value)}
              placeholder="Ex: 101, Bloco B"
              error={!formData.cadApartamento ? 'Informe o apartamento.' : null}
              fieldSize="sm"
            />
          ) : null}

          {showCidade ? (
            showUF ? (
              <div className="row-desktop" style={{ display: 'flex', gap: '12px', width: '100%', alignItems: 'flex-end', marginBottom: '12px' }}>
                <div style={{ flex: '8 1 0', minWidth: 0 }}>
                  <InputField
                    label="Cidade"
                    value={formData.cadCidade}
                    onChange={(e) => setField('cadCidade', e.target.value)}
                    placeholder="Ex: Belo Horizonte"
                  />
                </div>
                <div style={{ flex: '2 1 0', minWidth: 0 }}>
                  <InputField
                    label="Estado (UF)"
                    value={formData.cadUF}
                    readOnly
                    placeholder="UF"
                    fieldSize="xs"
                  />
                </div>
              </div>
            ) : (
              <InputField
                label="Cidade"
                value={formData.cadCidade}
                onChange={(e) => setField('cadCidade', e.target.value)}
                placeholder="Ex: Belo Horizonte"
              />
            )
          ) : null}
          {showUF && !formData.cadUF ? (
            <p style={styles.warn}>O estado e preenchido pela API de CEP/localizacao. Confirme o CEP para continuar.</p>
          ) : null}

          <div style={{ display: 'flex', flexDirection: 'column', gap: '10px', marginTop: '16px' }}>
            {viabChecking && (
              <p style={{ ...styles.hint, color: 'var(--primary)' }}>
                Verificando cobertura no seu endereço...
              </p>
            )}
            {viabResult === 'VIÁVEL' && !viabChecking && (
              <p style={styles.good}>
                Cobertura disponível no seu endereço!
              </p>
            )}
            {viabMsg && !viabChecking && (
              <div style={{
                marginTop: '0',
                padding: '12px',
                borderRadius: 'var(--radius-sm)',
                border: viabResult === 'ANÁLISE NECESSÁRIA'
                  ? '1.5px solid #fde68a'
                  : '1.5px solid #fca5a5',
                background: viabResult === 'ANÁLISE NECESSÁRIA'
                  ? '#fffbeb'
                  : '#fef2f2',
                color: viabResult === 'ANÁLISE NECESSÁRIA'
                  ? '#92400e'
                  : '#991b1b',
                fontSize: '0.88rem',
                lineHeight: 1.45
              }}>
                {viabMsg}
              </div>
            )}
            <button type="button" className={addressOk && viabResult !== 'NÃO VIÁVEL' ? 'btn-ready-pulse' : undefined} style={{ ...styles.button, opacity: addressOk && viabResult !== 'NÃO VIÁVEL' ? 1 : 0.6 }} onClick={goAfterAddress}>
              {viabChecking ? 'Verificando cobertura...' : (serasaStatus === 'approved' ? 'Escolher o plano' : 'Enviar documento')}
              {!viabChecking && <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>}
            </button>
            <button type="button" style={styles.secondaryButton} onClick={() => setCurrentStep(1)}>
              Voltar para meus dados
            </button>
          </div>
          </div>
        </section>
      )}

      {currentStep === planStep && hasPlanStep && (
        <section className="sonik-card" style={{ ...styles.card, ...styles.revealBlock, animation: 'fadeUp .4s ease .1s both' }}>
          {effectivePlanMode === null ? (
            <>
              <button
                type="button"
                style={{ ...styles.button, opacity: planAssistantAvailable ? 1 : 0.55 }}
                disabled={!planAssistantAvailable}
                onClick={() => planAssistantAvailable && setPlanSelectionMode('help')}
              >
                Quero ajuda para escolher meu plano
              </button>
              {!planAssistantAvailable ? (
                <p style={{ ...styles.hint, marginTop: '8px', textAlign: 'center' }}>
                  Para usar o assistente, informe um e-mail valido (sem pular) e confirme que este numero tem
                  WhatsApp. Caso contrario, escolha o plano na lista abaixo.
                </p>
              ) : null}
              <button type="button" style={styles.secondaryButton} onClick={() => setPlanSelectionMode('alone')}>
                Prefiro escolher sozinho
              </button>
            </>
          ) : null}

          {effectivePlanMode === 'help' ? (
            <>
              <div style={{ marginBottom: '18px' }}>
                <div style={styles.label}>Quantas pessoas moram na casa?</div>
                <div style={styles.choiceWrap}>
                  {PESSOAS_RANGE_OPTIONS.map((op) => (
                    <button
                      key={op.id}
                      type="button"
                      onClick={() => setAssistantAnswers((p) => ({ ...p, pessoasRange: op.id }))}
                      style={{
                        ...styles.choiceButton,
                        ...(assistantAnswers.pessoasRange === op.id ? styles.choiceButtonActive : {})
                      }}
                    >
                      {op.label}
                    </button>
                  ))}
                </div>
              </div>

              <div style={{ marginBottom: '18px' }}>
                <div style={styles.label}>Uso principal da internet</div>
                <div style={styles.choiceWrap}>
                  {USO_OPTIONS.map((op) => (
                    <button
                      key={op.id}
                      type="button"
                      onClick={() => setAssistantAnswers((p) => ({ ...p, uso: op.id }))}
                      style={{
                        ...styles.choiceButton,
                        ...(assistantAnswers.uso === op.id ? styles.choiceButtonActive : {})
                      }}
                    >
                      {op.label}
                    </button>
                  ))}
                </div>
              </div>

              {assistantAnswers.pessoasRange && assistantAnswers.uso ? (
                <div style={{ marginBottom: '18px' }}>
                  <div style={styles.label}>Qual beneficio voce prefere no plano?</div>
                  <div style={styles.choiceWrap}>
                    <button
                      type="button"
                      onClick={() => setAssistantAnswers((p) => ({ ...p, beneficio: 'TANTO_FAZ' }))}
                      style={{
                        ...styles.choiceButton,
                        ...(assistantAnswers.beneficio === 'TANTO_FAZ' ? styles.choiceButtonActive : {})
                      }}
                    >
                      Tanto faz
                    </button>
                    {benefitOptions.map((b) => (
                      <button
                        key={b.slug}
                        type="button"
                        onClick={() => setAssistantAnswers((p) => ({ ...p, beneficio: b.slug }))}
                        style={{
                          ...styles.choiceButton,
                          ...(assistantAnswers.beneficio === b.slug ? styles.choiceButtonActive : {})
                        }}
                      >
                        {b.label}
                      </button>
                    ))}
                  </div>
                  {benefitOptions.length === 0 ? (
                    <p style={styles.hint}>Nao ha beneficio premium para desempatar nos candidatos atuais.</p>
                  ) : null}
                </div>
              ) : null}

              {planRecLoading ? <p style={styles.hint}>Calculando melhor plano...</p> : null}
              {planRecError ? <p style={styles.warn}>{planRecError}</p> : null}

              {assistantReady ? (
                <div style={{ ...styles.info, border: '1.5px solid var(--primary)', borderRadius: 'var(--radius-sm)', padding: '14px', background: 'var(--primary-light)' }}>
                  <strong>Sugestao do assistente:</strong> {suggestedPlan.nome_produto} ({formatPlanPrice(suggestedPlan.vlr_final)}).
                </div>
              ) : null}

              <button
                type="button"
                className={assistantReady ? 'btn-ready-pulse' : undefined}
                style={{ ...styles.button, opacity: assistantReady ? 1 : 0.6 }}
                onClick={() => assistantReady && setField('plano', String(suggestedPlan.codcrmproduto))}
              >
                Usar sugestao do assistente
              </button>
              <button type="button" style={styles.secondaryButton} onClick={() => setPlanSelectionMode('alone')}>
                Ver todos os planos
              </button>
            </>
          ) : null}

          {effectivePlanMode === 'alone' ? (
            <>
              {plansLoading ? <p style={styles.hint}>Carregando planos...</p> : null}
              {plansError ? <p style={styles.warn}>{plansError}</p> : null}
              {plansCatalog.map((plano) => {
                const selected = formData.plano === String(plano.codcrmproduto);
                return (
                  <button
                    key={plano.codcrmproduto}
                    type="button"
                    onClick={() => setField('plano', String(plano.codcrmproduto))}
                    style={{
                      ...styles.secondaryButton,
                      ...(selected ? { borderColor: 'var(--primary)', background: 'var(--primary-light)', color: 'var(--primary-dark)' } : {}),
                      textAlign: 'left'
                    }}
                  >
                    {plano.nome_produto} - {formatPlanPrice(plano.vlr_final)}
                  </button>
                );
              })}
              {!plansLoading && !plansError && plansCatalog.length === 0 ? (
                <p style={styles.warn}>Nenhum plano disponivel no momento.</p>
              ) : null}
              <button
                type="button"
                style={{ ...styles.secondaryButton, opacity: planAssistantAvailable ? 1 : 0.55 }}
                disabled={!planAssistantAvailable}
                onClick={() => planAssistantAvailable && setPlanSelectionMode('help')}
              >
                Quero ajuda do assistente
              </button>
              {!planAssistantAvailable ? (
                <p style={{ ...styles.hint, marginTop: '8px', textAlign: 'center' }}>
                  Assistente indisponivel sem e-mail informado e WhatsApp neste numero.
                </p>
              ) : null}
            </>
          ) : null}

          <button type="button" style={styles.secondaryButton} onClick={() => setCurrentStep(2)}>
            Voltar para endereco
          </button>

          <button type="button" className={planOk ? 'btn-ready-pulse' : undefined} style={{ ...styles.button, opacity: planOk ? 1 : 0.6 }} onClick={goToDocument}>
            Enviar documento
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
          </button>
        </section>
      )}

      {((currentStep === documentStep && !hasPlanStep) || currentStep === documentStep) && (
        <section className="sonik-card" style={{ ...styles.card, ...styles.revealBlock, animation: 'fadeUp .4s ease .1s both' }}>
          <p style={styles.hint}>Pode ser conta de agua, energia, telefone ou internet no seu nome.</p>
          <p style={styles.info}>Seu comprovante fica protegido e e usado apenas para validar o endereco da instalacao.</p>
          <input
            ref={fileInputRef}
            type="file"
            accept="image/*,.pdf"
            onChange={handleFile}
            style={{ display: 'none' }}
          />
          <div
            style={{
              ...styles.uploadZone,
              borderColor: isDragOver ? 'var(--primary)' : 'var(--border)',
              background: isDragOver ? 'var(--primary-light)' : 'var(--input-bg)'
            }}
            onClick={() => fileInputRef.current?.click()}
            onDragOver={(e) => {
              e.preventDefault();
              setIsDragOver(true);
            }}
            onDragLeave={(e) => {
              e.preventDefault();
              setIsDragOver(false);
            }}
            onDrop={handleDropFile}
          >
            <button type="button" style={{ ...styles.secondaryButton, marginTop: 0 }}>
              Escolher arquivo
            </button>
            <p style={styles.info}>ou arraste o arquivo para esta area</p>
            <p style={styles.hint}>Formatos aceitos: imagem ou PDF</p>
            {formData.cadAddressProof?.name ? (
              <p style={styles.good}>Arquivo selecionado: {formData.cadAddressProof.name}</p>
            ) : null}
          </div>
          {formData.cadAddressProof ? (
            proofPreviewUrl ? (
              <div style={{ marginTop: '12px' }}>
                <img
                  src={proofPreviewUrl}
                  alt="Previa do comprovante"
                  style={{
                    width: '100%',
                    maxHeight: '320px',
                    objectFit: 'contain',
                    borderRadius: 'var(--radius-sm)',
                    border: '1.5px solid var(--border)',
                    background: '#fff'
                  }}
                />
                <p style={styles.hint}>Confira se o documento esta legivel antes de continuar.</p>
              </div>
            ) : (
              <div style={{
                marginTop: '12px',
                padding: '14px',
                borderRadius: 'var(--radius-sm)',
                border: '1.5px solid var(--border)',
                background: 'var(--input-bg)',
                display: 'flex',
                alignItems: 'center',
                gap: '10px'
              }}>
                <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ color: 'var(--primary)' }}>
                  <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
                  <polyline points="14 2 14 8 20 8"/>
                </svg>
                <div style={{ minWidth: 0, flex: 1 }}>
                  <div style={{ fontWeight: 600, color: 'var(--text)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                    {formData.cadAddressProof.name}
                  </div>
                  <div style={styles.hint}>PDF carregado.</div>
                </div>
              </div>
            )
          ) : null}
          {!documentOk ? <p style={styles.error}>Selecione um arquivo para continuar.</p> : null}

          {addrVerifying && formData.cadAddressProof && (
            <p style={{ ...styles.hint, marginTop: '8px', color: 'var(--primary)' }}>
              Verificando comprovante...
            </p>
          )}
          {addrVerified && !addrVerifying && formData.cadAddressProof && formData.cadAddressProof.type && formData.cadAddressProof.type.startsWith('image/') && (
            <p style={{ ...styles.good, marginTop: '8px' }}>
              Comprovante verificado! Endereço confere.
            </p>
          )}
          {addrVerifyMsg && !addrVerifying && (
            <div style={{
              marginTop: '8px',
              padding: '12px',
              borderRadius: 'var(--radius-sm)',
              border: '1.5px solid #fca5a5',
              background: '#fef2f2',
              color: '#991b1b',
              fontSize: '0.88rem',
              lineHeight: 1.45
            }}>
              {addrVerifyMsg}
            </div>
          )}

          <button
            type="button"
            className={documentOk && (addrVerified || !formData.cadAddressProof?.type?.startsWith('image/')) ? 'btn-ready-pulse' : undefined}
            onClick={goToReview}
            style={{ ...styles.button, opacity: documentOk && (addrVerified || !formData.cadAddressProof?.type?.startsWith('image/')) ? 1 : 0.6 }}
          >
            Revisar cadastro
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>
          </button>
        </section>
      )}

      {currentStep === reviewStep && (
        <section className="sonik-card" style={{ ...styles.card, ...styles.revealBlock, animation: 'fadeUp .4s ease .1s both' }}>
          <p style={styles.hint}>Confira com calma. Se quiser, volte e edite qualquer parte antes de confirmar.</p>

          <div style={{ ...styles.info, border: '1.5px solid var(--border)', borderRadius: 'var(--radius-sm)', padding: '14px', background: 'var(--input-bg)' }}>
            <strong>Identificacao</strong>
            <div>CPF: {formData.cadDoc}</div>
            <div>Nome: {formData.cadNome}</div>
            <div>Nascimento: {formData.cadNascimento}</div>
            <div>E-mail: {formData.cadEmail}</div>
            <div>Telefone: {formData.cadFone}</div>
            <button type="button" style={styles.secondaryButton} onClick={() => setCurrentStep(1)}>
              Editar identificacao
            </button>
          </div>

          <div style={{ ...styles.info, border: '1.5px solid var(--border)', borderRadius: 'var(--radius-sm)', padding: '14px', marginTop: '10px', background: 'var(--input-bg)' }}>
            <strong>Endereco</strong>
            <div>CEP: {formData.cadCEP}</div>
            <div>
              {formData.cadLogradouro}, {formData.cadNumero}
            </div>
            <div>Tipo de local: {formData.cadLocalTipo || 'Nao informado'}</div>
            {formData.cadLocalTipo === 'predio' ? <div>Apartamento: {formData.cadApartamento || 'Nao informado'}</div> : null}
            <div>
              {formData.cadBairro} - {formData.cadCidade}/{formData.cadUF}
            </div>
            <button type="button" style={styles.secondaryButton} onClick={() => setCurrentStep(2)}>
              Editar endereco
            </button>
          </div>

          {hasPlanStep ? (
            <div style={{ ...styles.info, border: '1.5px solid var(--border)', borderRadius: 'var(--radius-sm)', padding: '14px', marginTop: '10px', background: 'var(--input-bg)' }}>
              <strong>Plano escolhido</strong>
              <div>
                {plansCatalog.find((p) => String(p.codcrmproduto) === String(formData.plano))?.nome_produto || 'Nenhum plano selecionado'}
              </div>
              <button type="button" style={styles.secondaryButton} onClick={() => setCurrentStep(planStep)}>
                Editar plano
              </button>
            </div>
          ) : null}

          <div style={{ ...styles.info, border: '1.5px solid var(--border)', borderRadius: 'var(--radius-sm)', padding: '14px', marginTop: '10px', background: 'var(--input-bg)' }}>
            <strong>Comprovante</strong>
            <div>{formData.cadAddressProof?.name || 'Arquivo nao selecionado'}</div>
            <button type="button" style={styles.secondaryButton} onClick={() => setCurrentStep(documentStep)}>
              Editar comprovante
            </button>
          </div>

          <button
            type="button"
            className={documentOk && (addrVerified || !formData.cadAddressProof?.type?.startsWith('image/')) && !isSubmitting ? 'btn-ready-pulse' : undefined}
            onClick={submitForm}
            style={{ ...styles.button, opacity: documentOk && (addrVerified || !formData.cadAddressProof?.type?.startsWith('image/')) && !isSubmitting ? 1 : 0.6 }}
          >
            {isSubmitting ? 'Confirmando...' : 'Confirmar cadastro'}
          </button>

          {submitError ? <p style={{ ...styles.warn, marginTop: '10px' }}>{submitError}</p> : null}

          {submitted ? <p style={styles.good}>Cadastro confirmado com sucesso. Obrigado!</p> : null}
        </section>
      )}
        </div>
      </div>
    </>
  );
}

if (typeof window !== 'undefined') {
  window.CadastroForm = CadastroForm;
}
