// PickupCalendar — monthly grid of pickup orders + block-slot editor.

const PICKUP_SLOTS = [
  '07:00','07:30','08:00','08:30','09:00','09:30',
  '10:00','10:30','11:00','11:30','12:00','12:30',
  '13:00','13:30','14:00','14:30'
];

function localIso(d) {
  // YYYY-MM-DD from LOCAL parts — never via toISOString, which shifts by TZ offset.
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  return `${y}-${m}-${day}`;
}

function monthDays(year, month) {
  // month: 0–11. Returns array of ISO dates (YYYY-MM-DD) for the calendar grid
  // starting on Monday, including leading/trailing days for full weeks.
  const first = new Date(year, month, 1);
  const dow = (first.getDay() + 6) % 7; // 0=Mon
  const start = new Date(year, month, 1 - dow);
  const days = [];
  for (let i = 0; i < 42; i++) {
    const d = new Date(start); d.setDate(start.getDate() + i);
    days.push({ iso: localIso(d), date: d, inMonth: d.getMonth() === month });
  }
  return days;
}

function toLegacySlotKey(iso, time) {
  // Plugin stores blocked slots as DD-MM-YYYY_HH:MM in legacy format
  const [y, m, d] = iso.split('-');
  return `${d}-${m}-${y}_${time}`;
}

function PickupCalendar() {
  const now = new Date();
  const [view, setView] = React.useState({ year: now.getFullYear(), month: now.getMonth() });
  const [pickups, setPickups] = React.useState([]);
  const [blocked, setBlocked] = React.useState([]);  // array of "DD-MM-YYYY_HH:MM" strings
  const [loading, setLoading] = React.useState(true);
  const [toast, setToast] = React.useState(null);
  const [dayModal, setDayModal] = React.useState(null); // ISO date
  const canEdit = window.hasPerm ? window.hasPerm('calendar.edit') : false;

  const days = monthDays(view.year, view.month);
  const monthStart = days.find(d => d.inMonth).iso;
  const monthEndDate = [...days].reverse().find(d => d.inMonth).iso;

  async function reload() {
    setLoading(true);
    const [r1, r2] = await Promise.all([
      API.getPickupCalendar(monthStart, monthEndDate),
      API.getPickupBlocked(),
    ]);
    setLoading(false);
    if (r1.ok) setPickups(r1.body.pickups || []);
    if (r2.ok) setBlocked(r2.body.blocked_slots || []);
  }
  React.useEffect(() => { reload(); /* eslint-disable-next-line */ }, [view.year, view.month]);

  const monthNames = ['Január','Február','Marec','Apríl','Máj','Jún','Júl','August','September','Október','November','December'];
  const dayNames = ['Po','Ut','St','Št','Pi','So','Ne'];

  function prevMonth() { setView(v => v.month === 0 ? { year: v.year - 1, month: 11 } : { year: v.year, month: v.month - 1 }); }
  function nextMonth() { setView(v => v.month === 11 ? { year: v.year + 1, month: 0 } : { year: v.year, month: v.month + 1 }); }
  function goToday()   { setView({ year: now.getFullYear(), month: now.getMonth() }); }

  // Group pickups by ISO date
  const byDate = React.useMemo(() => {
    const m = {};
    for (const p of pickups) {
      if (!m[p.date]) m[p.date] = [];
      m[p.date].push(p);
    }
    return m;
  }, [pickups]);

  // Helper: is a slot blocked?
  function isSlotBlocked(iso, time) {
    return blocked.includes(toLegacySlotKey(iso, time));
  }
  function blockedCountForDay(iso) {
    const [y, m, d] = iso.split('-');
    const prefix = `${d}-${m}-${y}_`;
    return blocked.filter(s => s.startsWith(prefix)).length;
  }
  function isWholeDayBlocked(iso) {
    return blockedCountForDay(iso) >= PICKUP_SLOTS.length;
  }

  async function toggleBlock(iso, time, on) {
    if (!canEdit) return;
    const key = toLegacySlotKey(iso, time);
    const next = on
      ? (blocked.includes(key) ? blocked : [...blocked, key])
      : blocked.filter(s => s !== key);
    setBlocked(next);                         // optimistic
    const r = await API.setPickupBlocked(next);
    if (!r.ok) { setBlocked(blocked); setToast({kind:'error', text:'Nepodarilo sa uložiť.'}); }
  }
  async function toggleDayAll(iso) {
    if (!canEdit) return;
    const [y, m, d] = iso.split('-');
    const prefix = `${d}-${m}-${y}_`;
    const existing = blocked.filter(s => s.startsWith(prefix));
    const shouldBlock = existing.length < PICKUP_SLOTS.length; // if not all blocked → block all
    const next = shouldBlock
      ? [...blocked.filter(s => !s.startsWith(prefix)), ...PICKUP_SLOTS.map(t => `${d}-${m}-${y}_${t}`)]
      : blocked.filter(s => !s.startsWith(prefix));
    setBlocked(next);
    const r = await API.setPickupBlocked(next);
    if (!r.ok) { setBlocked(blocked); setToast({kind:'error', text:'Chyba.'}); }
  }

  async function setPickupStatus(orderId, next) {
    const r = await API.updateOrderPickup(orderId, { pickup_status: next });
    if (r.ok) { reload(); setToast({kind:'success', text: next === 'confirmed' ? 'Termín potvrdený.' : 'Stav zmenený.'}); }
    else      setToast({kind:'error', text:'Chyba.'});
  }

  const dayModalPickups = dayModal ? (byDate[dayModal] || []) : [];
  const todayIso = localIso(new Date());
  // Newest first for the table below (plugin returns ascending).
  const pickupsDesc = React.useMemo(() => (
    [...pickups].sort((a, b) => {
      const c = (b.date || '').localeCompare(a.date || '');
      return c !== 0 ? c : (b.time || '').localeCompare(a.time || '');
    })
  ), [pickups]);

  return (
    <AppShell active="pickup" crumbs={['CRM','Osobný odber']}>
      {toast && <Toast kind={toast.kind} onClose={() => setToast(null)}>{toast.text}</Toast>}
      {dayModal && (
        <Modal
          title={`${dayModal}${isWholeDayBlocked(dayModal) ? ' — celý deň zablokovaný' : ''}`}
          width={640}
          onClose={() => setDayModal(null)}
          footer={<button className="btn" onClick={() => setDayModal(null)}>Zavrieť</button>}
        >
          <div className="vstack" style={{gap:14}}>
            {/* Pickups scheduled for this day */}
            <div>
              <div className="small muted" style={{textTransform:'uppercase', letterSpacing:'0.08em', fontWeight:600, marginBottom:6}}>
                Objednávky na tento deň ({dayModalPickups.length})
              </div>
              {dayModalPickups.length === 0 ? (
                <div className="small muted" style={{padding:10, border:'1px dashed var(--border-strong)', borderRadius:6, textAlign:'center'}}>
                  Žiadne objednávky s osobným odberom.
                </div>
              ) : (
                <div className="vstack" style={{gap:6}}>
                  {dayModalPickups.map(p => (
                    <div key={p.order_id} className="card" style={{padding:10}}>
                      <div className="hstack">
                        <div style={{flex:1, minWidth:0}}>
                          <div style={{fontWeight:600}}>
                            <a href={`#/order?id=${p.order_id}`} style={{color:'var(--navy-700)', textDecoration:'none'}}>#{p.order_number}</a>
                            {' · '}{p.time || '—'} · {p.customer_name || p.customer_email}
                          </div>
                          <div className="small muted">
                            {p.pickup_status === 'confirmed' ? '✓ Potvrdené' :
                             p.pickup_status === 'picked_up' ? '✓ Vyzdvihnuté' :
                             p.pickup_status === 'suggested' ? '↔ Navrhnutý nový termín' :
                             '⏳ Čaká na potvrdenie'} · {p.person || '—'} · ŠPZ {p.spz || '—'} · {p.total} {p.currency}
                          </div>
                        </div>
                        {canEdit && p.pickup_status !== 'confirmed' && (
                          <button className="btn btn-xs" style={{background:'var(--green-100)', color:'#135e37', borderColor:'transparent'}}
                                  onClick={() => setPickupStatus(p.order_id, 'confirmed')}>
                            <Ico.check/>Potvrdiť
                          </button>
                        )}
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </div>

            {/* Blocked slots editor */}
            <div>
              <div className="hstack" style={{marginBottom:6}}>
                <div className="small muted" style={{textTransform:'uppercase', letterSpacing:'0.08em', fontWeight:600, flex:1}}>
                  Zablokované časy ({blockedCountForDay(dayModal)} / {PICKUP_SLOTS.length})
                </div>
                {canEdit && (
                  <button className="btn btn-xs" onClick={() => toggleDayAll(dayModal)}>
                    {isWholeDayBlocked(dayModal) ? 'Odblokovať celý deň' : 'Zablokovať celý deň'}
                  </button>
                )}
              </div>
              <div style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:6}}>
                {PICKUP_SLOTS.map(t => {
                  const b = isSlotBlocked(dayModal, t);
                  return (
                    <button
                      key={t}
                      type="button"
                      onClick={() => canEdit && toggleBlock(dayModal, t, !b)}
                      disabled={!canEdit}
                      className={`perm-cell ${b ? 'off' : 'on'}`}
                      style={{padding:'0 4px', minWidth:60}}
                    >{t}{b ? ' ✗' : ''}</button>
                  );
                })}
              </div>
            </div>
          </div>
        </Modal>
      )}

      <div className="page-head">
        <div>
          <h1>Osobný odber</h1>
          <p>Kalendár vyzdvihnutí · {pickups.length} termínov v tomto mesiaci</p>
        </div>
        <div className="page-head-actions">
          <button className="btn" onClick={reload}><Ico.refresh/>Obnoviť</button>
        </div>
      </div>

      <div className="card" style={{marginBottom:14}}>
        <div className="card-head" style={{padding:'10px 14px'}}>
          <div className="hstack">
            <button className="btn btn-sm" onClick={prevMonth}>←</button>
            <b style={{fontSize:15, margin:'0 8px', minWidth:150, textAlign:'center'}}>
              {monthNames[view.month]} {view.year}
            </b>
            <button className="btn btn-sm" onClick={nextMonth}>→</button>
            <button className="btn btn-sm" style={{marginLeft:8}} onClick={goToday}>Dnes</button>
            <div style={{marginLeft:'auto'}} className="hstack small">
              <span className="chip green dot">Potvrdené</span>
              <span className="chip amber dot">Čaká</span>
              <span className="chip red dot">Blokovaný deň</span>
            </div>
          </div>
        </div>
        <div style={{display:'grid', gridTemplateColumns:'repeat(7, 1fr)', gap:1, background:'var(--border)'}}>
          {dayNames.map(dn => (
            <div key={dn} style={{padding:'8px 10px', background:'var(--blue-50)', fontSize:11, fontWeight:600, color:'var(--ink-500)', textAlign:'center', letterSpacing:'0.08em', textTransform:'uppercase'}}>
              {dn}
            </div>
          ))}
          {days.map(d => {
            const items = byDate[d.iso] || [];
            const blockedN = blockedCountForDay(d.iso);
            const wholeBlocked = blockedN >= PICKUP_SLOTS.length;
            const isToday = d.iso === todayIso;
            return (
              <button
                key={d.iso}
                onClick={() => setDayModal(d.iso)}
                style={{
                  background: wholeBlocked ? '#fee2e2' : '#fff',
                  opacity: d.inMonth ? 1 : 0.4,
                  border: 'none',
                  borderLeft: isToday ? '3px solid var(--amber-500)' : 'none',
                  padding: '6px 8px',
                  minHeight: 86,
                  textAlign: 'left',
                  cursor: 'pointer',
                  fontFamily: 'var(--font)',
                  display: 'flex',
                  flexDirection: 'column',
                  gap: 3,
                }}
              >
                <div className="hstack">
                  <span style={{fontWeight: isToday ? 700 : 500, fontSize:12, color: d.inMonth ? 'var(--ink-900)' : 'var(--ink-400)'}}>
                    {d.date.getDate()}
                  </span>
                  {blockedN > 0 && !wholeBlocked && <span className="chip red" style={{marginLeft:'auto', padding:'0 5px', fontSize:9}}>{blockedN}✗</span>}
                  {wholeBlocked && <span className="chip red dot" style={{marginLeft:'auto', padding:'0 5px', fontSize:9}}>zavreté</span>}
                </div>
                {items.slice(0, 3).map(p => {
                  const cls = p.pickup_status === 'confirmed' ? 'green' :
                              p.pickup_status === 'picked_up' ? 'gray' : 'amber';
                  return (
                    <div key={p.order_id} className={`chip ${cls}`} style={{
                      padding:'1px 5px', fontSize:10, justifyContent:'flex-start',
                      maxWidth:'100%', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap',
                    }}>
                      {p.time || ''} #{p.order_number}
                    </div>
                  );
                })}
                {items.length > 3 && <div className="small muted" style={{fontSize:10}}>+{items.length - 3} ďalších</div>}
              </button>
            );
          })}
        </div>
        {loading && <div className="small muted" style={{padding:10, textAlign:'center'}}>Načítavam…</div>}
      </div>

      <div className="card">
        <div className="card-head"><h3>Všetky termíny v tomto mesiaci</h3></div>
        {pickups.length === 0 ? (
          <div style={{padding:30, textAlign:'center', color:'var(--ink-500)'}}>Žiadne pickup termíny v tomto mesiaci.</div>
        ) : (
          <table className="tbl">
            <thead><tr>
              <th>Dátum</th><th>Čas</th><th>Objednávka</th><th>Zákazník</th><th>Osoba / ŠPZ</th><th>Suma</th><th>Stav</th><th></th>
            </tr></thead>
            <tbody>
              {pickupsDesc.map(p => (
                <tr key={p.order_id}>
                  <td className="mono small">{p.date}</td>
                  <td className="mono small">{p.time || '—'}</td>
                  <td><a href={`#/order?id=${p.order_id}`} style={{color:'var(--navy-700)', fontWeight:600}}>#{p.order_number}</a></td>
                  <td>{p.customer_name || p.customer_email}<div className="small muted">{p.customer_phone || ''}</div></td>
                  <td>{p.person || '—'}<div className="small muted mono">{(p.spz || '').toUpperCase()}</div></td>
                  <td>{p.total} {p.currency}</td>
                  <td>
                    {p.pickup_status === 'confirmed' ? <span className="chip green dot">Potvrdené</span> :
                     p.pickup_status === 'picked_up' ? <span className="chip gray dot">Vyzdvihnuté</span> :
                     p.pickup_status === 'suggested' ? <span className="chip navy dot">Nový termín</span> :
                     <span className="chip amber dot">Čaká</span>}
                  </td>
                  <td style={{textAlign:'right', whiteSpace:'nowrap'}}>
                    {canEdit && p.pickup_status !== 'confirmed' && (
                      <button
                        className="btn btn-xs"
                        style={{background:'var(--green-100)', color:'#135e37', borderColor:'transparent'}}
                        onClick={() => setPickupStatus(p.order_id, 'confirmed')}
                      ><Ico.check/>Potvrdiť</button>
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </AppShell>
  );
}

Object.assign(window, { PickupCalendar });
