const { useState, useEffect, useRef } = React;

const SERVER_URL = 'https://plankton-app-ror7o.ondigitalocean.app';
const MONTHS    = ['January','February','March','April','May','June','July','August','September','October','November','December'];
const DAYS_S    = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
const DAYS_L    = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];

function minToStr(m) {
  const h = Math.floor(m / 60), mn = m % 60, ap = h >= 12 ? 'PM' : 'AM';
  const h12 = h > 12 ? h - 12 : h === 0 ? 12 : h;
  return `${h12}:${mn === 0 ? '00' : mn} ${ap}`;
}

function fmtDate(d) {
  return `${DAYS_L[d.getDay()]}, ${MONTHS[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`;
}

function genSlots(date) {
  const LAST = 18 * 60 - 60 - 30; // WORK_END - DUR - BUFFER
  const now = new Date();
  let todayMin = -1;
  if (date.toDateString() === now.toDateString())
    todayMin = now.getHours() * 60 + now.getMinutes() + 60;
  const slots = [];
  for (let t = 8 * 60; t <= LAST; t += 30)
    if (todayMin < 0 || t >= todayMin) slots.push(minToStr(t));
  return slots;
}

/* ─── Calendar ─── */
function Calendar({ selected, onSelect, calView, onPrev, onNext }) {
  const today = new Date(); today.setHours(0, 0, 0, 0);
  const y = calView.getFullYear(), m = calView.getMonth();
  const cells = Array(new Date(y, m, 1).getDay()).fill(null);
  for (let d = 1; d <= new Date(y, m + 1, 0).getDate(); d++) cells.push(new Date(y, m, d));

  return (
    <div className="r-cal">
      <div className="r-cal-hdr">
        <button className="r-cal-nav" onClick={onPrev}>&#8249;</button>
        <span className="r-cal-month">{MONTHS[m]} {y}</span>
        <button className="r-cal-nav" onClick={onNext}>&#8250;</button>
      </div>
      <div className="r-cal-dow">{DAYS_S.map(d => <span key={d}>{d}</span>)}</div>
      <div className="r-cal-grid">
        {cells.map((d, i) => {
          if (!d) return <div key={i} className="r-cal-day empty" />;
          const off = d < today || d.getDay() === 0;
          const sel = selected && d.toDateString() === selected.toDateString();
          return (
            <button key={i} disabled={off}
              className={`r-cal-day${off ? ' off' : ''}${sel ? ' sel' : ''}`}
              onClick={() => onSelect(d)}>
              {d.getDate()}
            </button>
          );
        })}
      </div>
    </div>
  );
}

/* ─── Address Autocomplete ─── */
function AddressInput({ value, onChange, hasError }) {
  const [items, setItems] = useState([]);
  const [open, setOpen]   = useState(false);
  const timer = useRef(null);
  const raf   = useRef(null);
  const ref   = useRef(null);

  useEffect(() => {
    const el = ref.current; if (!el) return;
    const book = document.getElementById('book');
    const reset = () => {
      if (book && book.scrollLeft) book.scrollLeft = 0;
      document.documentElement.scrollLeft = 0;
      document.body.scrollLeft = 0;
    };
    const loop = () => { reset(); raf.current = requestAnimationFrame(loop); };
    const onF = () => { raf.current = requestAnimationFrame(loop); };
    const onB = () => {
      cancelAnimationFrame(raf.current);
      const end = Date.now() + 600;
      (function flush() { reset(); if (Date.now() < end) requestAnimationFrame(flush); })();
    };
    el.addEventListener('focus', onF);
    el.addEventListener('blur', onB);
    return () => { el.removeEventListener('focus', onF); el.removeEventListener('blur', onB); cancelAnimationFrame(raf.current); };
  }, []);

  const search = q => {
    clearTimeout(timer.current);
    if (!q || q.length < 3) { setItems([]); setOpen(false); return; }
    timer.current = setTimeout(async () => {
      try {
        const houseMatch = q.match(/^(\d+)\s+(.+)/);
        const houseNum = houseMatch ? houseMatch[1] : null;
        const apiQuery = houseMatch ? houseMatch[2] : q;
        const res = await fetch(
          `https://photon.komoot.io/api/?q=${encodeURIComponent(apiQuery)}&limit=8&lang=en` +
          `&lat=44.8113&lon=-91.4985&location_bias_scale=0.8` +
          `&bbox=-96.0,41.5,-86.5,48.0`
        );
        const data = await res.json();
        const seen = new Set();
        const list = (data.features || []).map(f => {
          const p = f.properties;
          const streetName = p.street || p.name;
          const num = p.housenumber || houseNum;
          const street = num && streetName ? `${num} ${streetName}` : streetName;
          return [street, p.city || p.town, p.state].filter(Boolean).join(', ');
        }).filter(s => {
          if (!s || seen.has(s)) return false;
          seen.add(s); return true;
        });
        setItems(list); setOpen(list.length > 0);
      } catch {}
    }, 300);
  };

  return (
    <div className="r-addr-wrap">
      <input ref={ref} type="text" value={value} autoComplete="off"
        placeholder="123 Main St, Eau Claire, WI"
        className={hasError ? 'err' : ''}
        onChange={e => { onChange(e.target.value); search(e.target.value); }}
        onBlur={() => setTimeout(() => setOpen(false), 200)} />
      {open && (
        <div className="r-addr-drop">
          {items.map((s, i) => (
            <div key={i} className="r-addr-item"
              onMouseDown={e => { e.preventDefault(); onChange(s); setItems([]); setOpen(false); }}>
              {s}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

/* ─── Step indicator ─── */
function Steps({ step, onGo }) {
  return (
    <div className="r-steps">
      {['Date', 'Time', 'Details'].map((lbl, i) => (
        <React.Fragment key={i}>
          <div className={`r-step${step === i+1 ? ' active' : step > i+1 ? ' done' : ''}`}
            style={{ cursor: step > i+1 ? 'pointer' : 'default' }}
            onClick={() => step > i+1 && onGo(i+1)}>
            <div className="r-step-num">{step > i+1 ? '✓' : i+1}</div>
            <span className="r-step-lbl">{lbl}</span>
          </div>
          {i < 2 && <div className={`r-step-line${step > i+1 ? ' done' : ''}`} />}
        </React.Fragment>
      ))}
    </div>
  );
}

/* ─── Main App ─── */
function BookingApp() {
  const [step, setStep]         = useState(1);
  const [date, setDate]         = useState(null);
  const [time, setTime]         = useState(null);
  const [calView, setCalView]   = useState(() => { const d = new Date(); d.setDate(1); return d; });
  const [slots, setSlots]       = useState([]);
  const [blocked, setBlocked]   = useState([]);
  const [loading, setLoading]   = useState(false);
  const [form, setForm]         = useState({ fn:'', ln:'', email:'', phone:'', address:'', notes:'', sms:false });
  const [errs, setErrs]         = useState({});
  const [submitting, setSub]    = useState(false);
  const [apiErr, setApiErr]     = useState('');
  const [done, setDone]         = useState(null);

  useEffect(() => {
    if (!date) return;
    setSlots(genSlots(date)); setBlocked([]); setLoading(true);
    fetch(`${SERVER_URL}/api/booked-slots?date=${encodeURIComponent(fmtDate(date))}&duration=60`)
      .then(r => r.json())
      .then(d => setBlocked(d.booked || []))
      .catch(() => {})
      .finally(() => setLoading(false));
  }, [date]);

  const setF = (k, v) => {
    setForm(f => ({ ...f, [k]: v }));
    setErrs(e => { const n = { ...e }; delete n[k]; return n; });
  };

  const validate = () => {
    const e = {};
    if (!form.fn.trim())    e.fn    = 'Required';
    if (!form.ln.trim())    e.ln    = 'Required';
    if (!form.email.trim() || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) e.email = 'Valid email required';
    if (!form.phone.trim()) e.phone = 'Required';
    if (!form.address.trim()) e.address = 'Required';
    setErrs(e);
    return !Object.keys(e).length;
  };

  const submit = async () => {
    if (!validate()) return;
    setSub(true); setApiErr('');
    try {
      const res  = await fetch(`${SERVER_URL}/api/book`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          service_name:     'Headlight Restoration',
          appointment_date: fmtDate(date),
          appointment_time: time,
          duration_min:     60,
          customer_name:    `${form.fn.trim()} ${form.ln.trim()}`,
          customer_email:   form.email.trim(),
          customer_phone:   form.phone.trim(),
          customer_address: form.address.trim(),
          notes:            form.notes.trim() || 'None',
          sms_consent:      form.sms ? 'Yes' : 'No',
        }),
      });
      const data = await res.json();
      if (!res.ok) { setApiErr(data.error || 'That slot is no longer available. Please choose another time.'); setSub(false); return; }
      setDone({ email: form.email, date: fmtDate(date), time, address: form.address });
      setStep(4);
    } catch { setApiErr('Connection error. Please try again or email me at info@3sixtyrestore.com.'); }
    setSub(false);
  };

  const reset = () => {
    setStep(1); setDate(null); setTime(null);
    setForm({ fn:'', ln:'', email:'', phone:'', address:'', notes:'', sms:false });
    setErrs({}); setApiErr(''); setDone(null);
  };

  /* ── Success ── */
  if (step === 4 && done) return (
    <div className="r-success">
      <div className="r-success-icon">&#10003;</div>
      <h2 className="r-success-title">You're Booked!</h2>
      <p className="r-msg">Confirmation sent to <strong>{done.email}</strong></p>
      <p className="r-hint">Don't see it? Check <strong>Junk / Spam</strong> and add <strong>info@3sixtyrestore.com</strong> to your contacts.</p>
      <div className="r-summary">
        {[['Service','Headlight Restoration'],['Date',done.date],['Time',done.time],['Address',done.address],['Price','$125 flat rate']].map(([k,v]) => (
          <div key={k} className="r-summary-row">
            <span>{k}</span>
            <span style={k==='Price'?{color:'var(--accent)'}:{}}>{v}</span>
          </div>
        ))}
      </div>
      <button className="r-btn-primary" style={{maxWidth:300}} onClick={reset}>Book Another Appointment</button>
    </div>
  );

  const calPrev = () => { const v=new Date(calView); v.setMonth(v.getMonth()-1); setCalView(v); };
  const calNext = () => { const v=new Date(calView); v.setMonth(v.getMonth()+1); setCalView(v); };

  return (
    <div className="r-booking">
      <Steps step={step} onGo={setStep} />

      {/* Step 1 — Date */}
      {step === 1 && (
        <div className="r-panel">
          <div className="r-panel-title">Choose a Date</div>
          <Calendar selected={date} onSelect={d => { setDate(d); setTime(null); }}
            calView={calView} onPrev={calPrev} onNext={calNext} />
          <button className="r-btn-primary" disabled={!date} onClick={() => setStep(2)}>Next &rarr;</button>
        </div>
      )}

      {/* Step 2 — Time */}
      {step === 2 && (
        <div className="r-panel">
          <div className="r-panel-title">Pick a Time</div>
          {date && <p className="r-panel-sub">{fmtDate(date)}</p>}
          {loading
            ? <div className="r-loading">Checking availability&hellip;</div>
            : slots.length === 0
              ? <p className="r-no-slots">No available times for this date.</p>
              : <div className="r-slots">
                  {slots.map(s => (
                    <button key={s}
                      className={`r-slot${blocked.includes(s)?' taken':''}${time===s?' sel':''}`}
                      disabled={blocked.includes(s)}
                      onClick={() => setTime(s)}>
                      {s}
                    </button>
                  ))}
                </div>
          }
          <div className="r-nav">
            <button className="r-btn-ghost" onClick={() => setStep(1)}>&larr; Back</button>
            <button className="r-btn-primary" disabled={!time} onClick={() => setStep(3)}>Next &rarr;</button>
          </div>
        </div>
      )}

      {/* Step 3 — Details */}
      {step === 3 && (
        <div className="r-panel">
          <div className="r-panel-title">Your Details</div>
          <div className="r-row-2">
            <div className="r-fg">
              <label>First Name *</label>
              <input value={form.fn} onChange={e=>setF('fn',e.target.value)} placeholder="John" className={errs.fn?'err':''} />
              {errs.fn && <span className="r-err">{errs.fn}</span>}
            </div>
            <div className="r-fg">
              <label>Last Name *</label>
              <input value={form.ln} onChange={e=>setF('ln',e.target.value)} placeholder="Smith" className={errs.ln?'err':''} />
              {errs.ln && <span className="r-err">{errs.ln}</span>}
            </div>
          </div>
          <div className="r-fg">
            <label>Email *</label>
            <input type="email" value={form.email} onChange={e=>setF('email',e.target.value)}
              placeholder="you@email.com" className={errs.email?'err':''} />
            {errs.email && <span className="r-err">{errs.email}</span>}
          </div>
          <div className="r-fg">
            <label>Phone *</label>
            <input type="tel" value={form.phone} onChange={e=>setF('phone',e.target.value)}
              placeholder="(715) 555-0100" className={errs.phone?'err':''} />
            {errs.phone && <span className="r-err">{errs.phone}</span>}
          </div>
          <div className="r-fg">
            <label>Service Address *</label>
            <AddressInput value={form.address} onChange={v=>setF('address',v)} hasError={!!errs.address} />
            {errs.address && <span className="r-err">{errs.address}</span>}
          </div>
          <div className="r-fg">
            <label>Notes <span className="r-opt">(optional)</span></label>
            <textarea value={form.notes} onChange={e=>setF('notes',e.target.value)}
              placeholder="Anything I should know&hellip;" rows={3} />
          </div>
          <div className="r-check">
            <input type="checkbox" id="rSms" checked={form.sms} onChange={e=>setF('sms',e.target.checked)} />
            <label htmlFor="rSms">
              I agree to receive text messages about my appointment.
              <span className="r-check-note"> Standard rates may apply.</span>
            </label>
          </div>
          <div className="r-summary">
            {[['Service','Headlight Restoration'],['Date',fmtDate(date)],['Time',time],['Price','$125 flat rate']].map(([k,v]) => (
              <div key={k} className="r-summary-row">
                <span>{k}</span>
                <span style={k==='Price'?{color:'var(--accent)'}:{}}>{v}</span>
              </div>
            ))}
          </div>
          {apiErr && <div className="r-error-box">{apiErr}</div>}
          <div className="r-nav">
            <button className="r-btn-ghost" onClick={() => setStep(2)}>&larr; Back</button>
            <button className="r-btn-primary" disabled={submitting} onClick={submit}>
              {submitting ? 'Booking…' : 'Confirm Appointment →'}
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('booking-react-root')).render(<BookingApp />);
