import {
    get12HourTimeFormat,
    get12HourTimeMobileFormat,
    getDateFormat,
    getDateDifferenceInDays,
    calculateDuration,
    padTo2Digits,
    combineDateAndTime,
    addMinutes,
    shortTimeString,
} from "./date-helper";

describe("date-helper.js", () => {
    it("get12HourTimeMobileFormat should return time in expected 12 hour mobile format.", () => {
        // Define some sample times and their expected 12-hour formats
        const testCases = [
            { time: "00:00", expected: "12 AM" },
            { time: "01:23", expected: "1:23 AM" },
            { time: "11:59", expected: "11:59 AM" },
            { time: "12:00", expected: "12 PM" },
            { time: "13:45", expected: "1:45 PM" },
            { time: "23:59", expected: "11:59 PM" },
        ];
        // Loop through the test cases and call the function with each time
        for (let testCase of testCases) {
            // Call the function and store the result
            const result = get12HourTimeMobileFormat(testCase.time);
            // Assert that the result is equal to the expected 12-hour format
            expect(result).toEqual(testCase.expected);
        }
    });

    // Test if the function returns the correct 12-hour format for some sample times
    it("should return the correct 12-hour format", function () {
        // Define some sample times and their expected 12-hour formats
        const testCases = [
            { time: "00:00", expected: "12:00 AM" },
            { time: "01:23", expected: "1:23 AM" },
            { time: "11:59", expected: "11:59 AM" },
            { time: "12:00", expected: "12:00 PM" },
            { time: "13:45", expected: "1:45 PM" },
            { time: "23:59", expected: "11:59 PM" },
        ];
        // Loop through the test cases and call the function with each time
        for (let testCase of testCases) {
            // Call the function and store the result
            const result = get12HourTimeFormat(testCase.time);
            // Assert that the result is equal to the expected 12-hour format
            expect(result).toEqual(testCase.expected);
        }
    });

    it("getDateFormat should return date in the given format.", () => {
        // Arrange / Act
        const dateString = "2023-10-01";
        const dateParts = dateString.split("-");
        const date = new Date(dateParts[0], parseInt(dateParts[1]) - 1, dateParts[2]);
        const format = "yyyy-MM-dd";
        const formattedDate = getDateFormat(date, format);

        // Assert
        expect(formattedDate).toEqual("2023-10-01");
    });

    it("should return the correct difference in days", function () {
        // Define some sample dates and their expected differences
        const testCases = [
            { startDate: "2023-10-12", endDate: "2023-10-15", expected: 3 },
            { startDate: "2023-01-01", endDate: "2023-01-31", expected: 30 },
            { startDate: "2022-12-31", endDate: "2023-01-01", expected: 1 },
            { startDate: "2023-02-28", endDate: "2023-03-01", expected: 1 },
            { startDate: "2023-03-01", endDate: "2023-02-28", expected: -1 },
        ];
        // Loop through the test cases and call the function with each pair of dates
        for (let testCase of testCases) {
            // Call the function and store the result
            const result = getDateDifferenceInDays(testCase.startDate, testCase.endDate);
            // Assert that the result is equal to the expected difference
            expect(result).toEqual(testCase.expected);
        }
    });

    it("calculateDuration should return duration in hhmm format.", () => {
        // Arrange / Act
        const startDate = new Date("2023-10-01 10:00:00");
        const endDate = new Date("2023-10-01 23:00:00");
        const duration = calculateDuration(startDate, endDate);

        // Assert
        expect(duration).toEqual("1300");
    });

    it("padTo2Digits should return time in 2 digit format.", () => {
        // Define some sample time values and their expected strings
        const testCases = [
            { time: 0, expected: "00" },
            { time: 1, expected: "01" },
            { time: 9, expected: "09" },
            { time: 10, expected: "10" },
            { time: 59, expected: "59" },
        ];
        // Loop through the test cases and call the function with each time value
        for (let testCase of testCases) {
            // Call the function and store the result
            const result = padTo2Digits(testCase.time);
            // Assert that the result is equal to the expected string
            expect(result).toEqual(testCase.expected);
        }
    });

    it("combineDateAndTime should return combined dateTime format.", () => {
        // Define some sample inputs and their expected outputs
        const testCases = [
            { date: "2023-10-12", time: "12:00", expected: new Date(2023, 9, 12, 12, 0) },
            { date: "2023-01-01", time: "00:00", expected: new Date(2023, 0, 1, 0, 0) },
            { date: "2022-12-31", time: "23:59", expected: new Date(2022, 11, 31, 23, 59) },
            { date: "2023-02-28", time: "13:45", expected: new Date(2023, 1, 28, 13, 45) },
            { date: "2023-03-01", time: "01:23", expected: new Date(2023, 2, 1, 1, 23) },
        ];
        // Loop through the test cases and call the function with each pair of date and time
        for (let testCase of testCases) {
            // Call the function and store the result
            const result = combineDateAndTime(testCase.date, testCase.time);
            // Assert that the result is equal to the expected new date object
            expect(result.getTime()).toEqual(testCase.expected.getTime());
        }
    });

    it("addMinutes should add given time to date.", () => {
        // Define some sample inputs and their expected outputs
        const testCases = [
            {
                date: new Date(2023, 9, 12, 12, 0),
                minutes: 15,
                expected: new Date(2023, 9, 12, 12, 15),
            },
            {
                date: new Date(2023, 0, 1, 0, 0),
                minutes: -30,
                expected: new Date(2022, 11, 31, 23, 30),
            },
            {
                date: new Date(2022, 11, 31, 23, 59),
                minutes: 1,
                expected: new Date(2023, 0, 1, 0, 0),
            },
            {
                date: new Date(2023, 1, 28, 13, 45),
                minutes: 60,
                expected: new Date(2023, 1, 28, 14, 45),
            },
            {
                date: new Date(2023, 2, 1, 1, 23),
                minutes: -1440,
                expected: new Date(2023, 1, 28, 1, 23),
            },
        ];
        // Loop through the test cases and call the function with each pair of date and minutes
        for (let testCase of testCases) {
            // Call the function and store the result
            const result = addMinutes(testCase.date, testCase.minutes);
            // Assert that the result is equal to the expected modified date object
            expect(result.getTime()).toEqual(testCase.expected.getTime());
        }
    });

    it("shortTimeString should return time in short format.", () => {
        // Define some sample dates and their expected short time strings
        const testCases = [
            { date: new Date(2023, 9, 12, 12, 0), expected: "12:00 PM" },
            { date: new Date(2023, 0, 1, 0, 0), expected: "12:00 AM" },
            { date: new Date(2022, 11, 31, 23, 59), expected: "11:59 PM" },
            { date: new Date(2023, 1, 28, 13, 45), expected: "1:45 PM" },
            { date: new Date(2023, 2, 1, 1, 23), expected: "1:23 AM" },
        ];
        // Loop through the test cases and call the function with each date
        for (let testCase of testCases) {
            // Call the function and store the result
            const result = shortTimeString(testCase.date);
            // Assert that the result is equal to the expected short time string
            expect(result).toEqual(testCase.expected);
        }
    });
});
