import { expect, type Locator, type Page } from '@playwright/test';
import { BasePage } from '../BasePage';
import { ICustomerDetails } from 'safelite-playwright-core';
import { waitUntil } from 'safelite-playwright-core';

export class AddressForm extends BasePage {
    readonly page: Page;
    readonly streetAddressTextBox: Locator;
    readonly cityTextBox: Locator;
    readonly stateDrpDwn: Locator;
    readonly zipCodeTextBox: Locator;
    readonly firstNameTextBox: Locator;
    readonly lastNameTextBox: Locator;
    readonly addressNotFoundMsg: Locator;
    readonly addressSuggestionList: Locator;

    constructor(page: Page) {
        super(page);
        this.page = page;
        this.streetAddressTextBox = page.getByRole('textbox', { name: /Street (a|A)ddress$/ });
        this.cityTextBox = page.getByRole('textbox', { name: 'City' });
        this.stateDrpDwn = page.getByRole('combobox', { name: 'State' });
        this.zipCodeTextBox = page.getByRole('textbox', { name: 'ZIP code' });
        this.firstNameTextBox = page.getByRole('textbox', { name: 'First name' });
        this.lastNameTextBox = page.getByRole('textbox', { name: 'Last name' });
        this.addressNotFoundMsg = page.getByText('Address not found.');
        this.addressSuggestionList = page.locator('.pac-container .pac-item').first();
    }

    async forceAddressFormToAppear() {
        await expect(async () => {
            await this.streetAddressTextBox.click();
            await this.streetAddressTextBox.pressSequentially('7400 Safelite Way');
            await this.streetAddressTextBox.press('Tab');
            await expect(this.zipCodeTextBox).toBeVisible({ timeout: 100 });
        }).toPass();
    }

    async populateAddress(customerDetails: Partial<ICustomerDetails>) {

        if (customerDetails.address) {
            // Force address form to appear
            // await this.forceAddressFormToAppear();
            await this.streetAddressTextBox.click();
            await this.streetAddressTextBox.pressSequentially(`${customerDetails.address.street}, ${customerDetails.address.city}, ${customerDetails.address.state} ${customerDetails.address.postalCode}`).then( async() => {
                await this.streetAddressTextBox.dispatchEvent('keydown', { key: 'ArrowLeft' } );
                await this.streetAddressTextBox.dispatchEvent('keyup', { key: 'ArrowLeft' });
            });
            
            await waitUntil(async () => {
                await this.addressSuggestionList.waitFor({ state: 'visible', timeout: 5000 });
                let text = await this.addressSuggestionList.textContent() || '';
                return (
                    text.includes(customerDetails.address!.street) &&
                    text.includes(customerDetails.address!.city) &&
                    text.includes(customerDetails.address!.state)
                );
            });

            await this.page.hover(".pac-container .pac-item");
            await new Promise(resolve => setTimeout(resolve, 1000));
            await this.addressSuggestionList.click(); // Select the first suggestion
            //await this.streetAddressTextBox.press('Tab'); // Move focus to ZIP code field

            // Fill address
            await this.stateDrpDwn.waitFor({ state: 'visible', timeout: 5000 }).then(async () => {
                const selectedState = await this.stateDrpDwn.inputValue();
                if (selectedState !== customerDetails.address!.state) {
                    await this.stateDrpDwn.selectOption(customerDetails.address!.state);
                }
            })

            await this.fillAndValidate(this.streetAddressTextBox, customerDetails.address.street);
            await this.fillAndValidate(this.zipCodeTextBox, customerDetails.address.postalCode)
            await this.fillAndValidate(this.cityTextBox, customerDetails.address.city);
        }

        if (customerDetails.firstName) {
            await this.fillAndValidate(this.firstNameTextBox, customerDetails.firstName);
        }

        if (customerDetails.lastName) {
            await this.fillAndValidate(this.lastNameTextBox, customerDetails.lastName);
        }
    }
}