import TestCase from "@business-logic/types/TestCase";
import { Page } from "@playwright/test";
import { addSmokeTagToRandomTest, prepareTest, test, TestInfo } from "@business-logic/types/Test";
import { RuleEngine, ValidationOptions } from "@business-logic/types/RuleEngine";
import heavyTruckTests from "./alert-validation/alert0001_HeavyTruck";
import repairAndReplaceTests from "./alert-validation/alert0002_RepairAndReplace";
import splitWindshieldTests from "./alert-validation/alert0003_SplitWindshield";
import repairOnlyTests from "./alert-validation/alert0004_RepairOnly";
import unserviceableZipTests from "./alert-validation/alert0005_UnserviceableZip";
import invalidZipTests from "./alert-validation/alert0006_InvalidZip";
import vinNotFoundTests from "./alert-validation/alert0007_VinNotFound";
import TestSuccessAlert from "@business-logic/types/TestSuccessAlert";
import { AppointmentType, PaymentMethod, ServicePackage, VehicleLookupType, VehicleDamage, PaymentType } from "@business-logic/types/Enums";
import cashRepairMobileCCTests from "./CashRepairMobileCreditCard";
import cashReplaceDynamicRecalMobileTests from "./CashReplaceDynamicRecalMobile";
import cashReplaceGlassAddressLookupInshopAfterPayTests from "./CashReplaceGlassAddressLookupInshopAfterPay";
import cashReplaceGlassLicensePlateLookupInshopPaypalTests from "./CashReplaceGlassLicensePlateLookupInshopPaypal";
import ApiResponseInterceptUtil from "@impl/API/ApiResponseInterceptUtil";
import cashReplaceGlassPromoInshopTests from "./CashReplaceGlassPromoInshop";
import cashReplaceMultiGlassPromoInshopTests from "./CashReplaceMultiGlassPromoInshop";
import cashReplaceRainDefensePromoInshopTests from "./CashReplaceRainDefensePromoInshop";
import cashReplaceSafeliteCanNotRecalMobileTests from "./CashReplaceSafeliteCanNotRecalMobile";
import cashReplaceVinMobileTests from "./CashReplaceVinMobile";
import cashReplaceWiperDropoffTests from "./CashReplaceWiperDropoff";
import cashReplaceWiperPromoInShopTests from "./CashReplaceWiperPromoInshop";
import insuranceAcuityPaypalTests from "./InsuranceAcuityPaypal";
import insuranceITAC21stCenturyTests from "./InsuranceITAC21stCentury";
import insuranceGeicoTests from "./InsuranceGeico";
import insuranceITACOptimizedPriceValidationAllStateTests from "./InsuranceITACOptimizedPriceValidationAllState";
import cashRepairInShopAfterPayTests from "./CashRepairInShopAfterPay";
import cashRepairInShopPayPalTests from "./CashRepairInShopPayPal";
import cashReplaceMultiSlidingGlassDropoffTests from "./CashReplaceMultiSlidingGlassDropoff";
import cashReplaceMultiGlassMobileTests from "./CashReplaceMultiGlassMobile";

/**
 * Master Test Runner
 * 
 * This file orchestrates the execution of all test scenarios and defines the primary test workflow.
 * It imports all test cases and executes them through a common test runner function to ensure 
 * consistent behavior across different test scenarios.
 */

// Initialize shared rule engine and validation options
const ruleEngine = new RuleEngine<TestCase>();
const options = new ValidationOptions();

// Add smoke tag to selected tests for CI/CD pipelines
addSmokeTagToRandomTest(splitWindshieldTests);


// Standard test scenarios
const allStandardTests = [
    {name: "CashRepairMobileCreditCard", tests: cashRepairMobileCCTests},
    {name: "CashRepairInShopAfterPay", tests: cashRepairInShopAfterPayTests},
    {name: "CashRepairInShopPayPal", tests: cashRepairInShopPayPalTests},
    {name: "CashReplaceDynamicRecalMobile", tests: cashReplaceDynamicRecalMobileTests}, 
    {name: "CashReplaceGlassAddressLookupInshopAfterPay", tests: cashReplaceGlassAddressLookupInshopAfterPayTests},
    {name: "CashReplaceGlassLicensePlateLookupInshopPaypal", tests: cashReplaceGlassLicensePlateLookupInshopPaypalTests},
    {name: "CashReplaceGlassPromoInShop", tests: cashReplaceGlassPromoInshopTests},
    {name: "CashReplaceMultiGlassPromoInShop", tests: cashReplaceMultiGlassPromoInshopTests},
    {name: "CashReplaceMultiSlidingGlassDropoff",tests: cashReplaceMultiSlidingGlassDropoffTests},
    {name: "CashReplaceMultiGlassMobile",tests: cashReplaceMultiGlassMobileTests},
    {name: "CashReplaceRainDefensePromoInshop", tests: cashReplaceRainDefensePromoInshopTests},
    {name: "CashReplaceSafeliteCanNotRecalMobile", tests: cashReplaceSafeliteCanNotRecalMobileTests},
    {name: "CashReplaceVinMobile", tests: cashReplaceVinMobileTests},
    {name: "CashReplaceWiperDropoff", tests: cashReplaceWiperDropoffTests},
    {name: "CashReplaceWiperPromoInshop", tests: cashReplaceWiperPromoInShopTests},
    {name: "InsuranceAcuityPaypal", tests: insuranceAcuityPaypalTests},
    {name: "InsuranceITAC21stCentury", tests: insuranceITAC21stCenturyTests},
    // {name: "InsuranceGeico", tests: insuranceGeicoTests},
    // {name: "InsuranceITACOptimizedPriceValidationAllState", tests: insuranceITACOptimizedPriceValidationAllStateTests}

];

// Alert validation scenarios
const allAlertTests = [
    { name: "Alert Scenario 1: Heavy Truck", tests: heavyTruckTests },
    { name: "Alert Scenario 2: Repair and Replace", tests: repairAndReplaceTests },
    { name: "Alert Scenario 3: Split Windshield", tests: splitWindshieldTests },
    { name: "Alert Scenario 4: Repair Only", tests: repairOnlyTests },
    { name: "Alert Scenario 5: Unserviceable Zip", tests: unserviceableZipTests },
    { name: "Alert Scenario 6: Invalid Zip", tests: invalidZipTests },
    { name: "Alert Scenario 7: VIN Not Found", tests: vinNotFoundTests }
];

// Standard test cases
test.describe.parallel('Standard E2E Test Flows', () => {
    allStandardTests.forEach(scenario => {
        scenario.tests.forEach(testCase => {
            test(...prepareTest(testCase, run, options, ruleEngine));
        });
    });
});

// Alert validation test cases
test.describe.parallel('Alert Validation Tests', () => {
    allAlertTests.forEach(scenario => {
        test.describe(scenario.name, () => {
            scenario.tests.forEach(testCase => {
                test(...prepareTest(testCase, run, options, ruleEngine));
            });
        });
    });
});


/**
 * After each test, capture screenshot and handle cleanup
 */
test.afterEach(async ({ page, testInfo }) => {
    await TestCase.afterEachMethod(page, testInfo);
});

/**
 * Main test runner function that executes each test case
 * @param page - The Playwright page object
 * @param testInfo - Test information and context
 */
async function run(page: Page, testInfo: TestInfo): Promise<void> {
    try {
        await testInfo.testCase.setup();
        testInfo.testCase.setupPages(page);
        await testInfo.testCase.pages.homePage.goto();
        await runWorkflow(page, testInfo.testCase);
    } catch (error) {
        // Catch successful alert tests and log message
        if (error instanceof TestSuccessAlert) {
            console.log(error.message);
        // Catch and throw other errors
        } else {
            throw error;
        }
    }
}

/**
 * Main workflow that executes the test steps in sequence
 * 
 * This function contains the common test flow for all test scenarios:
 * 1. Start at home page and enter vehicle/damage information
 * 2. Select lookup method and provide details
 * 3. Answer part questions if applicable
 * 4. Select service package and payment method
 * 5. Handle insurance flow if applicable
 * 6. Select service location and schedule appointment
 * 7. Complete order and validate confirmation
 * 
 * @param page - The Playwright page object
 * @param testCase - The test case to execute
 */
async function runWorkflow(page: Page, testCase: TestCase) {

    // Intercept API Responses
    const apiResponseInterceptUtil = new ApiResponseInterceptUtil(testCase.testData);
    page.on('response', apiResponseInterceptUtil.handleInterceptResponse);

    // Destructure test data for easier access
    const { 
        servicePackage, paymentMethod, customerDetails, vehicleDetails, vehicleDamage,
        appointmentDetails, paymentDetails, claimDetails, partQuestions, enterFunnelWithZip,
        capabilityQuestions, vehiclePartQuestions, moldingQuestions, isPolicyFound,
        otherVehiclesOnPolicy, isUseVehicleOnPolicy, isDuplicateClaim, isRecalNotification,
        alertFlags, endorsements, isPolicyDriver, skipEstimatePage, isRecalVehicle, canNotRecal,
        dynamicRecal, hasOemEndorsement, promoCode
     } = testCase.testData;

    // Destructure alert flag data
    const { 
        isHeavyTruckVehicle, isRepairReplace, isSplitWindshield, isRepairOnly,
        isUnserviceableZip, isInvalidZip, isVinNotFound
    } = testCase.testData.alertFlags || {};

    // Define repair damage types (vs. replacement types)
    const repairTypes: VehicleDamage[] = [
        VehicleDamage.WindshieldOneChip,
        VehicleDamage.WindshieldTwoChips,
        VehicleDamage.WindshieldThreeChips
    ];

    // Determine if we're replacing or repairing
    const isReplace = !repairTypes.some(damageType => {
        return vehicleDamage!.includes(damageType);
    });

    // Check if the insurance policy has endorsements
    const hasEndorsements = endorsements && endorsements.length > 0;

    // Check if the vehicle damage includes a windshield crack
    const hasWindshieldCrack = vehicleDamage!.some(damage => 
        damage === VehicleDamage.WindshieldCrack
    );

    //============================= TEST WORKFLOW STEPS =============================

    // Use Environment Variable to decide whether or not we want to skip content site aka home page

    if (process.env.SKIP_CONTENT_SITE == "false") {    
        await test.step('HomePage >> Lets Get Started', async () => {
            let homePage = testCase.pages.homePage;
            console.log(`Customer for this test: ${customerDetails?.firstName} ${customerDetails?.lastName}`);
            await homePage.letsGetStarted(customerDetails?.address.postalCode!, !!enterFunnelWithZip!);
        });
    } else {
        // If enterFunnelWithZip is true, add zip code to url
        if (!!enterFunnelWithZip!) {
            const currentUrl = page.url();
            const zipParam = `&zipCode=${customerDetails?.address.postalCode!}`;
            if (!currentUrl.includes('zipCode=')) {
                await page.goto(currentUrl + zipParam);
            }
        }
        console.log(`Customer for this test: ${customerDetails?.firstName} ${customerDetails?.lastName}`);
    }


    await test.step('VehicleSelectionPage >> Select Vehicle', async () => {
        let vehicleSelectionPage = testCase.pages.vehicleSelectionPage;
        await vehicleSelectionPage.selectVehicle(vehicleDetails!);
        
        // Handle alert conditions for vehicle selection
        if (isHeavyTruckVehicle || isSplitWindshield) {
            await vehicleSelectionPage.checkForAlertMessages();
            throw new TestSuccessAlert('Both assertions are met successfully.');
        }
        
        await vehicleSelectionPage.nextPage();
    });

    await test.step('VehicleDamagePage >> Select Damage', async () => {
        let vehicleDamagePage = testCase.pages.vehicleDamagePage;
        await vehicleDamagePage.selectDamage(vehicleDamage!);
        
        // Handle alert conditions for vehicle damage
        if (isRepairReplace) {
            await vehicleDamagePage.checkForBothRepairReplaceAlertMessage();
            throw new TestSuccessAlert('Both assertions are met successfully.');
        }
        if (isRepairOnly) {
            await vehicleDamagePage.checkForRepairOnlyAlertMessage();
            throw new TestSuccessAlert('Both assertions are met successfully.');
        }
        
        await vehicleDamagePage.nextPage();
    });

    // If the vehicle has a windshield crack as part of its damage, go to estimate page and select lookup type
    if (hasWindshieldCrack && !skipEstimatePage) {
        await test.step('EstimatePage >> Select Lookup Type', async () => {
            let estimatePage = testCase.pages.estimatePage;
            await estimatePage.vehicleLookup(vehicleDetails!);
        });
    
        // Handle different vehicle lookup methods
        switch (vehicleDetails!.vehicleLookupType!) {
            case VehicleLookupType.Address:
                await test.step('VehicleLookupAddressPage >> Lookup by address: ' + customerDetails!.address.street, async () => {
                    let vehicleLookupAddressPage = testCase.pages.vehicleLookupAddressPage;
                    await vehicleLookupAddressPage.lookupVehicleByAddress(customerDetails!, vehicleDetails!);
                    await vehicleLookupAddressPage.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
                });
                break;
                
            case VehicleLookupType.LicensePlateNumber:
                await test.step('VehicleLookupLicensePage >> Lookup by license plate: ' + vehicleDetails!.licensePlateNumber, async () => {
                    let vehicleLookupLicensePage = testCase.pages.vehicleLookupLicensePage;
                    await vehicleLookupLicensePage.enterPlateDetails(vehicleDetails!);
                    await vehicleLookupLicensePage.enterZip(customerDetails!.address.postalCode!);
                    await vehicleLookupLicensePage.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
                });
                break;
                
            case VehicleLookupType.Vin:
                await test.step('VinLookupPage >> Lookup by VIN: ' + vehicleDetails!.vin!, async () => {
                    let vinLookupPage = testCase.pages.vinLookupPage;
                    await vinLookupPage.enterVin(vehicleDetails!.vin!);
                    await vinLookupPage.enterZip(customerDetails!.address.postalCode!);
                    await vinLookupPage.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
                });
                break;
                
            case VehicleLookupType.Zip:
                await test.step('ZipLookupPage >> Lookup by service ZIP: ' + customerDetails!.address.postalCode!, async () => {
                    let zipLookupPage = testCase.pages.zipLookupPage;
                    let vinLookupPage = testCase.pages.vinLookupPage;
                    await vinLookupPage.enterZip(customerDetails!.address.postalCode!);
                    await zipLookupPage.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
                });
        }
    } else {
        // Otherwise just use zip lookup
        await test.step('ZipLookupPage >> Lookup by service ZIP: ' + customerDetails!.address.postalCode!, async () => {
            let zipLookupPage = testCase.pages.zipLookupPage;
            let vinLookupPage = testCase.pages.vinLookupPage;
            await vinLookupPage.enterZip(customerDetails!.address.postalCode!);
            await zipLookupPage.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
        });
    }

    // Handle part questions if applicable
    if (partQuestions && partQuestions.length > 0) {
        await test.step('PartQuestionsPage >> Select Vehicle Part Question Responses', async () => {
            let partQuestionsPage = testCase.pages.partQuestionsPage;
            await partQuestionsPage.validatePartQuestions(partQuestions);
            await partQuestionsPage.selectPartQuestionResponses(partQuestions);
            await partQuestionsPage.nextPage();
        });
    }
    
    // Handle molding questions if applicable
    if (moldingQuestions && moldingQuestions.length > 0) {
        await test.step('MoldingQuestionsPage >> Select Molding Question Responses', async () => {
            let moldingQuestionsPage = testCase.pages.moldingQuestionsPage;
            await moldingQuestionsPage.validatePartQuestions(moldingQuestions);
            await moldingQuestionsPage.selectPartQuestionResponses(moldingQuestions);
            await moldingQuestionsPage.nextPage();
        });
    }

    // Handle vehicle part questions if applicable
    if (vehiclePartQuestions && vehiclePartQuestions.length > 0) {
        await test.step('VehiclePartsPage >> Select Vehicle Part Responses', async () => {
            let vehiclePartsPage = testCase.pages.vehiclePartsPage;
            await vehiclePartsPage.validatePartQuestions(vehiclePartQuestions);
            await vehiclePartsPage.selectPartQuestionResponses(vehiclePartQuestions);
            await vehiclePartsPage.nextPage();
        });
    }

    // Handle capability questions if applicable
    if (capabilityQuestions && capabilityQuestions.length > 0) {
        await test.step('CapabilityQuestionsPage >> Select Capability Question Responses', async () => {
            let capabilityQuestionsPage = testCase.pages.capabilityQuestionsPage;
            await capabilityQuestionsPage.validatePartQuestions(capabilityQuestions);
            await capabilityQuestionsPage.selectPartQuestionResponses(capabilityQuestions);
            await capabilityQuestionsPage.nextPage();
        });
    }

    // Select service package and payment method
    await test.step('ServicePackagePage >> Select Payment Method and Service Type', async() => {
        let servicePackagePage = testCase.pages.servicePackagePage;
        await servicePackagePage.handleQuotePopup(customerDetails!.email!);
        await servicePackagePage.selectPaymentMethod(paymentMethod!);
        await servicePackagePage.selectServicePackage(servicePackage!);
        // Enter promo code
        if (promoCode) {
            await servicePackagePage.enterPromo(promoCode);
        }

        // Backend Validations
        // Validate backend for can not recal if applicable
        if (canNotRecal) {
            await servicePackagePage.verifyCanNotRecal();
        }
        // Validate backend for dynamic recal if applicable
        if (dynamicRecal) {
            await servicePackagePage.verifyDynamicRecal();
        }
        // Validate backend for repair info (including chip verification)
        await servicePackagePage.verifyIsRepair(!isReplace, vehicleDamage!);
        if (isReplace) {
            // Validate backend for parts info
            await servicePackagePage.verifyVehicleParts(vehicleDamage!);
        }
        // Validate backend for OEM endorsement
        if (hasOemEndorsement) {
            await servicePackagePage.verifyOEMPart();
        }

        await servicePackagePage.nextPage();
    }); 

    //============================= INSURANCE FLOW =============================`   
    
    // Insurance flow - if user selected Insurance as Payment Method
    if (paymentMethod == PaymentMethod.Insurance) {
        await test.step('InsuranceCoveragePage >> Select your insurance', async() => {
            let insuranceCompanyPage = testCase.pages.insuranceCompanyPage;
            await insuranceCompanyPage.enterInsuranceCompany(claimDetails!.client!);
            await insuranceCompanyPage.nextPage();
        });

        await test.step('CCPolicyInfoPage >> Fill out claim information', async() => {
            let ccPolicyInfoPage = testCase.pages.ccPolicyInfoPage;
            await ccPolicyInfoPage.populatePage(customerDetails!, claimDetails!, await ccPolicyInfoPage.hasCityInfo());
            await ccPolicyInfoPage.nextPage();
        });

        // Handle duplicate claim case if applicable
        if (isDuplicateClaim) {
            await test.step('DuplicateCheckPage >> Start New Claim', async () => {
                let duplicateCheckPage = testCase.pages.duplicateCheckPage;
                await duplicateCheckPage.startNewClaim();
                await duplicateCheckPage.nextPage();
            });
        }

        // Handle policy found vs. not found flows
        if (isPolicyFound) {
            await test.step('PolicyVehiclesPage >> Select vehicle', async () => {
                let policyVehiclesPage = testCase.pages.policyVehiclesPage;
                let vehicleSelectionPage = testCase.pages.vehicleSelectionPage;
                
                // Validate other vehicles on policy
                if (otherVehiclesOnPolicy && otherVehiclesOnPolicy.length > 0) {
                    for (const vehicle of otherVehiclesOnPolicy) {
                        await policyVehiclesPage.validateVehicleIsOnPolicy(vehicle);
                    }
                }
                
                // If vehicle is not on the policy, select new vehicle
                if (!(isUseVehicleOnPolicy ?? true)) {
                    await policyVehiclesPage.selectVehicleNotListed();
                    await policyVehiclesPage.nextPage();
                    await vehicleSelectionPage.selectVehicle(vehicleDetails!);
                    await policyVehiclesPage.nextPage();
                } else {
                    // Otherwise, select the vehicle entered in Safelite.com
                    await policyVehiclesPage.selectVehicle(vehicleDetails!);
                    await policyVehiclesPage.nextPage();
                }
            });
            
            // Handle policy driver selection if applicable
            if (isPolicyDriver) {
                await test.step('PolicyDriverPage >> Confirm Driver at time of damage', async () => {
                    let policyDriverPage = testCase.pages.policyDriverPage;
                    await policyDriverPage.selectPolicyDriver(customerDetails!);
                    await policyDriverPage.nextPage();
                });
            }
    
            // Handle endorsements if applicable
            if (hasEndorsements) {
                await test.step('EndorsementsPage >> Select Endorsements', async () => {
                    let endorsementsPage = testCase.pages.endorsementsPage;
                    await endorsementsPage.verifyEndorsements(endorsements);
                    await endorsementsPage.selectEndorsements(endorsements);
                    await endorsementsPage.nextPage();
                });
            }
        } else {
            // Policy not found flow
            await test.step('VerifyDetailsPage >> Verify Details', async () => {
                let verifyDetailsPage = testCase.pages.verifyDetailsPage;
                await verifyDetailsPage.verifyPolicyDetails(customerDetails!, claimDetails!);
                await verifyDetailsPage.nextPage();
            });
        }

        // Continue with the insurance flow after policy information
        await test.step('PolicyInfoSubmittedPage >> Continue With Safelite Autoglass', async () => {
            let policyInfoSubmittedPage = testCase.pages.policyInfoSubmittedPage;
            await policyInfoSubmittedPage.verifyPolicyInfoSubmitted();
            await policyInfoSubmittedPage.nextPage();
        });

        // Handle recalibration notification if applicable
        if (isRecalNotification) {
            await test.step('RecallibrationInfoPage >> Continue With Recalibration Information', async () => {
                let recalibrationInfoPage = testCase.pages.recalibrationInfoPage;
                await recalibrationInfoPage.nextPage();
            });
        }

        // Continue to coverage statement
        await test.step('CoverageStatementPage >> Next page', async () => {
            let coverageStatementPage = testCase.pages.coverageStatementPage;
            await coverageStatementPage.validateDeductibleAmount(claimDetails!);
            await coverageStatementPage.nextPage();
        });
    }

    //============================= SERVICE SCHEDULING =============================
    
    // Select service location
    await test.step('ServiceLocationPage >> Select service location', async () => {
        let serviceLocationPage = testCase.pages.serviceLocationPage;
        await serviceLocationPage.selectLocation(appointmentDetails!);
        await serviceLocationPage.nextPage();
    });

    // Schedule appointment
    await test.step('SchedulePage >> Select day and time', async () => {
        let schedulePage = testCase.pages.schedulePage;
        customerDetails!.apptDate! = await schedulePage.scheduleFirstAppointment(appointmentDetails!.serviceLocation);
    });

    // Enter contact details
    await test.step('ContactDetailsPage >> Enter contact details', async () => {
        let contactDetailsPage = testCase.pages.contactDetailsPage;
        await contactDetailsPage.enterContactDetails(customerDetails!);
        await contactDetailsPage.nextPage();
    });

    //============================= PAYMENT PROCESSING =============================
    
    // Handle payment
    await test.step('PaymentMethodPage >> Execute Payment', async () => {
        let paymentMethodPage = testCase.pages.paymentMethodPage;
        await paymentMethodPage.validatePaymentDetailsPage(testCase.testData);
        // Verify VAPS wipers on backend for standard and premium packages
        if (servicePackage === ServicePackage.Standard || servicePackage === ServicePackage.Premium) {
            await paymentMethodPage.verifyVAPS();
        }
        if (paymentDetails?.paymentType) {
            await paymentMethodPage.executePayment(paymentDetails!, isRecalVehicle!);
        } else {
            await paymentMethodPage.nextPage();
        }
    });

    // If user selected Pay with Insurance as Payment Method, Enter Insurance Flow
    if (paymentDetails?.paymentType === PaymentType.PayWithInsurance) {
        await test.step('InsuranceCoveragePage >> Select your insurance', async() => {
            let insuranceCompanyPage = testCase.pages.insuranceCompanyPage;
            await insuranceCompanyPage.enterInsuranceCompany(claimDetails!.client!);
            await insuranceCompanyPage.nextPage();
        });

        await test.step('CCPolicyInfoPage >> Fill out claim information', async() => {
            const ccPolicyInfoPage = testCase.pages.ccPolicyInfoPage;
            await ccPolicyInfoPage.populatePage(customerDetails!, claimDetails!, await ccPolicyInfoPage.hasCityInfo());
            await ccPolicyInfoPage.nextPage();
        });

        // Handle duplicate claim case if applicable
        if (isDuplicateClaim) {
            await test.step('DuplicateCheckPage >> Start New Claim', async () => {
                const duplicateCheckPage = testCase.pages.duplicateCheckPage;
                await duplicateCheckPage.startNewClaim();
                await duplicateCheckPage.nextPage();
            });
        }

        // Handle policy found vs. not found flows
        if (isPolicyFound) {
            await test.step('PolicyVehiclesPage >> Select vehicle', async () => {
                const policyVehiclesPage = testCase.pages.policyVehiclesPage;
                const vehicleSelectionPage = testCase.pages.vehicleSelectionPage;
                
                // Validate other vehicles on policy
                if (otherVehiclesOnPolicy && otherVehiclesOnPolicy.length > 0) {
                    for (const vehicle of otherVehiclesOnPolicy) {
                        await policyVehiclesPage.validateVehicleIsOnPolicy(vehicle);
                    }
                }
                
                // If vehicle is not on the policy, select new vehicle
                if (!(isUseVehicleOnPolicy ?? true)) {
                    await policyVehiclesPage.selectVehicleNotListed();
                    await policyVehiclesPage.nextPage();
                    await vehicleSelectionPage.selectVehicle(vehicleDetails!);
                    await policyVehiclesPage.nextPage();
                } else {
                    // Otherwise, select the vehicle entered in Safelite.com
                    await policyVehiclesPage.selectVehicle(vehicleDetails!);
                    await policyVehiclesPage.nextPage();
                }
            });
            
            // Handle policy driver selection if applicable
            if (isPolicyDriver) {
                await test.step('PolicyDriverPage >> Confirm Driver at time of damage', async () => {
                    const policyDriverPage = testCase.pages.policyDriverPage;
                    await policyDriverPage.selectPolicyDriver(customerDetails!);
                    await policyDriverPage.nextPage();
                });
            }
    
            // Handle endorsements if applicable
            if (hasEndorsements) {
                await test.step('EndorsementsPage >> Select Endorsements', async () => {
                    const endorsementsPage = testCase.pages.endorsementsPage;
                    await endorsementsPage.verifyEndorsements(endorsements);
                    await endorsementsPage.selectEndorsements(endorsements);
                    await endorsementsPage.nextPage();
                });
            }
        } else {
            // Policy not found flow
            await test.step('VerifyDetailsPage >> Verify Details', async () => {
                const verifyDetailsPage = testCase.pages.verifyDetailsPage;
                await verifyDetailsPage.verifyPolicyDetails(customerDetails!, claimDetails!);
                await verifyDetailsPage.nextPage();
            });
        }

        // Continue with the insurance flow after policy information
        await test.step('PolicyInfoSubmittedPage >> Continue With Safelite Autoglass', async () => {
            const policyInfoSubmittedPage = testCase.pages.policyInfoSubmittedPage;
            await policyInfoSubmittedPage.verifyPolicyInfoSubmitted();
            await policyInfoSubmittedPage.nextPage();
        });

        // Handle recalibration notification if applicable
        if (isRecalNotification) {
            await test.step('RecallibrationInfoPage >> Continue With Recalibration Information', async () => {
                const recalibrationInfoPage = testCase.pages.recalibrationInfoPage;
                await recalibrationInfoPage.nextPage();
            });
        }

        // Continue to coverage statement
        await test.step('CoverageStatementPage >> Next page', async () => {
            const coverageStatementPage = testCase.pages.coverageStatementPage;
            await coverageStatementPage.validateDeductibleAmount(claimDetails!);
            await coverageStatementPage.nextPage();
        });
    }

    //============================= ORDER CONFIRMATION =============================
    
    // Validate order confirmation
    await test.step('OrderConfirmationPage >> Validate order', async () => {
        let orderConfirmationPage = testCase.pages.orderConfirmationPage;
        await orderConfirmationPage.validateOrderConfirmationPage(testCase.testData);
    });

    // Get the order number and wrap it in a test step
    const workOrderNumber = await testCase.pages.orderConfirmationPage.logOrderNumber();
    await test.step(`Session Storage Work Order Number: ${workOrderNumber}`, async () => {
        console.log(`Session Storage Work Order Number: ${workOrderNumber}`);
    });
}