const { useState: useStateB, useMemo, useEffect: useEffectB } = React;

// ---------- BOOKING ----------
const STEPS = ['Service', 'Date', 'Créneau', 'Vos infos'];

const bookingServices = [
  { id:'setup',   t:'Aménagement de poste',       d:'Bureau, écrans, câblage',            p:'Dès CHF 180', dur:'2–3h' },
  { id:'install', t:"Installation d'ordinateur",  d:'Windows ou macOS, apps, données',    p:'Dès CHF 140', dur:'1–2h' },
  { id:'support', t:'Support technique',           d:'Dépannage, Wi-Fi, imprimante',       p:'CHF 90/h',    dur:'≈ 1h' },
  { id:'conseil', t:'Conseil / upgrade',           d:'RAM, SSD, achat matériel',           p:'CHF 90/h',    dur:'≈ 1h' },
];

const SLOTS = ['09:00','10:30','13:00','14:30','16:00','17:30'];

const monthLabel = (d) => d.toLocaleDateString('fr-CH', { month:'long', year:'numeric' });
const sameDay    = (a,b) => a && b && a.toDateString() === b.toDateString();

function toIso(d) {
  return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;
}

const Booking = () => {
  const [step, setStep]       = useStateB(0);
  const [picked, setPicked]   = useStateB({ service:null, date:null, slot:null, mode:'place', name:'', email:'', phone:'', address:'', notes:'' });
  const [view, setView]       = useStateB(() => { const d = new Date(); return new Date(d.getFullYear(), d.getMonth(), 1); });
  const [confirmed, setConfirmed]       = useStateB(false);
  const [bookingResult, setBookingResult] = useStateB(null);
  const [availMap, setAvailMap]         = useStateB({});
  const [availLoading, setAvailLoading] = useStateB(false);
  const [submitLoading, setSubmitLoading] = useStateB(false);
  const [slotError, setSlotError]       = useStateB(null);

  // Fetch availability from API when the viewed month changes
  useEffectB(() => {
    const month = `${view.getFullYear()}-${String(view.getMonth()+1).padStart(2,'0')}`;
    setAvailLoading(true);
    fetch(`/api/availability?month=${month}`)
      .then(r => r.ok ? r.json() : null)
      .then(data => {
        if (!Array.isArray(data)) return;
        const map = {};
        for (const item of data) map[item.date] = item;
        setAvailMap(map);
      })
      .catch(() => {})
      .finally(() => setAvailLoading(false));
  }, [view]);

  // Build calendar grid (days array only — taken slots come from availMap)
  const days = useMemo(() => {
    const first = new Date(view.getFullYear(), view.getMonth(), 1);
    const last  = new Date(view.getFullYear(), view.getMonth()+1, 0);
    const start = (first.getDay() + 6) % 7; // monday-first
    const arr = [];
    for (let i=0; i<start; i++) arr.push(null);
    for (let d=1; d<=last.getDate(); d++) arr.push(new Date(view.getFullYear(), view.getMonth(), d));
    while (arr.length % 7 !== 0) arr.push(null);
    return arr;
  }, [view]);

  const today = new Date(); today.setHours(0,0,0,0);
  const isPast    = (d) => d && d < today;
  const isSunday  = (d) => d && d.getDay() === 0;

  const isAvailable = (d) => {
    if (!d || isPast(d) || isSunday(d)) return false;
    const info = availMap[toIso(d)];
    if (info) return info.available;
    return true; // optimistic while API data not yet loaded
  };

  const slotTaken = (s) => {
    if (!picked.date) return false;
    const info = availMap[toIso(picked.date)];
    if (!info) return false;
    return info.slots.find(sl => sl.time === s)?.taken ?? false;
  };

  const selService = bookingServices.find(s => s.id === picked.service);

  const next = () => setStep(s => Math.min(s+1, STEPS.length-1));
  const prev = () => setStep(s => Math.max(s-1, 0));

  const canNext = () => {
    if (step === 0) return !!picked.service;
    if (step === 1) return !!picked.date;
    if (step === 2) return !!picked.slot;
    return false;
  };

  const refreshAvail = (date) => {
    const month = `${date.getFullYear()}-${String(date.getMonth()+1).padStart(2,'0')}`;
    fetch(`/api/availability?month=${month}`)
      .then(r => r.ok ? r.json() : null)
      .then(data => {
        if (!Array.isArray(data)) return;
        const map = {};
        for (const item of data) map[item.date] = item;
        setAvailMap(map);
      })
      .catch(() => {});
  };

  const submit = async (e) => {
    e.preventDefault();
    if (!picked.name.trim() || !/^\S+@\S+\.\S+$/.test(picked.email)) return;

    setSubmitLoading(true);
    setSlotError(null);
    try {
      const res = await fetch('/api/bookings', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          service: picked.service,
          date:    toIso(picked.date),
          slot:    picked.slot,
          mode:    picked.mode,
          name:    picked.name,
          email:   picked.email,
          phone:   picked.phone   || undefined,
          address: picked.address || undefined,
          notes:   picked.notes   || undefined,
        }),
      });
      const data = await res.json();

      if (res.status === 409) {
        setSlotError("Désolé, ce créneau vient d'être pris. Veuillez en choisir un autre.");
        setPicked(p => ({ ...p, slot: null }));
        refreshAvail(picked.date);
        setStep(2);
        return;
      }

      if (data.ok) {
        setBookingResult(data);
        setConfirmed(true);
        window.__toast && window.__toast('Réservation enregistrée. Confirmation par e-mail.');
      } else {
        window.__toast && window.__toast("Erreur lors de la réservation. Réessayez ou appelez le 076 281 76 43.");
      }
    } catch {
      window.__toast && window.__toast('Erreur réseau. Réessayez ou appelez le 076 281 76 43.');
    } finally {
      setSubmitLoading(false);
    }
  };

  const reset = () => {
    setStep(0);
    setPicked({ service:null, date:null, slot:null, mode:'place', name:'', email:'', phone:'', address:'', notes:'' });
    setConfirmed(false);
    setBookingResult(null);
    setSlotError(null);
  };

  if (confirmed) {
    return (
      <section id="reserver" className="section-wash">
        <div className="container" style={{maxWidth:760}}>
          <div className="booking-shell" style={{padding:48,textAlign:'center'}}>
            <div style={{width:64,height:64,margin:'0 auto 18px',borderRadius:'50%',background:'var(--primary-soft)',color:'var(--primary-deep)',display:'inline-flex',alignItems:'center',justifyContent:'center'}}>
              <Icon name="check" size={28} stroke={2.4}/>
            </div>
            <h2 style={{fontSize:32}}>Rendez-vous confirmé</h2>
            <p style={{color:'var(--ink-2)',marginTop:14,fontSize:17,maxWidth:480,marginInline:'auto'}}>
              Un e-mail de confirmation vient d'être envoyé à <b>{picked.email}</b>. Je vous recontacte dans la matinée pour valider l'adresse exacte.
            </p>
            <div style={{margin:'28px auto 0',maxWidth:420,textAlign:'left',background:'var(--cream)',padding:20,borderRadius:'var(--r)'}}>
              <div className="summary-row" style={{borderTop:'none',paddingTop:0}}><span className="lbl">Service</span><span>{selService?.t}</span></div>
              <div className="summary-row"><span className="lbl">Date</span><span>{picked.date?.toLocaleDateString('fr-CH',{weekday:'long',day:'numeric',month:'long'})}</span></div>
              <div className="summary-row"><span className="lbl">Heure</span><span>{picked.slot}</span></div>
              <div className="summary-row"><span className="lbl">Lieu</span><span>{picked.mode==='place'?'À domicile':picked.mode==='remote'?'À distance':'Au bureau'}</span></div>
              {bookingResult?.confirmCode && (
                <div className="summary-row"><span className="lbl">Réf.</span><span className="mono" style={{fontSize:12}}>{bookingResult.confirmCode.slice(0,8).toUpperCase()}</span></div>
              )}
            </div>
            <button className="btn btn-ghost" onClick={reset} style={{marginTop:24}}>Réserver un autre créneau</button>
          </div>
        </div>
      </section>
    );
  }

  return (
    <section id="reserver" className="section-wash">
      <div className="container" style={{maxWidth:980}}>
        <div style={{display:'flex',alignItems:'end',justifyContent:'space-between',gap:24,flexWrap:'wrap',marginBottom:32}}>
          <div>
            <div className="eyebrow">Réservation</div>
            <h2 style={{marginTop:18}}>Choisissez un créneau,<br/>en moins d'une minute.</h2>
          </div>
          <div style={{color:'var(--muted)',fontSize:14,display:'flex',alignItems:'center',gap:8}}>
            <Icon name="clock" size={16}/> Créneaux du lundi au samedi · 09:00 → 18:30
          </div>
        </div>

        <div className="booking-shell">
          <div className="steps-bar">
            {STEPS.map((s,i)=>(
              <div key={s} className={`step ${i===step?'active':''} ${i<step?'done':''}`}>
                <span className="n">{i<step ? <Icon name="check" size={12} stroke={2.6}/> : i+1}</span>
                <span>{s}</span>
              </div>
            ))}
          </div>

          <div className="booking-body">
            {step === 0 && (
              <div>
                <h3 style={{fontSize:20,marginBottom:6}}>Quel type d'intervention ?</h3>
                <p style={{color:'var(--muted)',fontSize:14,marginBottom:20}}>Vous pourrez préciser votre besoin à l'étape suivante.</p>
                <div className="svc-pick">
                  {bookingServices.map(s => (
                    <button key={s.id} className={`svc-opt ${picked.service===s.id?'selected':''}`}
                      onClick={()=>setPicked(p=>({...p,service:s.id}))} type="button">
                      <div style={{display:'flex',alignItems:'center',justifyContent:'space-between'}}>
                        <span className="t">{s.t}</span>
                        <span className="chip" style={{background:'var(--cream)',color:'var(--ink-2)'}}>{s.dur}</span>
                      </div>
                      <div className="d">{s.d}</div>
                      <div className="p">{s.p}</div>
                    </button>
                  ))}
                </div>
                <div style={{marginTop:20,display:'flex',gap:10}}>
                  <span className="chip">Sur place</span>
                  <span className="chip chip-outline">À distance possible pour le support</span>
                </div>
              </div>
            )}

            {step === 1 && (
              <div>
                <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:6}}>
                  <h3 style={{fontSize:20}}>Choisissez une date</h3>
                  <div style={{display:'flex',gap:6,alignItems:'center'}}>
                    <button className="btn btn-sm btn-ghost" onClick={()=>setView(v=>new Date(v.getFullYear(),v.getMonth()-1,1))}><Icon name="chevL" size={14}/></button>
                    <span style={{padding:'8px 14px',fontWeight:600,fontSize:14,textTransform:'capitalize'}}>{monthLabel(view)}</span>
                    <button className="btn btn-sm btn-ghost" onClick={()=>setView(v=>new Date(v.getFullYear(),v.getMonth()+1,1))}><Icon name="chevR" size={14}/></button>
                    {availLoading && <span style={{fontSize:12,color:'var(--muted)'}}>Chargement…</span>}
                  </div>
                </div>
                <p style={{color:'var(--muted)',fontSize:14,marginBottom:8}}>Dimanches non disponibles. Les créneaux apparaissent à l'étape suivante.</p>
                <div className="calendar">
                  {['Lun','Mar','Mer','Jeu','Ven','Sam','Dim'].map(d=><div key={d} className="cal-h">{d}</div>)}
                  {days.map((d,i)=>{
                    if (!d) return <div key={i} className="cal-d empty"/>;
                    const dis = !isAvailable(d);
                    const sel = sameDay(d, picked.date);
                    const isToday = sameDay(d, new Date());
                    return (
                      <button key={i} type="button"
                        className={`cal-d ${dis?'disabled':'available'} ${sel?'selected':''} ${isToday?'today':''}`}
                        disabled={dis}
                        onClick={()=>{ if (!dis) setPicked(p=>({...p,date:d,slot:null})); }}>
                        {d.getDate()}
                      </button>
                    );
                  })}
                </div>
              </div>
            )}

            {step === 2 && (
              <div>
                <h3 style={{fontSize:20,marginBottom:6}}>Choisissez un créneau</h3>
                <p style={{color:'var(--muted)',fontSize:14,marginBottom:18}}>
                  {picked.date?.toLocaleDateString('fr-CH',{weekday:'long',day:'numeric',month:'long',year:'numeric'})}
                </p>
                {slotError && (
                  <div style={{marginBottom:16,padding:'12px 16px',background:'#fff3cd',borderRadius:'var(--r)',color:'#7a4a00',fontSize:14,display:'flex',alignItems:'center',gap:8}}>
                    <Icon name="bolt" size={16} color="#7a4a00"/> {slotError}
                  </div>
                )}
                <div className="slots">
                  {SLOTS.map(s => {
                    const taken = slotTaken(s);
                    return (
                      <button key={s} type="button" disabled={taken}
                        className={`slot ${picked.slot===s?'selected':''} ${taken?'taken':''}`}
                        onClick={()=>{ if (!taken) { setPicked(p=>({...p,slot:s})); setSlotError(null); } }}>
                        {s}
                      </button>
                    );
                  })}
                </div>
                <div style={{marginTop:24,padding:16,background:'var(--cream)',borderRadius:'var(--r)',display:'flex',gap:12,alignItems:'center'}}>
                  <Icon name="bolt" size={18} color="var(--primary)"/>
                  <span style={{fontSize:13,color:'var(--ink-2)'}}>Besoin urgent dans les 24h ? <b>Appelez-moi au 076 281 76 43</b>, j'essaierai de m'organiser.</span>
                </div>
              </div>
            )}

            {step === 3 && (
              <form onSubmit={submit}>
                <div style={{display:'grid',gridTemplateColumns:'1.2fr 1fr',gap:32,alignItems:'flex-start'}} className="booking-final">
                  <div>
                    <h3 style={{fontSize:20,marginBottom:18}}>Vos coordonnées</h3>
                    <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:14}}>
                      <div className="field">
                        <label>Nom complet *</label>
                        <input required value={picked.name} onChange={e=>setPicked(p=>({...p,name:e.target.value}))} />
                      </div>
                      <div className="field">
                        <label>E-mail *</label>
                        <input type="email" required value={picked.email} onChange={e=>setPicked(p=>({...p,email:e.target.value}))} />
                      </div>
                      <div className="field">
                        <label>Téléphone</label>
                        <input type="tel" value={picked.phone} onChange={e=>setPicked(p=>({...p,phone:e.target.value}))} placeholder="076 000 00 00"/>
                      </div>
                      <div className="field">
                        <label>Lieu de l'intervention</label>
                        <select value={picked.mode} onChange={e=>setPicked(p=>({...p,mode:e.target.value}))}>
                          <option value="place">Chez vous (Lausanne et alentours)</option>
                          <option value="remote">À distance</option>
                          <option value="office">Au bureau (Rue de l'Ale 31)</option>
                        </select>
                      </div>
                    </div>
                    <div className="field" style={{marginTop:14}}>
                      <label>Adresse / précisions</label>
                      <input value={picked.address} onChange={e=>setPicked(p=>({...p,address:e.target.value}))} placeholder="Rue, n° et localité"/>
                    </div>
                    <div className="field" style={{marginTop:14}}>
                      <label>Décrivez votre besoin (optionnel)</label>
                      <textarea value={picked.notes} onChange={e=>setPicked(p=>({...p,notes:e.target.value}))} placeholder="Ex : nouveau MacBook + 2 écrans à installer, migration depuis ancien PC…"></textarea>
                    </div>
                  </div>
                  <div style={{position:'sticky',top:90}}>
                    <div className="card" style={{padding:24,background:'var(--cream)'}}>
                      <div className="eyebrow">Récapitulatif</div>
                      <div style={{marginTop:14}}>
                        <div className="summary-row" style={{borderTop:'none',paddingTop:0}}><span className="lbl">Service</span><span style={{fontWeight:600}}>{selService?.t}</span></div>
                        <div className="summary-row"><span className="lbl">Durée estimée</span><span>{selService?.dur}</span></div>
                        <div className="summary-row"><span className="lbl">Date</span><span style={{fontWeight:600,textTransform:'capitalize'}}>{picked.date?.toLocaleDateString('fr-CH',{weekday:'short',day:'numeric',month:'short'})}</span></div>
                        <div className="summary-row"><span className="lbl">Heure</span><span style={{fontWeight:600}}>{picked.slot}</span></div>
                        <div className="summary-row total"><span>À payer</span><span>{selService?.p}</span></div>
                      </div>
                      <p style={{fontSize:12,color:'var(--muted)',marginTop:14,lineHeight:1.55}}>
                        Paiement après l'intervention par TWINT, virement ou espèces. Devis détaillé envoyé sous 24h si nécessaire.
                      </p>
                    </div>
                  </div>
                </div>
                <button type="submit" disabled={submitLoading} className="btn btn-primary" style={{marginTop:24}}>
                  {submitLoading ? 'Envoi en cours…' : <>Confirmer la réservation <Icon name="check" size={16} stroke={2.4}/></>}
                </button>
              </form>
            )}
          </div>

          {step < 3 && (
            <div style={{display:'flex',justifyContent:'space-between',padding:'18px 36px 28px',gap:12,borderTop:'1px solid var(--line)'}}>
              <button className="btn btn-ghost btn-sm" onClick={prev} disabled={step===0} style={{opacity:step===0?.4:1}}>
                <Icon name="chevL" size={14}/> Retour
              </button>
              <button className="btn btn-primary btn-sm" onClick={next} disabled={!canNext()} style={{opacity:canNext()?1:.5}}>
                Continuer <Icon name="chevR" size={14}/>
              </button>
            </div>
          )}
        </div>
      </div>
    </section>
  );
};

window.Booking = Booking;
