// form-fields.jsx — Field, inputStyle, ProgressBar (2 steps),
// VeiculoAutocomplete, AnoSelect, DataCalendarPopup, HorarioSelect.

function Field({ label, required, error, children }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      <label style={{
        fontFamily: "'Roboto',sans-serif", fontSize: 12, fontWeight: 500,
        color: '#5B5B5B',
      }}>
        {label}{required && <span style={{ color: '#E31018' }}> *</span>}
      </label>
      {children}
      {error && (
        <span style={{ fontFamily: "'Roboto',sans-serif", fontSize: 11, color: '#E31018' }}>
          {error}
        </span>
      )}
    </div>
  );
}

const inputStyle = (err) => ({
  width: '100%', padding: '11px 14px', borderRadius: 8,
  border: `1px solid ${err ? '#E31018' : '#E0E0E0'}`,
  background: '#fff',
  fontFamily: "'Roboto',sans-serif", fontSize: 14, color: '#2D2D2D',
  outline: 'none', transition: 'border-color 150ms ease',
});

// ─── ProgressBar de 2 passos ───────────────────────────────────────────
function ProgressBar({ step }) {
  const labels = ['Seus dados', 'Veículo e horário'];
  const pct = step === 1 ? 0 : 100;
  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', position: 'relative', marginBottom: 22 }}>
      <div style={{ position: 'absolute', top: 14, left: 14, right: 14, height: 2, background: '#E0E0E0', zIndex: 0 }} />
      <div style={{
        position: 'absolute', top: 14, left: 14,
        width: `calc(${pct}% - 28px)`,
        height: 2, background: '#E31018', zIndex: 1,
        transition: 'width 320ms ease',
      }} />
      {labels.map((label, i) => {
        const n = i + 1;
        const done = step > n;
        const active = step === n;
        return (
          <div key={label} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8, zIndex: 2, flex: 1 }}>
            <div style={{
              width: 28, height: 28, borderRadius: '50%',
              background: done ? '#2D2D2D' : active ? '#E31018' : '#fff',
              border: !done && !active ? '2px solid #E0E0E0' : 'none',
              color: '#fff', fontSize: 13, fontWeight: 700,
              fontFamily: "'Roboto',sans-serif",
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              transition: 'all 280ms ease',
              boxShadow: active ? '0 0 0 4px rgba(227,16,24,0.15)' : 'none',
            }}>
              {done ? <Icon name="check" size={14} color="#fff" stroke={3} /> : <span style={{ color: active ? '#fff' : '#919191' }}>{n}</span>}
            </div>
            <span style={{
              fontFamily: "'Roboto',sans-serif", fontSize: 11,
              fontWeight: active || done ? 600 : 400,
              color: active || done ? '#2D2D2D' : '#919191', textAlign: 'center',
            }}>{label}</span>
          </div>
        );
      })}
    </div>
  );
}

// ─── Autocomplete de veículo (AbortController + text/descricao) ────────
function VeiculoAutocomplete({ valor, descricao, onSelect, onClear, error, ano }) {
  const [termo, setTermo] = React.useState(descricao || '');
  const [sugestoes, setSugestoes] = React.useState([]);
  const [open, setOpen] = React.useState(false);
  const [loading, setLoading] = React.useState(false);
  const [highlight, setHighlight] = React.useState(0);
  const timerRef = React.useRef(null);
  const abortRef = React.useRef(null);
  const boxRef = React.useRef(null);

  React.useEffect(() => { setTermo(descricao || ''); }, [descricao]);

  React.useEffect(() => {
    const onClick = (e) => { if (boxRef.current && !boxRef.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', onClick);
    return () => document.removeEventListener('mousedown', onClick);
  }, []);

  // Cancela qualquer busca pendente ao desmontar
  React.useEffect(() => () => {
    if (timerRef.current) clearTimeout(timerRef.current);
    if (abortRef.current) abortRef.current.abort();
  }, []);

  const buscar = (t) => {
    if (timerRef.current) clearTimeout(timerRef.current);
    if (abortRef.current) abortRef.current.abort();

    if (t.length < 2) { setSugestoes([]); setOpen(false); setLoading(false); return; }

    setLoading(true);
    timerRef.current = setTimeout(() => {
      const ctrl = new AbortController();
      abortRef.current = ctrl;
      window.api.buscarVeiculos(t, ano, ctrl.signal)
        .then(res => {
          if (ctrl.signal.aborted) return;
          setSugestoes(res);
          setOpen(true);
          setHighlight(0);
          setLoading(false);
        })
        .catch(err => {
          if (err && err.name === 'AbortError') return;
          setLoading(false);
        });
    }, 300);
  };

  const handleChange = (v) => {
    setTermo(v);
    if (valor) onClear && onClear();
    buscar(v);
  };

  const escolher = (item) => {
    setTermo(item.descricao);
    setOpen(false);
    onSelect(item);
  };

  const onKeyDown = (e) => {
    if (!open || sugestoes.length === 0) return;
    if (e.key === 'ArrowDown') { e.preventDefault(); setHighlight(h => Math.min(h + 1, sugestoes.length - 1)); }
    else if (e.key === 'ArrowUp') { e.preventDefault(); setHighlight(h => Math.max(h - 1, 0)); }
    else if (e.key === 'Enter') { e.preventDefault(); escolher(sugestoes[highlight]); }
    else if (e.key === 'Escape') { setOpen(false); }
  };

  return (
    <div ref={boxRef} style={{ position: 'relative' }}>
      <input type="hidden" name="VeiculoId" value={valor || ''} />
      <input
        value={termo}
        onChange={e => handleChange(e.target.value)}
        onFocus={() => { if (sugestoes.length > 0) setOpen(true); }}
        onKeyDown={onKeyDown}
        placeholder="Ex: Corolla, HB20, Onix..."
        style={inputStyle(error)}
        autoComplete="off"
      />
      {loading && (
        <div style={{
          position: 'absolute', right: 12, top: '50%', transform: 'translateY(-50%)',
          width: 14, height: 14, borderRadius: '50%',
          border: '2px solid #E0E0E0', borderTopColor: '#E31018',
          animation: 'spin 700ms linear infinite',
        }} />
      )}
      {valor && !loading && (
        <div style={{
          position: 'absolute', right: 12, top: '50%', transform: 'translateY(-50%)',
        }}>
          <Icon name="check" size={16} color="#0C7110" stroke={2.6} />
        </div>
      )}
      {open && sugestoes.length > 0 && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 4px)', left: 0, right: 0,
          background: '#fff', border: '1px solid #E0E0E0', borderRadius: 8,
          boxShadow: '0 8px 24px rgba(0,0,0,0.08)', zIndex: 50,
          maxHeight: 240, overflowY: 'auto',
        }}>
          {sugestoes.map((s, i) => (
            <div
              key={s.id}
              onMouseDown={(e) => { e.preventDefault(); escolher(s); }}
              onMouseEnter={() => setHighlight(i)}
              style={{
                padding: '10px 14px', cursor: 'pointer',
                background: i === highlight ? '#F9F9F9' : '#fff',
                fontFamily: "'Roboto',sans-serif", fontSize: 14, color: '#2D2D2D',
                borderBottom: i < sugestoes.length - 1 ? '1px solid #F4F4F4' : 'none',
              }}
            >{s.descricao}</div>
          ))}
        </div>
      )}
      {open && sugestoes.length === 0 && termo.length >= 2 && !loading && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 4px)', left: 0, right: 0,
          background: '#fff', border: '1px solid #E0E0E0', borderRadius: 8,
          padding: '12px 14px', fontFamily: "'Roboto',sans-serif", fontSize: 13,
          color: '#919191', zIndex: 50,
        }}>Nenhum veículo encontrado para "{termo}"</div>
      )}
    </div>
  );
}

// ─── AnoSelect ────────────────────────────────────────────────────────
function AnoSelect({ valor, onChange, error }) {
  const anoAtual = new Date().getFullYear();
  const anos = [];
  for (let y = anoAtual + 1; y >= 1980; y--) anos.push(y);
  return (
    <select name="AnoModelo" id="AnoModelo" value={valor} onChange={e => onChange(e.target.value)} style={inputStyle(error)}>
      <option value="">Selecione</option>
      {anos.map(y => <option key={y} value={y}>{y}</option>)}
    </select>
  );
}

// ─── Calendário popup ─────────────────────────────────────────────────
// Substitui input nativo. Domingos e datas passadas: desabilitados visualmente
// E não clicáveis (o handler retorna early antes de invocar onChange).
const NOMES_MESES = ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho',
                     'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'];
const DIAS_SEMANA_CURTO = ['D', 'S', 'T', 'Q', 'Q', 'S', 'S'];

function formatarDataISO(d) {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, '0');
  const dd = String(d.getDate()).padStart(2, '0');
  return `${y}-${m}-${dd}`;
}

function formatarDataBR(iso) {
  if (!iso) return '';
  const p = iso.split('-');
  return `${p[2]}/${p[1]}/${p[0]}`;
}

function formatarDataLonga(iso) {
  if (!iso) return '';
  const d = new Date(iso + 'T00:00');
  return d.toLocaleDateString('pt-BR', { weekday: 'long', day: '2-digit', month: 'long' });
}

function DataCalendarPopup({ valor, onChange, error }) {
  const hoje = React.useMemo(() => {
    const d = new Date(); d.setHours(0, 0, 0, 0); return d;
  }, []);
  const [open, setOpen] = React.useState(false);
  const [mesVisivel, setMesVisivel] = React.useState(() => {
    if (valor) {
      const p = valor.split('-');
      return new Date(Number(p[0]), Number(p[1]) - 1, 1);
    }
    return new Date(hoje.getFullYear(), hoje.getMonth(), 1);
  });
  const boxRef = React.useRef(null);

  React.useEffect(() => {
    const onClick = (e) => { if (boxRef.current && !boxRef.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', onClick);
    return () => document.removeEventListener('mousedown', onClick);
  }, []);

  // Constrói matriz do mês visível (com células vazias antes do dia 1)
  const celulas = React.useMemo(() => {
    const ano = mesVisivel.getFullYear();
    const mes = mesVisivel.getMonth();
    const primeiroDia = new Date(ano, mes, 1);
    const offset = primeiroDia.getDay(); // 0=Dom
    const diasNoMes = new Date(ano, mes + 1, 0).getDate();
    const out = [];
    for (let i = 0; i < offset; i++) out.push(null);
    for (let d = 1; d <= diasNoMes; d++) out.push(new Date(ano, mes, d));
    return out;
  }, [mesVisivel]);

  const podeNavegarParaAnterior = mesVisivel > new Date(hoje.getFullYear(), hoje.getMonth(), 1);

  const escolher = (d) => {
    if (!d) return;
    if (d.getDay() === 0) return;     // domingo
    if (d < hoje) return;             // passado
    onChange(formatarDataISO(d));
    setOpen(false);
  };

  return (
    <div ref={boxRef} style={{ position: 'relative' }}>
      <button
        type="button"
        onClick={() => setOpen(o => !o)}
        style={{
          ...inputStyle(error),
          textAlign: 'left', cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          color: valor ? '#2D2D2D' : '#919191',
        }}
      >
        <span>{valor ? `${formatarDataBR(valor)} · ${formatarDataLonga(valor)}` : 'Escolha uma data'}</span>
        <Icon name="calendar" size={16} color="#919191" stroke={2} />
      </button>

      {open && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 6px)', left: 0,
          width: 300, background: '#fff', borderRadius: 12,
          border: '1px solid #E0E0E0',
          boxShadow: '0 12px 32px rgba(0,0,0,0.12)',
          padding: 16, zIndex: 60,
        }}>
          <div style={{
            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
            marginBottom: 12,
          }}>
            <button
              type="button"
              disabled={!podeNavegarParaAnterior}
              onClick={() => setMesVisivel(m => new Date(m.getFullYear(), m.getMonth() - 1, 1))}
              style={{
                width: 28, height: 28, borderRadius: 6, background: 'none',
                border: '1px solid #E0E0E0',
                cursor: podeNavegarParaAnterior ? 'pointer' : 'not-allowed',
                opacity: podeNavegarParaAnterior ? 1 : 0.4,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}
            >
              <Icon name="arrowLeft" size={14} color="#5B5B5B" />
            </button>
            <div style={{
              fontFamily: "'Roboto',sans-serif", fontSize: 14, fontWeight: 500, color: '#2D2D2D',
            }}>
              {NOMES_MESES[mesVisivel.getMonth()]} {mesVisivel.getFullYear()}
            </div>
            <button
              type="button"
              onClick={() => setMesVisivel(m => new Date(m.getFullYear(), m.getMonth() + 1, 1))}
              style={{
                width: 28, height: 28, borderRadius: 6, background: 'none',
                border: '1px solid #E0E0E0', cursor: 'pointer',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}
            >
              <Icon name="arrowRight" size={14} color="#5B5B5B" />
            </button>
          </div>

          <div style={{
            display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 2,
            marginBottom: 4,
          }}>
            {DIAS_SEMANA_CURTO.map((d, i) => (
              <div key={i} style={{
                textAlign: 'center', fontFamily: "'Roboto',sans-serif",
                fontSize: 11, fontWeight: 500,
                color: i === 0 ? '#C0C0C0' : '#919191', padding: '6px 0',
              }}>{d}</div>
            ))}
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 2 }}>
            {celulas.map((d, i) => {
              if (!d) return <div key={`empty-${i}`} />;
              const iso = formatarDataISO(d);
              const isDomingo = d.getDay() === 0;
              const isPassado = d < hoje;
              const disabled = isDomingo || isPassado;
              const isHoje = +d === +hoje;
              const ativo = valor === iso;

              return (
                <button
                  key={iso}
                  type="button"
                  disabled={disabled}
                  onClick={() => escolher(d)}
                  aria-disabled={disabled}
                  title={isDomingo ? 'Domingo indisponível' : isPassado ? 'Data passada' : ''}
                  style={{
                    height: 34, borderRadius: 8, border: 'none',
                    background: ativo ? '#E31018' : isHoje && !ativo ? 'rgba(227,16,24,0.08)' : 'transparent',
                    color: disabled ? '#D0D0D0' : ativo ? '#fff' : isHoje ? '#E31018' : '#2D2D2D',
                    cursor: disabled ? 'not-allowed' : 'pointer',
                    fontFamily: "'Roboto',sans-serif", fontSize: 13,
                    fontWeight: ativo || isHoje ? 600 : 400,
                    textDecoration: isPassado ? 'line-through' : 'none',
                    transition: 'background 150ms ease',
                  }}
                  onMouseEnter={(e) => {
                    if (!disabled && !ativo) e.currentTarget.style.background = '#F4F4F4';
                  }}
                  onMouseLeave={(e) => {
                    if (!disabled && !ativo) e.currentTarget.style.background = isHoje ? 'rgba(227,16,24,0.08)' : 'transparent';
                  }}
                >{d.getDate()}</button>
              );
            })}
          </div>
          <div style={{
            marginTop: 12, paddingTop: 10, borderTop: '1px solid #F0F0F0',
            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
            fontFamily: "'Roboto',sans-serif", fontSize: 11, color: '#919191',
          }}>
            <span>Domingos indisponíveis</span>
            <button
              type="button"
              onClick={() => setOpen(false)}
              style={{
                background: 'none', border: 'none', color: '#5B5B5B',
                fontFamily: "'Roboto',sans-serif", fontSize: 12, cursor: 'pointer',
              }}
            >Fechar</button>
          </div>
        </div>
      )}
    </div>
  );
}

// ─── Select de horário (filtrado por horaAbertura/horaFechamento) ──────
// Lista base: 08:00 → 18:00 a cada 1h.
// Se a data selecionada for hoje, remove horários já passados.
function gerarHorarios(horaAbertura, horaFechamento, dataISO) {
  const base = [];
  for (let h = 8; h <= 18; h++) base.push(String(h).padStart(2, '0') + ':00');

  const [ah, am] = (horaAbertura || '08:00').split(':').map(Number);
  const [fh, fm] = (horaFechamento || '18:00').split(':').map(Number);
  const aMin = ah * 60 + am;
  const fMin = fh * 60 + fm;

  let filtrado = base.filter(h => {
    const [hh, mm] = h.split(':').map(Number);
    const total = hh * 60 + mm;
    return total >= aMin && total <= fMin;
  });

  // Se for hoje, remove horários passados
  if (dataISO) {
    const hojeISO = formatarDataISO(new Date());
    if (dataISO === hojeISO) {
      const agora = new Date();
      const agoraMin = agora.getHours() * 60 + agora.getMinutes();
      filtrado = filtrado.filter(h => {
        const [hh, mm] = h.split(':').map(Number);
        return hh * 60 + mm > agoraMin;
      });
    }
  }
  return filtrado;
}

function HorarioSelect({ data, valor, onChange, error, horaAbertura, horaFechamento }) {
  const horarios = React.useMemo(
    () => gerarHorarios(horaAbertura, horaFechamento, data),
    [horaAbertura, horaFechamento, data]
  );

  if (horarios.length === 0) {
    return (
      <div style={{
        ...inputStyle(error),
        color: '#919191', fontStyle: 'italic',
      }}>
        Não há horários disponíveis para essa data
      </div>
    );
  }

  return (
    <select name="DataVistoria" value={valor} onChange={e => onChange(e.target.value)} style={inputStyle(error)}>
      <option value="">Selecione um horário</option>
      {horarios.map(h => <option key={h} value={h}>{h}</option>)}
    </select>
  );
}

Object.assign(window, {
  Field, inputStyle, ProgressBar,
  VeiculoAutocomplete, AnoSelect, DataCalendarPopup, HorarioSelect,
  formatarDataISO, formatarDataBR, formatarDataLonga,
});
