// Calendar + slot picker
const { useState, useMemo, useEffect } = React;

function apiBase() {
  if (typeof window !== 'undefined' && window.NEXO_AVAILABLE_DATES_API_BASE != null) {
    return String(window.NEXO_AVAILABLE_DATES_API_BASE).replace(/\/$/, '');
  }
  return '';
}

function Calendar({ selectedDate, onSelectDate, selectedAvailable }) {
  const today = useMemo(() => {
    const d = new Date(); d.setHours(0,0,0,0); return d;
  }, []);

  const [viewMonth, setViewMonth] = useState(() => new Date(today.getFullYear(), today.getMonth(), 1));
  const mockAvailability = useMemo(() => buildAvailability(), []);
  const [apiAvailable, setApiAvailable] = useState(undefined);
  const [apiError, setApiError] = useState(false);

  useEffect(() => {
    const base = apiBase();
    const url = `${base || ''}/api/available-dates?month=${viewMonth.getMonth() + 1}&year=${viewMonth.getFullYear()}`;
    let cancelled = false;
    setApiError(false);
    fetch(url, { credentials: 'same-origin' })
      .then((r) => {
        if (!r.ok) throw new Error(String(r.status));
        return r.json();
      })
      .then((data) => {
        if (cancelled || !data || !Array.isArray(data.available)) return;
        setApiAvailable(new Set(data.available));
      })
      .catch(() => {
        if (cancelled) return;
        setApiAvailable(null);
        setApiError(true);
      });
    return () => { cancelled = true; };
  }, [viewMonth]);

  const availability = useMemo(() => {
    if (apiAvailable instanceof Set) {
      return {
        isAvailable: (date) => apiAvailable.has(dateKey(date)),
        slotsForDate: () => [],
      };
    }
    return mockAvailability;
  }, [apiAvailable, mockAvailability]);

  const maxMonth = new Date(today.getFullYear(), today.getMonth() + 3, 1);
  const minMonth = new Date(today.getFullYear(), today.getMonth(), 1);

  const canPrev = viewMonth > minMonth;
  const canNext = viewMonth < maxMonth;

  const monthGrid = useMemo(() => {
    const firstOfMonth = new Date(viewMonth.getFullYear(), viewMonth.getMonth(), 1);
    const startDow = (firstOfMonth.getDay() + 6) % 7; // Monday-first (0=Mon)
    const daysInMonth = new Date(viewMonth.getFullYear(), viewMonth.getMonth() + 1, 0).getDate();
    const cells = [];
    for (let i = 0; i < startDow; i++) cells.push(null);
    for (let d = 1; d <= daysInMonth; d++) {
      cells.push(new Date(viewMonth.getFullYear(), viewMonth.getMonth(), d));
    }
    // pad to multiple of 7
    while (cells.length % 7 !== 0) cells.push(null);
    return cells;
  }, [viewMonth]);

  const selectedKey = selectedDate ? dateKey(selectedDate) : null;
  const todayKey = dateKey(today);

  return (
    <div className="calendar">
      <div className="cal-head">
        <div className="cal-title">
          {MONTH_NAMES[viewMonth.getMonth()]} {viewMonth.getFullYear()}
        </div>
        <div className="cal-nav">
          <button
            type="button"
            disabled={!canPrev}
            onClick={() => setViewMonth(new Date(viewMonth.getFullYear(), viewMonth.getMonth() - 1, 1))}
            aria-label="Mes anterior"
          >‹</button>
          <button
            type="button"
            disabled={!canNext}
            onClick={() => setViewMonth(new Date(viewMonth.getFullYear(), viewMonth.getMonth() + 1, 1))}
            aria-label="Mes siguiente"
          >›</button>
        </div>
      </div>
      <div className="cal-grid">
        {DOW_SHORT.map((d, i) => (
          <div key={'dow-'+i} className="cal-dow">{d}</div>
        ))}
        {monthGrid.map((d, idx) => {
          if (!d) return <div key={'e-'+idx} className="cal-cell empty"></div>;
          const available = availability.isAvailable(d);
          const isSelected = selectedKey === dateKey(d);
          const isToday = todayKey === dateKey(d);
          return (
            <button
              key={dateKey(d)}
              type="button"
              className={
                'cal-cell ' +
                (available ? 'available ' : 'disabled ') +
                (isSelected ? 'selected ' : '') +
                (isToday ? 'today ' : '')
              }
              onClick={() => onSelectDate(d, available)}
            >
              {d.getDate()}
              {available && !isSelected && <span className="dot"></span>}
            </button>
          );
        })}
      </div>
      <div className="cal-legend">
        <span className={selectedDate && selectedAvailable ? 'is-active' : ''}><i></i>Disponible</span>
        <span className={selectedDate && !selectedAvailable ? 'is-active is-unavail' : ''}><i className="unavail"></i>No disponible</span>
      </div>
      {apiError && (
        <div className="cal-api-hint" style={{ marginTop: 10, fontSize: 11, color: 'var(--gray-muted)' }}>
          No se pudo cargar la agenda en vivo; mostrando disponibilidad de ejemplo.
        </div>
      )}
    </div>
  );
}

function SlotsPanel({ selectedDate, selectedTime, onSelectTime }) {
  const availability = useMemo(() => buildAvailability(), []);
  const slots = selectedDate ? availability.slotsForDate(selectedDate) : [];

  if (!selectedDate) {
    return (
      <div className="slots-panel">
        <div className="slots-head">Horarios disponibles</div>
        <div className="slots-date">Selecciona una fecha primero</div>
        <div className="slots-empty">
          Las visitas se agendan en bloques de <br /><strong style={{color: 'var(--teal)'}}>1 hora</strong>, de lunes a viernes.
        </div>
      </div>
    );
  }

  return (
    <div className="slots-panel">
      <div className="slots-head">Horarios disponibles</div>
      <div className="slots-date">{fmtDateLong(selectedDate)}</div>
      <div className="slots-grid">
        {slots.map(s => (
          <button
            key={s.time}
            type="button"
            className={'slot ' + (selectedTime === s.time ? 'selected' : '')}
            disabled={!s.available}
            onClick={() => onSelectTime(s.time)}
          >
            {s.time}
          </button>
        ))}
      </div>
    </div>
  );
}

window.Calendar = Calendar;
window.SlotsPanel = SlotsPanel;
