import { test, expect } from '@playwright/test';

// Test 1: Preview button opens SongPreviewModal
test('preview button opens SongPreviewModal', async ({ page }) => {
    await page.goto('/services');
    await page.waitForLoadState('networkidle');

    const editButton = page.getByTestId('service-list-edit-button').first();
    const hasEditableService = await editButton.isVisible().catch(() => false);

    if (!hasEditableService) {
        test.skip();
    }

    await editButton.click();
    await page.waitForLoadState('networkidle');

    // Find the Songs block toggle button (4th block)
    const blockToggles = page.getByTestId('service-edit-block-toggle');
    const songsToggle = blockToggles.filter({ has: page.locator('text=Songs') }).first();

    const toggleExists = await songsToggle.isVisible().catch(() => false);
    if (!toggleExists) {
        test.skip();
    }

    // Expand Songs block if collapsed
    const songsBlock = page.getByTestId('songs-block');
    const isHidden = await songsBlock.isHidden().catch(() => true);
    if (isHidden) {
        await songsToggle.click();
        await page.waitForTimeout(300);
    }

    // Find first matched song with preview button
    const songCards = page.getByTestId('songs-block-song-card');
    const songCount = await songCards.count();

    if (songCount === 0) {
        test.skip();
    }

    // Find first song with preview button (matched songs only)
    let previewButton = null;
    for (let i = 0; i < songCount; i++) {
        const card = songCards.nth(i);
        const button = card.getByTestId('songs-block-preview-button');
        const isVisible = await button.isVisible().catch(() => false);
        if (isVisible) {
            previewButton = button;
            break;
        }
    }

    if (!previewButton) {
        test.skip();
    }

    // Click preview button
    await previewButton.click();
    await page.waitForTimeout(300); // Wait for modal transition

    // Verify modal is visible
    const modal = page.getByTestId('song-preview-modal');
    await expect(modal).toBeVisible();

    // Verify modal has header with song title and arrangement name
    const modalHeader = modal.locator('h2').first();
    await expect(modalHeader).toBeVisible();

    // Verify close button is visible
    const closeButton = page.getByTestId('song-preview-modal-close-button');
    await expect(closeButton).toBeVisible();
});

// Test 2: Modal shows song text organized by groups with highlighted group labels
test('modal shows groups with labels and slides', async ({ page }) => {
    await page.goto('/services');
    await page.waitForLoadState('networkidle');

    const editButton = page.getByTestId('service-list-edit-button').first();
    const hasEditableService = await editButton.isVisible().catch(() => false);

    if (!hasEditableService) {
        test.skip();
    }

    await editButton.click();
    await page.waitForLoadState('networkidle');

    // Expand Songs block
    const blockToggles = page.getByTestId('service-edit-block-toggle');
    const songsToggle = blockToggles.filter({ has: page.locator('text=Songs') }).first();

    const toggleExists = await songsToggle.isVisible().catch(() => false);
    if (!toggleExists) {
        test.skip();
    }

    const songsBlock = page.getByTestId('songs-block');
    const isHidden = await songsBlock.isHidden().catch(() => true);
    if (isHidden) {
        await songsToggle.click();
        await page.waitForTimeout(300);
    }

    // Find first matched song with preview button
    const songCards = page.getByTestId('songs-block-song-card');
    const songCount = await songCards.count();

    if (songCount === 0) {
        test.skip();
    }

    let previewButton = null;
    for (let i = 0; i < songCount; i++) {
        const card = songCards.nth(i);
        const button = card.getByTestId('songs-block-preview-button');
        const isVisible = await button.isVisible().catch(() => false);
        if (isVisible) {
            previewButton = button;
            break;
        }
    }

    if (!previewButton) {
        test.skip();
    }

    // Click preview button
    await previewButton.click();
    await page.waitForTimeout(300);

    // Verify modal is visible
    const modal = page.getByTestId('song-preview-modal');
    await expect(modal).toBeVisible();

    // Verify modal content area exists
    const contentArea = modal.locator('div').filter({ has: page.locator('text=/^[A-Z].*$/') }).first();
    await expect(contentArea).toBeVisible();

    // Verify modal has text content (groups and slides)
    const modalText = await modal.textContent();
    expect(modalText).toBeTruthy();
    expect(modalText?.length).toBeGreaterThan(0);
});

// Test 3: Close modal with X button
test('close modal with X button', async ({ page }) => {
    await page.goto('/services');
    await page.waitForLoadState('networkidle');

    const editButton = page.getByTestId('service-list-edit-button').first();
    const hasEditableService = await editButton.isVisible().catch(() => false);

    if (!hasEditableService) {
        test.skip();
    }

    await editButton.click();
    await page.waitForLoadState('networkidle');

    // Expand Songs block
    const blockToggles = page.getByTestId('service-edit-block-toggle');
    const songsToggle = blockToggles.filter({ has: page.locator('text=Songs') }).first();

    const toggleExists = await songsToggle.isVisible().catch(() => false);
    if (!toggleExists) {
        test.skip();
    }

    const songsBlock = page.getByTestId('songs-block');
    const isHidden = await songsBlock.isHidden().catch(() => true);
    if (isHidden) {
        await songsToggle.click();
        await page.waitForTimeout(300);
    }

    // Find first matched song with preview button
    const songCards = page.getByTestId('songs-block-song-card');
    const songCount = await songCards.count();

    if (songCount === 0) {
        test.skip();
    }

    let previewButton = null;
    for (let i = 0; i < songCount; i++) {
        const card = songCards.nth(i);
        const button = card.getByTestId('songs-block-preview-button');
        const isVisible = await button.isVisible().catch(() => false);
        if (isVisible) {
            previewButton = button;
            break;
        }
    }

    if (!previewButton) {
        test.skip();
    }

    // Click preview button
    await previewButton.click();
    await page.waitForTimeout(300);

    // Verify modal is visible
    const modal = page.getByTestId('song-preview-modal');
    await expect(modal).toBeVisible();

    // Click close button
    const closeButton = page.getByTestId('song-preview-modal-close-button');
    await closeButton.click();
    await page.waitForTimeout(300);

    // Verify modal is hidden
    const isModalHidden = await modal.isHidden().catch(() => true);
    expect(isModalHidden).toBe(true);
});

// Test 4: Close modal with ESC key
test('close modal with ESC key', async ({ page }) => {
    await page.goto('/services');
    await page.waitForLoadState('networkidle');

    const editButton = page.getByTestId('service-list-edit-button').first();
    const hasEditableService = await editButton.isVisible().catch(() => false);

    if (!hasEditableService) {
        test.skip();
    }

    await editButton.click();
    await page.waitForLoadState('networkidle');

    // Expand Songs block
    const blockToggles = page.getByTestId('service-edit-block-toggle');
    const songsToggle = blockToggles.filter({ has: page.locator('text=Songs') }).first();

    const toggleExists = await songsToggle.isVisible().catch(() => false);
    if (!toggleExists) {
        test.skip();
    }

    const songsBlock = page.getByTestId('songs-block');
    const isHidden = await songsBlock.isHidden().catch(() => true);
    if (isHidden) {
        await songsToggle.click();
        await page.waitForTimeout(300);
    }

    // Find first matched song with preview button
    const songCards = page.getByTestId('songs-block-song-card');
    const songCount = await songCards.count();

    if (songCount === 0) {
        test.skip();
    }

    let previewButton = null;
    for (let i = 0; i < songCount; i++) {
        const card = songCards.nth(i);
        const button = card.getByTestId('songs-block-preview-button');
        const isVisible = await button.isVisible().catch(() => false);
        if (isVisible) {
            previewButton = button;
            break;
        }
    }

    if (!previewButton) {
        test.skip();
    }

    // Click preview button
    await previewButton.click();
    await page.waitForTimeout(300);

    // Verify modal is visible
    const modal = page.getByTestId('song-preview-modal');
    await expect(modal).toBeVisible();

    // Press ESC key
    await page.press('body', 'Escape');
    await page.waitForTimeout(300);

    // Verify modal is hidden
    const isModalHidden = await modal.isHidden().catch(() => true);
    expect(isModalHidden).toBe(true);
});

// Test 5: PDF download button triggers download with PDF content-type
test('PDF download button triggers download with PDF content-type', async ({ page, context }) => {
    await page.goto('/services');
    await page.waitForLoadState('networkidle');

    const editButton = page.getByTestId('service-list-edit-button').first();
    const hasEditableService = await editButton.isVisible().catch(() => false);

    if (!hasEditableService) {
        test.skip();
    }

    await editButton.click();
    await page.waitForLoadState('networkidle');

    // Expand Songs block
    const blockToggles = page.getByTestId('service-edit-block-toggle');
    const songsToggle = blockToggles.filter({ has: page.locator('text=Songs') }).first();

    const toggleExists = await songsToggle.isVisible().catch(() => false);
    if (!toggleExists) {
        test.skip();
    }

    const songsBlock = page.getByTestId('songs-block');
    const isHidden = await songsBlock.isHidden().catch(() => true);
    if (isHidden) {
        await songsToggle.click();
        await page.waitForTimeout(300);
    }

    // Find first matched song with preview button
    const songCards = page.getByTestId('songs-block-song-card');
    const songCount = await songCards.count();

    if (songCount === 0) {
        test.skip();
    }

    let previewButton = null;
    for (let i = 0; i < songCount; i++) {
        const card = songCards.nth(i);
        const button = card.getByTestId('songs-block-preview-button');
        const isVisible = await button.isVisible().catch(() => false);
        if (isVisible) {
            previewButton = button;
            break;
        }
    }

    if (!previewButton) {
        test.skip();
    }

    // Click preview button
    await previewButton.click();
    await page.waitForTimeout(300);

    // Verify modal is visible
    const modal = page.getByTestId('song-preview-modal');
    await expect(modal).toBeVisible();

    // Get PDF link and verify it exists
    const pdfLink = page.getByTestId('song-preview-modal-pdf-link');
    await expect(pdfLink).toBeVisible();

    // Verify PDF link has href attribute
    const href = await pdfLink.getAttribute('href');
    expect(href).toBeTruthy();
    expect(href).toMatch(/\/songs\/\d+\/arrangements\/\d+\/pdf/);

    // Listen for response to PDF download
    const downloadPromise = context.waitForEvent('page');
    
    // Click PDF link (opens in new tab)
    await pdfLink.click();

    // Wait for new page/tab
    const newPage = await downloadPromise;
    await newPage.waitForLoadState('networkidle');

    // Verify response has PDF content-type
    const requests = await newPage.context().storageState();
    
    // Alternative: Check the response headers by intercepting
    let pdfContentTypeFound = false;
    
    // Listen to all responses on the new page
    newPage.on('response', (response) => {
        const contentType = response.headers()['content-type'];
        if (contentType && contentType.includes('application/pdf')) {
            pdfContentTypeFound = true;
        }
    });

    // Navigate to PDF URL directly to verify content-type
    const pdfUrl = href;
    const response = await page.request.get(pdfUrl);
    
    expect(response.status()).toBe(200);
    const contentType = response.headers()['content-type'];
    expect(contentType).toContain('application/pdf');

    await newPage.close();
});
