<div class="ab-card mb-3">
  <div class="ab-card-header">
    <div class="d-flex align-items-center gap-3">
      <button class="btn btn-icon btn-light-soft" id="abCalPrev"><i class="bi bi-chevron-left"></i></button>
      <h2 class="mb-0" id="abCalLabel">Loading…</h2>
      <button class="btn btn-icon btn-light-soft" id="abCalNext"><i class="bi bi-chevron-right"></i></button>
      <button class="btn btn-light-soft btn-sm" id="abCalToday">Today</button>
    </div>
    <div class="d-flex gap-2">
      <div class="btn-group btn-group-sm" role="group">
        <button class="btn btn-light-soft active" data-view="month">Month</button>
        <button class="btn btn-light-soft" data-view="week">Week</button>
        <button class="btn btn-light-soft" data-view="day">Day</button>
      </div>
      <a href="<?= base_url('appointments/export') ?>" class="btn btn-light-soft btn-sm"><i class="bi bi-download"></i></a>
      <button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#abApptModal" id="abNewApptBtn"><i class="bi bi-plus-lg me-1"></i>New Appointment</button>
    </div>
  </div>
  <div class="ab-card-body">
    <div class="row g-3 mb-3">
      <div class="col-auto"><select class="form-select form-select-sm" id="abCalFilterBl"><option value="">All Businesses</option><?php foreach ($lookups['business_lines'] as $bl): ?><option value="<?= (int) $bl['id'] ?>"><?= e($bl['name']) ?></option><?php endforeach; ?></select></div>
      <div class="col-auto"><select class="form-select form-select-sm" id="abCalFilterStaff"><option value="">All Staff</option><?php foreach ($lookups['staff'] as $s): ?><option value="<?= (int) $s['id'] ?>"><?= e($s['name']) ?></option><?php endforeach; ?></select></div>
    </div>
    <div id="abCalGrid"><div class="text-center p-5 ab-text-muted">Loading calendar…</div></div>
  </div>
</div>

<!-- Booking Modal -->
<div class="modal fade" id="abApptModal" tabindex="-1">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header"><h5 class="modal-title">New Appointment</h5><button class="btn-close" data-bs-dismiss="modal"></button></div>
      <div class="modal-body">
        <div id="abAvailabilityWarning" class="alert alert-warning d-none">This staff member already has a conflicting appointment.</div>
        <form id="abApptForm">
          <div class="mb-3"><label class="form-label ab-req">Business Line</label>
            <select class="form-select" name="business_line_id" required><?php foreach ($lookups['business_lines'] as $bl): ?><option value="<?= (int) $bl['id'] ?>"><?= e($bl['name']) ?></option><?php endforeach; ?></select>
          </div>
          <div class="mb-3"><label class="form-label">Link To</label>
            <div class="d-flex gap-2 mb-2"><span class="ab-chip active" data-link="customer">Customer</span><span class="ab-chip" data-link="lead">Lead</span></div>
            <select class="form-select" name="customer_id" id="abLinkCustomer"><option value="">Select a customer...</option><?php foreach ($lookups['customers'] as $c): ?><option value="<?= (int) $c['id'] ?>"><?= e($c['name']) ?></option><?php endforeach; ?></select>
            <select class="form-select d-none" name="lead_id" id="abLinkLead"><option value="">Select a lead...</option><?php foreach ($lookups['leads'] as $l): ?><option value="<?= (int) $l['id'] ?>"><?= e($l['name']) ?></option><?php endforeach; ?></select>
          </div>
          <div class="row g-3 mb-3">
            <div class="col-6"><label class="form-label ab-req">Date</label><input type="date" class="form-control" name="date" required></div>
            <div class="col-3"><label class="form-label ab-req">Start</label><input type="time" class="form-control" name="start_time" value="09:00" required></div>
            <div class="col-3"><label class="form-label ab-req">End</label><input type="time" class="form-control" name="end_time" value="10:00" required></div>
          </div>
          <div class="mb-3"><label class="form-label">Service Type</label>
            <select class="form-select" name="service_type_id"><option value="">—</option><?php foreach ($lookups['service_types'] as $st): ?><option value="<?= (int) $st['id'] ?>" data-duration="<?= (int) $st['default_duration_minutes'] ?>"><?= e($st['name']) ?></option><?php endforeach; ?></select>
          </div>
          <div class="mb-3"><label class="form-label">Assigned Staff</label>
            <select class="form-select" name="assigned_staff_id" id="abApptStaff"><option value="">—</option><?php foreach ($lookups['staff'] as $s): ?><option value="<?= (int) $s['id'] ?>"><?= e($s['name']) ?></option><?php endforeach; ?></select>
          </div>
          <div class="mb-3"><label class="form-label">Location / Address</label><input class="form-control" name="location_address"></div>
          <div class="mb-3">
            <div class="form-check"><input class="form-check-input" type="checkbox" id="abRecurringCheck"><label class="form-check-label small" for="abRecurringCheck">Recurring Appointment</label></div>
            <div id="abRecurrenceOptions" class="d-none row g-2 mt-1">
              <div class="col-5"><select class="form-select form-select-sm" id="abRecurFreq"><option value="weekly">Weekly</option><option value="biweekly">Every 2 weeks</option><option value="monthly">Monthly</option></select></div>
              <div class="col-7"><input type="date" class="form-control form-control-sm" id="abRecurUntil" placeholder="Repeat until"></div>
            </div>
          </div>
          <div class="mb-0"><label class="form-label">Notes</label><textarea class="form-control" name="notes" rows="2"></textarea></div>
        </form>
      </div>
      <div class="modal-footer"><button class="btn btn-light-soft" data-bs-dismiss="modal">Cancel</button><button class="btn btn-primary" id="abApptSaveBtn">Book Appointment</button></div>
    </div>
  </div>
</div>

<!-- Detail / actions modal -->
<div class="modal fade" id="abApptDetailModal" tabindex="-1">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header"><h5 class="modal-title">Appointment</h5><button class="btn-close" data-bs-dismiss="modal"></button></div>
      <div class="modal-body" id="abApptDetailBody"></div>
      <div class="modal-footer" id="abApptDetailActions"></div>
    </div>
  </div>
</div>

<script>
(function () {
  var currentView = 'month';
  var currentDate = new Date();

  function fmt(d) { return d.toISOString().slice(0, 19).replace('T', ' '); }
  function rangeForView() {
    var start, end;
    if (currentView === 'month') {
      start = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1);
      end = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1);
    } else if (currentView === 'week') {
      var day = currentDate.getDay();
      start = new Date(currentDate); start.setDate(currentDate.getDate() - day);
      end = new Date(start); end.setDate(start.getDate() + 7);
    } else {
      start = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
      end = new Date(start); end.setDate(start.getDate() + 1);
    }
    return { start: start, end: end };
  }

  function renderLabel(range) {
    var opts = { year: 'numeric', month: 'long' };
    if (currentView === 'day') opts = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
    document.getElementById('abCalLabel').textContent = currentView === 'week'
      ? range.start.toLocaleDateString(undefined, { month: 'short', day: 'numeric' }) + ' – ' + new Date(range.end - 86400000).toLocaleDateString(undefined, { month: 'short', day: 'numeric' })
      : currentDate.toLocaleDateString(undefined, opts);
  }

  function load() {
    var range = rangeForView();
    renderLabel(range);
    var params = new URLSearchParams({
      start: fmt(range.start), end: fmt(range.end),
      business_line_id: document.getElementById('abCalFilterBl').value,
      assigned_staff_id: document.getElementById('abCalFilterStaff').value
    });
    abFetch('<?= base_url('appointments/feed') ?>?' + params.toString())
      .then(function (res) { renderGrid(res.data, range); })
      .catch(function (err) {
        document.getElementById('abCalGrid').innerHTML =
          '<div class="text-center p-5 ab-text-muted"><i class="bi bi-exclamation-triangle text-danger d-block mb-2" style="font-size:1.5rem;"></i>' +
          'Could not load the calendar: ' + (err.message || 'unknown error') +
          '<div class="mt-2"><button class="btn btn-light-soft btn-sm" id="abCalRetry">Retry</button></div></div>';
        document.getElementById('abCalRetry')?.addEventListener('click', load);
      });
  }

  function renderGrid(appointments, range) {
    var grid = document.getElementById('abCalGrid');
    if (currentView === 'month') {
      grid.innerHTML = renderMonthGrid(appointments, range);
    } else {
      grid.innerHTML = renderListGrid(appointments);
    }
    grid.querySelectorAll('.ab-cal-event, .ab-appt-list-item').forEach(function (el) {
      el.addEventListener('click', function () { showDetail(el.dataset.apptId, appointments); });
    });
  }

  function renderMonthGrid(appointments, range) {
    var byDay = {};
    appointments.forEach(function (a) {
      var key = a.scheduled_start.slice(0, 10);
      (byDay[key] = byDay[key] || []).push(a);
    });

    var firstOfMonth = new Date(range.start);
    var startDow = firstOfMonth.getDay();
    var gridStart = new Date(firstOfMonth); gridStart.setDate(1 - startDow);
    var html = '<div class="ab-cal-grid"><div class="ab-cal-dow">Sun</div><div class="ab-cal-dow">Mon</div><div class="ab-cal-dow">Tue</div><div class="ab-cal-dow">Wed</div><div class="ab-cal-dow">Thu</div><div class="ab-cal-dow">Fri</div><div class="ab-cal-dow">Sat</div>';

    for (var i = 0; i < 42; i++) {
      var d = new Date(gridStart); d.setDate(gridStart.getDate() + i);
      var key = d.toISOString().slice(0, 10);
      var inMonth = d.getMonth() === range.start.getMonth();
      var isToday = key === new Date().toISOString().slice(0, 10);
      var events = (byDay[key] || []).slice(0, 4).map(function (a) {
        var label = (a.customer_name || a.lead_name || 'Appointment').trim();
        var cls = a.status === 'cancelled' ? 'bg-danger-soft text-danger' : 'bg-primary-soft text-primary';
        return '<div class="ab-cal-event ' + cls + '" data-appt-id="' + a.id + '">' + a.scheduled_start.slice(11, 16) + ' ' + label + '</div>';
      }).join('');
      html += '<div class="ab-cal-cell ' + (inMonth ? '' : 'muted') + ' ' + (isToday ? 'today' : '') + '"><span class="ab-cal-daynum">' + d.getDate() + '</span>' + events + '</div>';
      if (i > 27 && d.getMonth() !== range.start.getMonth() && i % 7 === 6) break;
    }
    html += '</div>';
    return html;
  }

  function renderListGrid(appointments) {
    if (!appointments.length) return '<div class="ab-empty"><i class="bi bi-calendar-x"></i><h3>No appointments in this range</h3></div>';
    return '<div class="list-group">' + appointments.map(function (a) {
      var label = (a.customer_name || a.lead_name || 'Appointment').trim();
      var badge = { scheduled: 'bg-secondary-soft', completed: 'bg-success-soft', cancelled: 'bg-danger-soft', no_show: 'bg-warning-soft' }[a.status] || 'bg-secondary-soft';
      return '<div class="ab-appt-list-item d-flex align-items-center gap-3 p-3 border-bottom ab-hairline" style="cursor:pointer;" data-appt-id="' + a.id + '">' +
        '<div class="ab-mono small" style="width:140px;">' + new Date(a.scheduled_start).toLocaleString(undefined, { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' }) + '</div>' +
        '<div class="flex-fill"><strong class="small">' + label + '</strong><div class="ab-cell-sub">' + (a.service_name || '') + ' · ' + (a.staff_name || 'Unassigned') + '</div></div>' +
        '<span class="ab-badge ' + badge + '">' + a.status.replace('_', ' ') + '</span></div>';
    }).join('') + '</div>';
  }

  function showDetail(id, appointments) {
    var a = appointments.find(function (x) { return String(x.id) === String(id); });
    if (!a) return;
    document.getElementById('abApptDetailBody').innerHTML =
      '<p><strong>' + (a.customer_name || a.lead_name || '') + '</strong></p>' +
      '<p class="small ab-text-muted">' + new Date(a.scheduled_start).toLocaleString() + ' – ' + new Date(a.scheduled_end).toLocaleTimeString() + '</p>' +
      '<p class="small">' + (a.service_name || '') + ' · ' + (a.staff_name || 'Unassigned') + '</p>';

    document.getElementById('abApptDetailActions').innerHTML =
      '<button class="btn btn-light-soft btn-sm" id="abActCancel">Cancel</button>' +
      '<button class="btn btn-light-soft btn-sm" id="abActMissed">Mark Missed</button>' +
      '<button class="btn btn-primary btn-sm" id="abActComplete">Mark Completed</button>';

    document.getElementById('abActCancel').onclick = function () {
      var reason = prompt('Cancellation reason?') || 'No reason given';
      abFetch('<?= base_url('appointments') ?>/' + a.id + '/cancel', { method: 'POST', body: { reason: reason } })
        .then(function () { abToast('Appointment cancelled.'); bootstrap.Modal.getInstance(document.getElementById('abApptDetailModal')).hide(); load(); });
    };
    document.getElementById('abActMissed').onclick = function () {
      abFetch('<?= base_url('appointments') ?>/' + a.id + '/missed', { method: 'POST' })
        .then(function () { abToast('Marked as missed.'); bootstrap.Modal.getInstance(document.getElementById('abApptDetailModal')).hide(); load(); });
    };
    document.getElementById('abActComplete').onclick = function () {
      abFetch('<?= base_url('appointments') ?>/' + a.id + '/complete', { method: 'POST' })
        .then(function () { abToast('Marked completed.'); bootstrap.Modal.getInstance(document.getElementById('abApptDetailModal')).hide(); load(); });
    };

    new bootstrap.Modal(document.getElementById('abApptDetailModal')).show();
  }

  document.querySelectorAll('[data-view]').forEach(function (btn) {
    btn.addEventListener('click', function () {
      document.querySelectorAll('[data-view]').forEach(function (b) { b.classList.remove('active'); });
      btn.classList.add('active');
      currentView = btn.dataset.view;
      load();
    });
  });
  document.getElementById('abCalPrev').addEventListener('click', function () { step(-1); });
  document.getElementById('abCalNext').addEventListener('click', function () { step(1); });
  document.getElementById('abCalToday').addEventListener('click', function () { currentDate = new Date(); load(); });
  function step(dir) {
    if (currentView === 'month') currentDate.setMonth(currentDate.getMonth() + dir);
    else if (currentView === 'week') currentDate.setDate(currentDate.getDate() + dir * 7);
    else currentDate.setDate(currentDate.getDate() + dir);
    load();
  }
  ['abCalFilterBl', 'abCalFilterStaff'].forEach(function (id) { document.getElementById(id).addEventListener('change', load); });

  // ---- Booking form ----
  document.querySelectorAll('[data-link]').forEach(function (chip) {
    chip.addEventListener('click', function () {
      document.querySelectorAll('[data-link]').forEach(function (c) { c.classList.remove('active'); });
      chip.classList.add('active');
      document.getElementById('abLinkCustomer').classList.toggle('d-none', chip.dataset.link !== 'customer');
      document.getElementById('abLinkLead').classList.toggle('d-none', chip.dataset.link !== 'lead');
    });
  });
  document.getElementById('abRecurringCheck').addEventListener('change', function () {
    document.getElementById('abRecurrenceOptions').classList.toggle('d-none', !this.checked);
  });

  document.getElementById('abApptSaveBtn').addEventListener('click', function () {
    var form = document.getElementById('abApptForm');
    var fd = new FormData(form);
    var data = Object.fromEntries(fd.entries());
    data.scheduled_start = data.date + ' ' + data.start_time + ':00';
    data.scheduled_end = data.date + ' ' + data.end_time + ':00';
    delete data.date; delete data.start_time; delete data.end_time;

    if (document.getElementById('abRecurringCheck').checked) {
      data.recurrence = {
        frequency: document.getElementById('abRecurFreq').value,
        interval: 1,
        until: document.getElementById('abRecurUntil').value
      };
    }

    abFetch('<?= base_url('appointments') ?>', { method: 'POST', body: data }).then(function (res) {
      abToast(res.message);
      bootstrap.Modal.getInstance(document.getElementById('abApptModal')).hide();
      load();
    }).catch(function (err) {
      if (err.errors && err.errors.conflict) {
        document.getElementById('abAvailabilityWarning').classList.remove('d-none');
      }
      abToast(err.message || 'Booking failed.', 'danger');
    });
  });

  load();
})();
</script>