"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = DatePickerWeek;
const contexts_1 = require("../../../contexts/index.js");
const web_1 = require("@react-spring/web");
const dayjs_1 = __importDefault(require("dayjs"));
const react_1 = __importStar(require("react"));
const react_use_gesture_1 = require("react-use-gesture");
const react_use_measure_1 = __importDefault(require("react-use-measure"));
const DatePickerDay_1 = __importDefault(require("./DatePickerDay"));
const Icon_1 = __importStar(require("../Icon/Icon"));
const Text_1 = require("../Text");
const CalendarHelper_1 = __importDefault(require("../../../util/CalendarHelper"));
const Color_1 = require("../../../util/Color");
const DataLayer_1 = __importStar(require("../../../util/DataLayer"));
const ScreenSize_1 = __importDefault(require("../../../util/ScreenSize"));
const TextAlignment_1 = require("../../../util/TextAlignment");
function DatePickerWeek() {
    var _a, _b;
    const dpContext = (0, react_1.useContext)(contexts_1.DatePickerContext);
    const context = (0, react_1.useContext)(contexts_1.BookingEngineContext);
    const showingMonth = (_b = (_a = dpContext.startDate) !== null && _a !== void 0 ? _a : dpContext.currentMonth) !== null && _b !== void 0 ? _b : (0, dayjs_1.default)().add(14, 'day');
    const scrollingOffset = 0;
    let sliderVelocity = 0;
    const [{ x }, set] = (0, web_1.useSpring)(() => ({ x: 0, config: { mass: 1, tension: 170, friction: 20 } }));
    const [lastReleaseX, setLastReleaseX] = (0, react_1.useState)(0);
    const [ref, bounds] = (0, react_use_measure_1.default)();
    const [daysLoaded, setDaysLoaded] = (0, react_1.useState)([]);
    const [lastDay, setLastDay] = (0, react_1.useState)(null);
    const [firstDay, setFirstDay] = (0, react_1.useState)((0, dayjs_1.default)());
    const [numberOfDaysLoaded, setNumberOfDaysLoaded] = (0, react_1.useState)(0);
    const [toggler, setToggler] = (0, react_1.useState)(false);
    (0, react_1.useEffect)(() => {
        setDaysLoaded(CalendarHelper_1.default.getDaysBetween((0, dayjs_1.default)(), showingMonth));
        if (dpContext.startDate) {
            setTimeout(() => {
                focusDay(dpContext.startDate);
            }, 500);
        }
    }, []);
    const setSwiperLocation = (location) => {
        if (location > 0) {
            location = 0;
        }
        set({ x: location });
        setLastReleaseX(location);
    };
    const focusDay = (toFocus) => {
        let index = 0;
        index = firstDay ? Math.abs(Number(toFocus.diff(firstDay, 'day'))) : Number(toFocus.format('DD'));
        const focus = -(62 * index);
        setSwiperLocation(focus);
    };
    const loadDataForDate = (forDate_1, ...args_1) => __awaiter(this, [forDate_1, ...args_1], void 0, function* (forDate, after = true) {
        if (forDate.isBefore((0, dayjs_1.default)())) {
            return;
        }
        setDaysLoaded((oldDaysLoaded) => {
            let newDaysLoaded = [];
            const newDays = after ? CalendarHelper_1.default.getWeekFrom(forDate) : CalendarHelper_1.default.getWeekTo(forDate);
            newDaysLoaded = after ? [...oldDaysLoaded, ...newDays] : [...newDays.reverse(), ...oldDaysLoaded];
            return newDaysLoaded;
        });
    });
    (0, react_1.useEffect)(() => {
        setLastDay(daysLoaded[daysLoaded.length - 1]);
        setFirstDay(daysLoaded[0]);
        setNumberOfDaysLoaded(daysLoaded.length);
    }, [daysLoaded]);
    (0, react_1.useEffect)(() => {
        if (62 * numberOfDaysLoaded - 1000 <= -lastReleaseX) {
            loadNext();
        }
    }, [lastReleaseX]);
    const loadNext = () => __awaiter(this, void 0, void 0, function* () {
        var _a;
        loadDataForDate((_a = daysLoaded[daysLoaded.length - 1]) !== null && _a !== void 0 ? _a : showingMonth.add(7, 'days'));
    });
    let lastIndex = 0;
    // Set the drag hook and define component movement based on gesture data
    const bind = (0, react_use_gesture_1.useDrag)(({ down, movement: [mx], velocity }) => {
        if (context.screenSize <= ScreenSize_1.default.Medium) {
            velocity = velocity * 0.75;
            sliderVelocity = velocity > 4 ? 4 : velocity < 1 ? 1 : velocity;
        }
        else {
            sliderVelocity = 1;
        }
        mx = mx * sliderVelocity;
        if (!down) {
            const releasePosition = lastReleaseX + mx;
            const cardWidth = 62;
            const maxX = numberOfDaysLoaded * cardWidth;
            let restingLocation = 0;
            if (releasePosition > 0) {
                restingLocation = 0;
            }
            else if (releasePosition < -maxX) {
                restingLocation = -maxX;
            }
            else {
                const magic = -releasePosition / cardWidth;
                lastIndex = releasePosition % cardWidth > -cardWidth / 2 ? Math.floor(magic) : Math.ceil(magic);
                restingLocation = -(lastIndex * cardWidth);
            }
            if (62 * numberOfDaysLoaded - 1000 <= -releasePosition) {
                loadNext();
            }
            set({ x: restingLocation });
            setLastReleaseX(restingLocation);
        }
        else {
            set({ x: lastReleaseX + mx });
        }
    });
    const days = (0, react_1.useMemo)(() => (react_1.default.createElement(react_1.default.Fragment, null, daysLoaded.map((date, index) => {
        const day = date.format('D');
        const unix = date.unix();
        return (react_1.default.createElement(react_1.default.Fragment, null,
            react_1.default.createElement(DatePickerDay_1.default, { key: unix, text: day, selectable: true, day: date, displayType: "week", unix: unix })));
    }))), [daysLoaded]);
    // TODO refactor
    const getCurrentDay = () => {
        const day = Math.floor(lastReleaseX / 62);
        if (firstDay) {
            return firstDay.add(-day, 'day').format('MMMM');
        }
        return showingMonth.format('MMMM');
    };
    const currentDayValue = getCurrentDay();
    const showPreviousWeek = () => {
        DataLayer_1.default.instance.sendInteraction('Show Previous Week', DataLayer_1.InteractionType.CALENDAR, DataLayer_1.InteractionStep.DATES);
        setSwiperLocation(lastReleaseX + 62 * 7);
    };
    const showNextWeek = () => {
        DataLayer_1.default.instance.sendInteraction('Show Next Week', DataLayer_1.InteractionType.CALENDAR, DataLayer_1.InteractionStep.DATES);
        setSwiperLocation(lastReleaseX - 62 * 7);
    };
    return (react_1.default.createElement(react_1.default.Fragment, null,
        react_1.default.createElement("div", { className: "diji-calendar-navigation" },
            react_1.default.createElement(Icon_1.default, { icon: Icon_1.IconType.ArrowLeft2, onClick: showPreviousWeek, color: Color_1.Color.White, backgroundColor: Color_1.Color.Navy, borderRadius: "round", size: "24px" }),
            react_1.default.createElement(Icon_1.default, { icon: Icon_1.IconType.ArrowRight2, onClick: showNextWeek, color: Color_1.Color.White, backgroundColor: Color_1.Color.Navy, borderRadius: "round", size: "24px" })),
        react_1.default.createElement("div", { className: "u-marg-top" },
            react_1.default.createElement(Text_1.Text, { type: Text_1.TextType.Body, bold: true, align: TextAlignment_1.TextAlign.Center }, currentDayValue)),
        react_1.default.createElement("div", { className: "diji-calendar-week--global-month" }, currentDayValue),
        react_1.default.createElement("div", { className: "diji-calendar-week" },
            react_1.default.createElement("div", Object.assign({ className: "diji-calendar-week--track" }, bind()),
                react_1.default.createElement(web_1.animated.div, { className: "diji-calendar-week--items", style: { left: x } }, days)))));
}
//# sourceMappingURL=DatePickerWeek.js.map