import { expect, type Locator, type Page } from '@playwright/test';
import { BasePage } from './BasePage';
import { ICustomerDetails, IVehicleDetails } from '@business-logic/types/CustomerDetails';
import { ServicePackage, PaymentType, PaymentMethod } from '@business-logic/types/Enums';
import { ITestData } from '@business-logic/types/ITestData';

export class OrderConfirmationPage extends BasePage {
    readonly page: Page;
    readonly serviceText: Locator;
    readonly emailText: Locator;
    readonly apptDateText: Locator;
    readonly amountDueText: Locator;
    readonly viewCartButton: Locator;
    readonly deductibleText: Locator;
    readonly subtotalText: Locator;
    readonly finalAmountDue: Locator;
    readonly cartServicePackageText: Locator;
    readonly winshieldWiper: Locator;
    readonly rainDefense: Locator;

    url = process.env['BASE_URL']! + '/fmg/?fmgPage=confirmation';

    constructor(page: Page) {
        super(page);
        this.page = page;
        this.serviceText = this.page.locator('p', {
            hasText: /to service your/
        });
        this.emailText = this.emailText = this.page.getByText('A confirmation email was sent');
        this.apptDateText = this.page.locator('[class="scheduleText"]');
        this.amountDueText = this.page.getByLabel('expand cart');
        this.viewCartButton = this.page.locator('#cart-dropdown-head');
        this.deductibleText = this.page.locator('#deductible-value');
        this.subtotalText = this.page.locator('.sub-total');
        this.finalAmountDue = this.page.locator('div.amount-due');
        this.cartServicePackageText = this.cartServicePackageText = this.page.locator('.cart-panel');
        // this.validateURL(this.url);
    }

    async validateOrderConfirmationPage(testData: Partial<ITestData>) {
        // Destructure data we use
        const { vehicleDetails, customerDetails, servicePackage, promoCode,
             isPolicyFound, claimDetails, paymentDetails, isUseVehicleOnPolicy, paymentMethod } = testData;
        await this.serviceText.waitFor({ state: "visible" });

        // Grab text
        const serviceTextValue = await this.serviceText.textContent();
        const apptDateValue = await this.apptDateText.textContent();
        const emailTextValue = await this.emailText.textContent();
        const servicePackageValue = await this.cartServicePackageText.textContent();
        const amountDueValue = await this.amountDueText.textContent();
        // const deductibleTextValue = await this.deductibleText.textContent();
        const subtotalTextValue = await this.subtotalText.textContent();
        const finalAmountDueValue = await this.finalAmountDue.textContent();

        // Extract service package price
        const servicePackageAmt = Number.parseFloat(servicePackageValue!.split('$')[1].replaceAll(',', ''));

        // General Validations
        expect.soft(serviceTextValue).toContain(`${vehicleDetails!.year} ${vehicleDetails!.make} ${vehicleDetails!.model}`);
        expect.soft(apptDateValue).toContain(customerDetails!.apptDate);
        expect.soft(emailTextValue).toContain(customerDetails!.email);

        // Service package validations
        await expect.soft(this.cartServicePackageText).toContainText(`${servicePackage}`)
        if (servicePackage === ServicePackage.Premium || servicePackage === ServicePackage.Standard) {
            expect.soft(servicePackageValue).toContain('New wiper blades');
        }
        if (servicePackage === ServicePackage.Premium) {
            expect.soft(servicePackageValue).toContain('Rain Defense™');
        }

        // Promo Code Validation
        if (promoCode) {
            expect.soft(servicePackageValue).toContain(`Promo code ${promoCode} applied`);
        };

        if (paymentMethod === PaymentMethod.SelfPay || (paymentDetails?.paymentType && paymentDetails?.paymentType !== PaymentType.PayWithInsurance)) {
            // Cart validation for non insurance users 
            // Extract numbers
            const amountDueAmt = Number.parseFloat(amountDueValue!.split('$')[1].replaceAll(',', ''));
            // const deductibleAmt = deductibleTextValue? Number.parseFloat(deductibleTextValue.split('$')[1].replaceAll(',', '')): 0;
            const subtotalAmt = Number.parseFloat(subtotalTextValue!.split('$')[1].replaceAll(',', ''));
            subtotalTextValue?.replaceAll(',', '')
            const finalAmountDueAmt = Number.parseFloat(finalAmountDueValue!.split('$')[1].replaceAll(',', ''));


            expect.soft(subtotalAmt).toBeGreaterThan(0);
            // expect.soft(deductibleAmt).toEqual(0);
            
            if (paymentDetails!.paymentType === PaymentType.PayAtService && (servicePackageAmt > 0)) {
                // Verify amount due > 0
                expect.soft(amountDueAmt).toBeGreaterThan(0);
                expect.soft(finalAmountDueAmt).toBeGreaterThan(0);
            } else {
                // Verify amount due 0
                expect.soft(amountDueAmt).toEqual(0);
                expect.soft(finalAmountDueAmt).toEqual(0);
            }
        } else {
            // Price validations for insurance users
            if (servicePackage === ServicePackage.GlassOnly) {
                expect.soft(servicePackageAmt).toEqual(0);
            } else {
                expect.soft(servicePackageAmt).toBeGreaterThan(0);
            }

            // Check for either "Verifying coverage" or "0.00" in price fields
            expect.soft(
                amountDueValue?.includes('Verifying coverage') || 
                amountDueValue?.includes('0.00')
            ).toBeTruthy();
            
            expect.soft(
                subtotalTextValue?.includes('Verifying coverage') || 
                subtotalTextValue?.includes('0.00')
            ).toBeTruthy();
            
            expect.soft(
                finalAmountDueValue?.includes('Verifying coverage') || 
                finalAmountDueValue?.includes('0.00')
            ).toBeTruthy();
        }
    }

    async logOrderNumber() {
        const sessionStorage = JSON.parse(await this.page.evaluate('sessionStorage.getItem(\'submittedState\')'));
        return sessionStorage.workOrderNumber;
    }
    
}