import { type Locator, type Page, expect } from '@playwright/test';
import { BasePage } from './BasePage';
import TestSuccessAlert from '@business-logic/types/TestSuccessAlert';
import IAlertFlags from '@business-logic/types/IAlertFlags';
import { VehicleLookupType } from '@business-logic/types/Enums';

export class LookupPage extends BasePage {
    protected serviceZipTextBox: Locator;
    protected emailTextBox: Locator;
    protected unserviceableZipAlertMessage: Locator;
    protected invalidZipAlertMessage: Locator;
    protected vinNotFoundAlertMessage: Locator;

    constructor(page: Page) {
        super(page);
        this.initializeLocators(page);
    }

    protected initializeLocators(page: Page) {
        this.serviceZipTextBox = page.getByRole('textbox', { name: 'Service ZIP' });
        this.emailTextBox = page.getByRole('textbox', { name: 'Mobile phone number or email' });
        this.unserviceableZipAlertMessage = this.page.locator('div.alert-danger.widget-name-widgetUndefined', { hasText: "We don't currently provide service within " });
        this.invalidZipAlertMessage = this.page.getByText('ZIP code is not valid.Please');
        this.vinNotFoundAlertMessage = this.page.locator('div.alert-danger.widget-name-AlertVinNotFoundWidget');
    }

    async enterZip(zip: string) {
        await this.serviceZipTextBox.fill(zip);
    }

    async enterEmail(email: string | undefined) {
        if (email != undefined) {
            await this.emailTextBox.fill(email);
        }
    }

    async checkForInvalidZipAlertMessage() {
        await this.continueButton.click();
        await expect(this.invalidZipAlertMessage).toBeVisible();
        const alertMessage = await this.invalidZipAlertMessage.textContent();
        console.log(`Alert encountered: ${alertMessage}`);
        
        const expectedAlertMessage = `ZIP code is not valid.Please re-enter your correct service ZIP.`;
        expect(alertMessage).toContain(expectedAlertMessage);
    }

    async checkForUnserviceableZipAlertMessage(zipCode: string) {
        await this.continueButton.click();
        await expect(this.unserviceableZipAlertMessage).toBeVisible();
        const alertMessage = await this.unserviceableZipAlertMessage.textContent();
        console.log(`Alert encountered: ${alertMessage}`);
        
        const expectedAlertMessage = `We don't currently provide service within ${zipCode}.Please enter a different ZIP code where you'd like service so we can get you scheduled.`;
        expect(alertMessage).toContain(expectedAlertMessage);
    }

    async checkForVinNotFoundAlertMessage(lookupType: VehicleLookupType) {
        await this.continueButton.click();
        await expect(this.vinNotFoundAlertMessage).toBeVisible();
        const alertMessage = await this.vinNotFoundAlertMessage.textContent() || '';
        console.log(`Alert encountered: ${alertMessage}`);
        
        // Map lookup type enum to string
        let lookupTypeString: string;
        switch(lookupType) {
            case VehicleLookupType.Address:
                lookupTypeString = 'address';
                break;
            case VehicleLookupType.LicensePlateNumber:
                lookupTypeString = 'license plate';
                break;
            case VehicleLookupType.Vin:
                lookupTypeString = 'VIN';
                break;
            case VehicleLookupType.Zip:
                lookupTypeString = 'ZIP code';
                break;
            default:
                lookupTypeString = '';
        }
        
        // Map of expected messages by lookup type
        const expectedMessages = {
            'address': "Your address didn't return a VIN match.Please re-enter the information below or provide your VIN  in a different way.",
            'license plate': "Your license plate didn’t return a VIN match.Please re-enter the information above or provide your VIN  in a different way.",
            'VIN': "Your VIN didn’t return a vehicle matchPlease re-enter your VIN or we can look up your VIN  for you.",
            'ZIP code': "Your ZIP code didn't return a match.Please re-enter the information above or provide your VIN in a different way."
        };
        
        if (lookupTypeString && expectedMessages[lookupTypeString]) {
            // If lookup type is provided and has a defined message, check for exact match
            console.log(`Checking for message: "${expectedMessages[lookupTypeString]}"`);
            expect(alertMessage).toContain(expectedMessages[lookupTypeString]);
            console.log(`VIN not found alert validation passed for ${lookupTypeString}`);
        } else {
            // Fall back to checking for key phrases if no specific lookup type match
            const containsVinMatch = alertMessage.includes("didn't return a VIN match") || 
                                   alertMessage.includes("didn't return a match");
            const containsReenterInfo = alertMessage.includes("re-enter the information");
            const containsProvideVin = alertMessage.includes("provide your VIN");
            
            expect(containsVinMatch).toBeTruthy();
            expect(containsReenterInfo).toBeTruthy();
            expect(containsProvideVin).toBeTruthy();
            console.log("VIN not found alert validation passed with generic check");
        }
    }

    async handleZipValidation(zip: string, lookupType: VehicleLookupType, alertFlags?: IAlertFlags): Promise<boolean> {
        
        // Only proceed with validation if alertFlags is provided
        if (alertFlags) {
            if (alertFlags.isUnserviceableZip) {
                await this.checkForUnserviceableZipAlertMessage(zip);
                throw new TestSuccessAlert('Unserviceable ZIP validation successful.');
            } else if (alertFlags.isInvalidZip) {
                await this.checkForInvalidZipAlertMessage();
                throw new TestSuccessAlert('Invalid ZIP validation successful.');
            } else if (alertFlags.isVinNotFound) {
                await this.checkForVinNotFoundAlertMessage(lookupType);
                throw new TestSuccessAlert('Vin not found validation successful.');
            } else {
                
            }
        }
    
        // If no alert flags or no matching condition, just continue
        await this.nextPage();
        return true;
    }
}