import { test, expect } from '@playwright/test';
import { siteConfig } from '../../config/siteConfig';
import { waitForHydration } from '../../support/cart-helpers';
import {
    generateTestEmail,
    waitForEmail,
    clearEmails,
    extractLinksFromHtml,
    emailContains,
} from '../../support/email-helpers';

test.describe('Email verification', () => {
    test.describe('Registration email', () => {
        test('receives welcome email after registration', async ({ page }) => {
            test.setTimeout(120_000);

            const testEmail = generateTestEmail('reg');
            const beforeRegister = new Date();

            // Clear any previous emails for this address
            await clearEmails(page, testEmail);

            // Navigate to registration page
            await page.goto(siteConfig.routes.register, { waitUntil: 'domcontentloaded' });
            await page.waitForLoadState('networkidle').catch(() => {});
            await waitForHydration(page);

            // Fill registration form
            const familyName = page.getByRole('textbox', { name: /family name/i }).first();
            await familyName.waitFor({ state: 'visible', timeout: 10000 }).catch(() => null);
            if (!(await familyName.isVisible().catch(() => false))) {
                test.skip(true, 'Registration form not found');
                return;
            }

            await familyName.fill('テスト');

            const firstName = page.getByRole('textbox', { name: /first name/i }).first();
            if (await firstName.isVisible().catch(() => false)) {
                await firstName.fill('太郎');
            }

            const emailInput = page.getByRole('textbox', { name: /email/i }).first();
            await emailInput.fill(testEmail);

            const passwordInputs = page.locator('input[type="password"]');
            const pwCount = await passwordInputs.count();
            if (pwCount >= 1) await passwordInputs.nth(0).fill('E2eTest123!');
            if (pwCount >= 2) await passwordInputs.nth(1).fill('E2eTest123!');

            // Submit registration
            const registerBtn = page.locator('main button:has-text("REGISTER"), main button:has-text("Register")').first();
            await Promise.all([
                page.waitForResponse(
                    (resp) => resp.url().includes('/graphql') || resp.url().includes('/auth'),
                    { timeout: 20000 }
                ).catch(() => null),
                registerBtn.click(),
            ]);

            await page.waitForTimeout(5000);

            // Verify registration succeeded (redirected away from create-account)
            const stillOnRegister = page.url().includes('create-account');
            if (stillOnRegister) {
                test.skip(true, 'Registration did not complete — email test cannot proceed');
                return;
            }

            // Wait for welcome email
            const email = await waitForEmail(page, testEmail, {
                timeoutMs: 90000,
                afterDate: beforeRegister,
            });

            expect(email, 'Should receive a welcome/registration email').toBeTruthy();

            if (email) {
                // Verify email subject
                expect(
                    email.subject.length,
                    'Email should have a subject'
                ).toBeGreaterThan(0);

                // Verify email is from matsuyaginza domain
                expect(
                    email.from,
                    'Email should be from a matsuyaginza address'
                ).toContain('matsuyaginza');

                // Verify email body has content
                const hasBody = email.htmlBody.length > 0 || email.textBody.length > 0;
                expect(hasBody, 'Email should have a body').toBeTruthy();

                // Check for common welcome email content
                const hasWelcomeContent =
                    emailContains(email, 'welcome') ||
                    emailContains(email, 'thank you') ||
                    emailContains(email, 'registration') ||
                    emailContains(email, 'account') ||
                    emailContains(email, 'ようこそ') ||
                    emailContains(email, '登録');

                expect(
                    hasWelcomeContent,
                    'Welcome email should contain relevant content (welcome, thank you, registration, etc.)'
                ).toBeTruthy();

                // Check for links in email
                if (email.htmlBody) {
                    const links = extractLinksFromHtml(email.htmlBody);
                    expect(
                        links.length,
                        'Welcome email should contain at least one link'
                    ).toBeGreaterThan(0);

                    // Verify links point to matsuyaginza domain
                    const hasMatsuyaLink = links.some(
                        (link) => link.includes('matsuyaginza')
                    );
                    expect(
                        hasMatsuyaLink,
                        'Email should contain a link to matsuyaginza.com'
                    ).toBeTruthy();
                }
            }
        });

        test('registration email has correct recipient', async ({ page }) => {
            test.setTimeout(120_000);

            const testEmail = generateTestEmail('recipient');
            const beforeRegister = new Date();

            await clearEmails(page, testEmail);

            // Register
            await page.goto(siteConfig.routes.register, { waitUntil: 'domcontentloaded' });
            await page.waitForLoadState('networkidle').catch(() => {});
            await waitForHydration(page);

            const familyName = page.getByRole('textbox', { name: /family name/i }).first();
            await familyName.waitFor({ state: 'visible', timeout: 10000 }).catch(() => null);
            if (!(await familyName.isVisible().catch(() => false))) {
                test.skip(true, 'Registration form not found');
                return;
            }

            await familyName.fill('受信テスト');
            const firstName = page.getByRole('textbox', { name: /first name/i }).first();
            if (await firstName.isVisible().catch(() => false)) await firstName.fill('確認');

            const emailInput = page.getByRole('textbox', { name: /email/i }).first();
            await emailInput.fill(testEmail);

            const passwordInputs = page.locator('input[type="password"]');
            if ((await passwordInputs.count()) >= 1) await passwordInputs.nth(0).fill('E2eTest123!');
            if ((await passwordInputs.count()) >= 2) await passwordInputs.nth(1).fill('E2eTest123!');

            const registerBtn = page.locator('main button:has-text("REGISTER"), main button:has-text("Register")').first();
            await registerBtn.click();
            await page.waitForTimeout(5000);

            if (page.url().includes('create-account')) {
                test.skip(true, 'Registration did not complete');
                return;
            }

            const email = await waitForEmail(page, testEmail, {
                timeoutMs: 90000,
                afterDate: beforeRegister,
            });

            expect(email, 'Should receive email').toBeTruthy();

            if (email) {
                // Verify the "to" field matches exactly
                expect(
                    email.to.map((e) => e.toLowerCase()),
                    'Email recipient should match the registered address'
                ).toContain(testEmail.toLowerCase());
            }
        });
    });
});
