text: // Generated by BUCKLESCRIPT, PLEASE EDIT WITH CARE
  'use strict';
  
  var $$Array = require("bs-platform/lib/js/array.js");
  var MomentRe = require("bs-moment/lib/js/src/MomentRe.js");
  var Belt_Array = require("bs-platform/lib/js/belt_Array.js");
  var Caml_array = require("bs-platform/lib/js/caml_array.js");
  var Caml_splice_call = require("bs-platform/lib/js/caml_splice_call.js");
  var Sqlite3$SlotsChallenge = require("./Sqlite3.bs.js");
  
  function dayToJs(param) {
    return param;
  }
  
  function is(day, date) {
    return date.getDay() === day;
  }
  
  function isSaturday(date) {
    return is(/* Saturday */6, date);
  }
  
  function decodeEvent(r) {
    return {
            kind: r.kind,
            starts: new Date(r.starts_at),
            ends: new Date(r.ends_at),
            weekly_recurring: r.weekly_recurring
          };
  }
  
  function makeYMD(date) {
    return new Date(date.getFullYear(), date.getMonth(), date.getDate());
  }
  
  function copy(date) {
    return new Date(date.valueOf());
  }
  
  function toInt(date) {
    return date.valueOf() | 0;
  }
  
  function addDays(date, numberOfDays) {
    var d = new Date(date.valueOf());
    d.setDate(d.getDate() + numberOfDays);
    return d;
  }
  
  function addMinutes(date, numberOfMinutes) {
    var d = new Date(date.valueOf());
    d.setMinutes(d.getMinutes() + numberOfMinutes);
    return d;
  }
  
  function isWithinInterval(interval, date) {
    var ts = new Date(date.valueOf()).getTime();
    if (ts >= new Date(interval.start.valueOf()).getTime()) {
      return ts < new Date(interval.end_.valueOf()).getTime();
    } else {
      return false;
    }
  }
  
  function makeInterval(start, end_) {
    return {
            start: start,
            end_: end_
          };
  }
  
  function makeResult(r, date) {
    var rangeStart = addDays(date, -1);
    var data = Belt_Array.map(r, decodeEvent);
    var openings = Belt_Array.keepMap(data, (function (x) {
            var match = x.kind === "opening";
            if (match) {
              return x;
            }
            
          }));
    var appointments = Belt_Array.keepMap(data, (function (x) {
            var match = x.kind === "appointment";
            if (match) {
              return x;
            }
            
          }));
    var appointment = Caml_array.caml_array_get(appointments, 0);
    var createAvailabilitiesArray = function (date) {
      return $$Array.init(7, (function (index) {
                    var date$1 = addDays(date, index + 1 | 0);
                    return {
                            date: date$1,
                            slots: []
                          };
                  }));
    };
    var availabilities = createAvailabilitiesArray(rangeStart);
    var weekRangeStart = Caml_array.caml_array_get(data, 0).starts;
    var weekRangeEnd = addDays(weekRangeStart, 7);
    var weekInterval = {
      start: weekRangeStart,
      end_: weekRangeEnd
    };
    var generateApptSlots = function (param) {
      var formattedApptSlots = [];
      var starts = appointment.starts;
      var slotInterval_end_ = appointment.ends;
      var slotInterval = {
        start: starts,
        end_: slotInterval_end_
      };
      var slot = function (date) {
        if (isWithinInterval(slotInterval, date)) {
          var hours = date.toString();
          var formattedSlot = MomentRe.moment(undefined, hours).format("h:mm");
          formattedApptSlots.push(formattedSlot);
          slot(addMinutes(new Date(date.valueOf()), 30));
          return /* () */0;
        } else {
          return /* () */0;
        }
      };
      slot(starts);
      return formattedApptSlots;
    };
    var generateSlots = function (eventToCheck) {
      var formattedSlots = [];
      var starts = eventToCheck.starts;
      var slotInterval_end_ = eventToCheck.ends;
      var slotInterval = {
        start: starts,
        end_: slotInterval_end_
      };
      var slot = function (dateToCheck) {
        if (isWithinInterval(slotInterval, dateToCheck)) {
          var hours = dateToCheck.toString();
          var formattedSlot = MomentRe.moment(undefined, hours).format("h:mm");
          formattedSlots.push(formattedSlot);
          slot(addMinutes(new Date(dateToCheck.valueOf()), 30));
          return /* () */0;
        } else {
          return /* () */0;
        }
      };
      slot(starts);
      return formattedSlots;
    };
    var makeSlotTime = function (date, hours, minutes) {
      return new Date(date.getFullYear(), date.getMonth(), date.getDate(), hours, minutes);
    };
    Belt_Array.map(availabilities, (function (a) {
            var isSaturday = is(/* Saturday */6, a.date);
            var isInInterval = isWithinInterval(weekInterval, a.date);
            var slotStartHours = Caml_array.caml_array_get(openings, 0).starts.getHours();
            var slotStartMinutes = Caml_array.caml_array_get(openings, 0).starts.getMinutes();
            var slotEndsHours = Caml_array.caml_array_get(openings, 0).ends.getHours();
            var slotEndsMinutes = Caml_array.caml_array_get(openings, 0).ends.getMinutes();
            var starts = makeSlotTime(a.date, slotStartHours, slotStartMinutes);
            var ends = makeSlotTime(a.date, slotEndsHours, slotEndsMinutes);
            var init = Caml_array.caml_array_get(openings, 0);
            var currentEvent_kind = init.kind;
            var currentEvent_weekly_recurring = init.weekly_recurring;
            var currentEvent = {
              kind: currentEvent_kind,
              starts: starts,
              ends: ends,
              weekly_recurring: currentEvent_weekly_recurring
            };
            var newSlots = generateSlots(currentEvent);
            var hasAppointments = MomentRe.moment(undefined, makeYMD(a.date).toString()).isSame(MomentRe.moment(undefined, makeYMD(appointment.starts).toString()));
            if (isSaturday || !isInInterval) {
              return 0;
            } else if (hasAppointments) {
              return Caml_splice_call.spliceObjApply(a.slots, "push", [newSlots]);
            } else {
              var badSlots = generateApptSlots(/* () */0);
              var newSlotsFiltered = newSlots.filter((function (x) {
                      return !$$Array.mem(x, badSlots);
                    }));
              return Caml_splice_call.spliceObjApply(a.slots, "push", [newSlotsFiltered]);
            }
          }));
    return availabilities;
  }
  
  var db = Sqlite3$SlotsChallenge.Database.make("db.sqlite", undefined, undefined, undefined, true, /* () */0);
  
  function getAvailabilities(date) {
    return makeResult(db.prepare("select * from `events`").all(), date);
  }
  
  exports.dayToJs = dayToJs;
  exports.is = is;
  exports.isSaturday = isSaturday;
  exports.decodeEvent = decodeEvent;
  exports.makeYMD = makeYMD;
  exports.copy = copy;
  exports.toInt = toInt;
  exports.addDays = addDays;
  exports.addMinutes = addMinutes;
  exports.isWithinInterval = isWithinInterval;
  exports.makeInterval = makeInterval;
  exports.makeResult = makeResult;
  exports.db = db;
  exports.getAvailabilities = getAvailabilities;
  /* db Not a pure module */
  