import { test, expect } from '../../fixtures/test-base';
import { siteConfig } from '../../config/siteConfig';
import {
    selectDeliveryFulfillment,
    fillShippingAddress,
    acceptTermsAndPlaceOrder,
    verifyOrderConfirmation,
    TEST_SHIPPING_ADDRESS,
} from '../../support/checkout-helpers';
import { fillStripeCard, STRIPE_CARDS } from '../../support/payment-helpers';
import { waitForHydration } from '../../support/cart-helpers';

test.describe('Guest Checkout', () => {
    test.setTimeout(120_000);

    test('CHK-001 @checkout: Guest checkout full flow', async ({ page, addToCartAndCheckout }) => {
        await addToCartAndCheckout('cotton_knit_cardigan_swing');
        await selectDeliveryFulfillment(page);
        await fillShippingAddress(page, TEST_SHIPPING_ADDRESS);
        await page.waitForTimeout(2000);

        // Single-page checkout — payment section is already visible, no "Continue" step
        const cardFilled = await fillStripeCard(page, STRIPE_CARDS.standard);
        if (!cardFilled) {
            console.log('Stripe card input not found, payment step may differ');
        }
        await page.waitForTimeout(1000);

        const orderPlaced = await acceptTermsAndPlaceOrder(page);
        test.skip(!orderPlaced, 'Place order button not found or disabled');

        const confirmed = await verifyOrderConfirmation(page);
        expect(confirmed, 'CHK-001: Order confirmation page should be displayed').toBeTruthy();
    });

    test('CHK-002 @checkout: Guest checkout — create account', async ({ page, addToCartAndCheckout }) => {
        await addToCartAndCheckout('cotton_knit_cardigan_swing');
        await selectDeliveryFulfillment(page);
        await fillShippingAddress(page, TEST_SHIPPING_ADDRESS);
        await page.waitForTimeout(2000);

        // Look for "Create an account" checkbox (on feature branch it's pre-checked)
        const createAccountCheckbox = page.locator(
            'input[name*="create_account" i], input[name*="createAccount" i]'
        ).first();
        const createAccountLabel = page.getByText(/create an account/i).first();

        const hasCheckbox = await createAccountCheckbox.isVisible().catch(() => false);
        const hasLabel = await createAccountLabel.isVisible().catch(() => false);

        test.skip(!hasCheckbox && !hasLabel, 'Create account checkbox not found on checkout page');

        if (hasCheckbox) {
            const checked = await createAccountCheckbox.isChecked().catch(() => false);
            if (!checked) await createAccountCheckbox.check();
        }

        expect(hasCheckbox || hasLabel, 'CHK-002: Create account option should be available').toBeTruthy();
    });

    test('CHK-008 @checkout: Empty cart redirects to home', async ({ page }) => {
        await page.goto(siteConfig.routes.checkout, { waitUntil: 'domcontentloaded' });
        await page.waitForLoadState('networkidle').catch(() => {});
        await waitForHydration(page);
        await page.waitForTimeout(3000);

        const currentUrl = page.url();
        const isRedirected = !currentUrl.includes('checkout') ||
            currentUrl === siteConfig.baseUrl + '/' ||
            currentUrl.endsWith('/en/');

        const emptyCart = await page.getByText(/cart is empty|bag is empty|カートは空/i)
            .isVisible().catch(() => false);

        expect(isRedirected || emptyCart, 'CHK-008: Empty cart should redirect or show empty message').toBeTruthy();
    });

    test('CHK-009 @checkout: Terms required — error shown when unchecked', async ({ page, addToCartAndCheckout }) => {
        await addToCartAndCheckout('cotton_knit_cardigan_swing');
        await selectDeliveryFulfillment(page);
        await fillShippingAddress(page, TEST_SHIPPING_ADDRESS);
        await page.waitForTimeout(2000);

        // Fill card (single-page, no continue step)
        await fillStripeCard(page, STRIPE_CARDS.standard);
        await page.waitForTimeout(1000);

        // Uncheck terms checkbox (it may be pre-checked on feature branch)
        const termsCheckbox = page.locator(
            'button:has-text("Agree to Terms"), input[name*="terms" i], label:has-text("Terms") input[type="checkbox"]'
        ).first();

        if (await termsCheckbox.isVisible().catch(() => false)) {
            // Find the actual checkbox near the terms button/label
            const checkbox = page.locator('input[type="checkbox"]').nth(1); // Terms is typically second checkbox
            const checked = await checkbox.isChecked().catch(() => false);
            if (checked) await checkbox.uncheck().catch(() => {});
        }

        // Try to place order with "Confirm" button
        const confirmBtn = page.locator(
            'button:has-text("Confirm"), button:has-text("Place Order"), button:has-text("注文する")'
        ).first();

        if (await confirmBtn.isVisible().catch(() => false)) {
            await confirmBtn.click();
            await page.waitForTimeout(1500);
        }

        // Check for error or disabled button
        const hasError = await page.locator('[class*="error" i], [role="alert"]').first()
            .isVisible().catch(() => false);
        const isDisabled = await confirmBtn.isDisabled().catch(() => false);

        expect(hasError || isDisabled,
            'CHK-009: Error should be shown or button disabled when terms not accepted'
        ).toBeTruthy();
    });

    test('CHK-010 @checkout: Privacy required — error shown when unchecked', async ({ page, addToCartAndCheckout }) => {
        await addToCartAndCheckout('cotton_knit_cardigan_swing');
        await selectDeliveryFulfillment(page);
        await fillShippingAddress(page, TEST_SHIPPING_ADDRESS);
        await page.waitForTimeout(2000);

        await fillStripeCard(page, STRIPE_CARDS.standard);
        await page.waitForTimeout(1000);

        // Uncheck privacy checkbox (it may be pre-checked)
        const privacyCheckbox = page.locator(
            'button:has-text("Agree to Privacy"), input[name*="privacy" i], label:has-text("Privacy") input[type="checkbox"]'
        ).first();

        if (await privacyCheckbox.isVisible().catch(() => false)) {
            const checkbox = page.locator('input[type="checkbox"]').nth(2); // Privacy is typically third checkbox
            const checked = await checkbox.isChecked().catch(() => false);
            if (checked) await checkbox.uncheck().catch(() => {});
        }

        const confirmBtn = page.locator(
            'button:has-text("Confirm"), button:has-text("Place Order"), button:has-text("注文する")'
        ).first();

        if (await confirmBtn.isVisible().catch(() => false)) {
            await confirmBtn.click();
            await page.waitForTimeout(1500);
        }

        const hasError = await page.locator('[class*="error" i], [role="alert"]').first()
            .isVisible().catch(() => false);
        const isDisabled = await confirmBtn.isDisabled().catch(() => false);

        expect(hasError || isDisabled,
            'CHK-010: Error should be shown or button disabled when privacy not accepted'
        ).toBeTruthy();
    });
});
