"use strict";
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());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.selectAvailableDates = selectAvailableDates;
exports.proceedToConfirmationStep = proceedToConfirmationStep;
exports.fillContactInfo = fillContactInfo;
exports.fillPaymentInformation = fillPaymentInformation;
exports.submitBookingReservation = submitBookingReservation;
exports.verifyBookingConfirmation = verifyBookingConfirmation;
const test_1 = require("@playwright/test");
function selectAvailableDates(page_1) {
    return __awaiter(this, arguments, void 0, function* (page, maxRetries = 5) {
        for (let attempt = 0; attempt < maxRetries; attempt++) {
            // Choose the first available check-in date.
            const checkInDateElement = page.locator('.diji-calendar-month--item.--selectable').first();
            yield (0, test_1.expect)(checkInDateElement).toBeVisible();
            yield checkInDateElement.click();
            let checkOutDateElement;
            if (attempt === maxRetries - 1) {
                // If this is the last attempt, try a 1-night stay (this has a higher success rate).
                checkOutDateElement = page.locator('.diji-calendar-month--item.--selectable:not(.--selected)').first();
            }
            else {
                // Choose a random available check-out date.
                const checkOutDateElements = yield page.locator('.diji-calendar-month--item.--selectable:not(.--selected)').all();
                const randomIndex = Math.floor(Math.random() * checkOutDateElements.length);
                checkOutDateElement = checkOutDateElements[randomIndex];
            }
            yield (0, test_1.expect)(checkOutDateElement).toBeVisible();
            yield checkOutDateElement.click();
            // TODO: Instead of waiting for timeout, wait for the loading indicators on the other dates to disappear.
            // Context: After choosing checkout date, the loading indicators appear for the dates following the checkout
            // date. If we click 'Check Availability', we seem to briefly see an error message. This doesn't actually
            // make the tests fail though. Keeping this in here in case it's indicative of an issue with RoomStay itself.
            // The error is an "Oh no, something went wrong" message and shows the select room bar without any dates in it.
            // The error quickly goes away though.
            yield page.waitForTimeout(500);
            // Click the 'Check Availability' button.
            const checkAvailabilityButton = page.getByRole('button', { name: 'Check Availability' });
            yield (0, test_1.expect)(checkAvailabilityButton).not.toBeDisabled();
            yield checkAvailabilityButton.click();
            // Check for error message.
            const errorMessage = yield page.waitForSelector('text=Please check your dates and', { timeout: 1000 }).catch(() => null);
            if (errorMessage) {
                console.log(`Error message found on attempt ${attempt + 1}. Retrying with different dates.`);
                const newSearchButton = page.getByRole('button', { name: 'New Search' });
                yield (0, test_1.expect)(newSearchButton).toBeVisible();
                yield newSearchButton.click();
            }
            else {
                return true;
            }
        }
        return false;
    });
}
function proceedToConfirmationStep(page) {
    return __awaiter(this, void 0, void 0, function* () {
        // Click the 'View Rates' button.
        const viewRatesNowButton = page.getByRole('button', { name: 'View rates now' }).first();
        yield (0, test_1.expect)(viewRatesNowButton).toBeVisible();
        yield (0, test_1.expect)(viewRatesNowButton).not.toBeDisabled();
        yield viewRatesNowButton.click();
        // Click the first 'Book Now' button.
        const firstBookNowButton = page.getByRole('button', { name: 'Book Now' }).first();
        yield (0, test_1.expect)(firstBookNowButton).toBeVisible();
        yield firstBookNowButton.click();
        // Confirm that the 'Added xx' toast notification is visible.
        // TOODO: Sometimes there are two notifications, but I can only reproduce this in Playwright.
        const addedRoomNotification = page.locator('.c-notification__inner').first();
        yield (0, test_1.expect)(addedRoomNotification).toBeVisible();
        yield (0, test_1.expect)(addedRoomNotification).toContainText('Added');
        // A bit hacky... Need a better way to check the current step.
        try {
            const isAddonsStep = yield page.waitForSelector('.step-selector__item.is-current p.text-body:has-text("Add-Ons")', { timeout: 1000 });
            if (isAddonsStep) {
                const nextButton = page.getByRole('button', { name: 'Next Step' }).first();
                yield (0, test_1.expect)(nextButton).toBeVisible();
                yield nextButton.click();
            }
        }
        catch (error) {
            console.log('Add-ons step not found, continuing.');
        }
        const confirmReservationButton = page.getByRole('button', { name: 'Confirm Reservation' });
        yield (0, test_1.expect)(confirmReservationButton).toBeVisible();
        yield (0, test_1.expect)(confirmReservationButton).toHaveText('Confirm Reservation');
    });
}
function fillContactInfo(page, data) {
    return __awaiter(this, void 0, void 0, function* () {
        // Fill Contact Info fields
        yield page.fill('input[name="userProfiles.0.Forename"]', data.firstName);
        yield page.fill('input[name="userProfiles.0.Surname"]', data.lastName);
        yield page.fill('input[name="userProfiles.0.Email"]', data.email);
        yield page.fill('input[name="userProfiles.0.Phone"]', data.phone);
        yield page.fill('input[name="userProfiles.0.Address"]', data.address);
        yield page.fill('input[name="userProfiles.0.City"]', data.city);
        yield page.fill('input[name="userProfiles.0.PostCode"]', data.zipCode);
        // Country selector
        yield page.fill('.rs-enhanced-country-field--search input', data.country);
        yield page.waitForSelector('.rs-enhanced-country-field--suggest-list-country', { state: 'visible' });
        yield page.click('.rs-enhanced-country-field--suggest-list-country-name'); // Assuming there's only one result...
    });
}
function fillPaymentInformation(page, data) {
    return __awaiter(this, void 0, void 0, function* () {
        // Fill Payment Information. Each of these fields is within their own secure iframe that we need to enter first.
        const cardNumberFrame = yield (yield page.waitForSelector('iframe[title="Secure card number input frame"]')).contentFrame();
        if (cardNumberFrame) {
            yield cardNumberFrame.fill('input[aria-label="Card Number Input"]', data.cardNumber);
        }
        const cardExpiryFrame = yield (yield page.waitForSelector('iframe[title="Secure card expiration date input frame"]')).contentFrame();
        if (cardExpiryFrame) {
            yield cardExpiryFrame.fill('input[aria-label="Card expiration date"]', data.cardExpiry);
        }
        const cardCvvFrame = yield (yield page.waitForSelector('iframe[title="Secure card security code input frame"]')).contentFrame();
        if (cardCvvFrame) {
            yield cardCvvFrame.fill('input[aria-label="Card Security Code"]', data.cardCVC);
        }
        const cardNameFrame = yield (yield page.waitForSelector('iframe[title="Secure text input frame"]')).contentFrame();
        if (cardNameFrame) {
            yield cardNameFrame.fill('input[aria-label="Text input"]', `${data.firstName} ${data.lastName}`);
        }
    });
}
function submitBookingReservation(page) {
    return __awaiter(this, void 0, void 0, function* () {
        const confirmReservationButton = page.getByRole('button', { name: 'Confirm Reservation' });
        yield (0, test_1.expect)(confirmReservationButton).toBeVisible();
        yield confirmReservationButton.click();
    });
}
function verifyBookingConfirmation(page, data) {
    return __awaiter(this, void 0, void 0, function* () {
        // We should now be on the 'Thanks' step.
        yield page.waitForSelector('.step-selector__item.is-current p.text-body:has-text("Thanks")', { timeout: 5000 });
        // There should be a message thanking us for our booking.
        const thankYouMessage = page.locator('h3:has-text("Thank you")');
        yield (0, test_1.expect)(thankYouMessage).toBeVisible();
        // Click the 'More Details' button to show a modal with our booking details.
        const moreDetailsButton = page.getByRole('button', { name: 'More Details' });
        yield (0, test_1.expect)(moreDetailsButton).toBeVisible();
        yield moreDetailsButton.click();
        const modal = page.locator('div[class*="roomstay-modal"]').first();
        yield (0, test_1.expect)(modal).toBeVisible();
        // The modal should contain our name and email address.
        yield (0, test_1.expect)(modal.locator(`text=${data.firstName} ${data.lastName}`)).toBeVisible();
        yield (0, test_1.expect)(modal.locator(`text=${data.email}`)).toBeVisible();
        // Close the modal.
        const closeButton = modal.locator('i[name="Close"]');
        yield closeButton.click();
    });
}
//# sourceMappingURL=checkoutHelpers.js.map