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

// Test 1: Edit button opens modal
test('edit button opens song edit modal', async ({ page }) => {
    await page.goto('/songs');
    await page.waitForLoadState('networkidle');

    // Check if songs exist
    const songTable = page.locator('table');
    const hasTable = await songTable.isVisible().catch(() => false);

    if (!hasTable) {
        // Skip test if no songs exist
        test.skip();
    }

    // Get first song row
    const firstRow = page.locator('tbody tr').first();
    const hasEditButton = await firstRow.getByTestId('song-list-edit-button').isVisible().catch(() => false);

    if (!hasEditButton) {
        // Skip test if no edit button visible
        test.skip();
    }

    // Click edit button
    const editButton = firstRow.getByTestId('song-list-edit-button');
    await editButton.click();

    // Wait for modal to appear
    await page.waitForTimeout(300);

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

    // Verify modal title
    await expect(page.getByText('Song bearbeiten')).toBeVisible();
});

// Test 2: Modal shows input fields (name, CCLI ID, copyright)
test('modal shows song metadata input fields', async ({ page }) => {
    await page.goto('/songs');
    await page.waitForLoadState('networkidle');

    // Check if songs exist
    const songTable = page.locator('table');
    const hasTable = await songTable.isVisible().catch(() => false);

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

    // Get first song row and click edit
    const firstRow = page.locator('tbody tr').first();
    const hasEditButton = await firstRow.getByTestId('song-list-edit-button').isVisible().catch(() => false);

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

    const editButton = firstRow.getByTestId('song-list-edit-button');
    await editButton.click();

    // Wait for modal to appear
    await page.waitForTimeout(300);

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

    // Verify input fields are visible
    const titleInput = page.getByTestId('song-edit-modal-title-input');
    const ccliInput = page.getByTestId('song-edit-modal-ccli-input');
    const copyrightTextarea = page.getByTestId('song-edit-modal-copyright-textarea');

    await expect(titleInput).toBeVisible();
    await expect(ccliInput).toBeVisible();
    await expect(copyrightTextarea).toBeVisible();

    // Verify labels are visible
    await expect(page.getByText('Titel')).toBeVisible();
    await expect(page.getByText('CCLI-ID')).toBeVisible();
    await expect(page.getByText('Copyright-Text')).toBeVisible();
});

// Test 3: Fields are auto-saved on change (debounced) — verify no explicit save button
test('modal fields auto-save on change without explicit save button', async ({ page }) => {
    await page.goto('/songs');
    await page.waitForLoadState('networkidle');

    // Check if songs exist
    const songTable = page.locator('table');
    const hasTable = await songTable.isVisible().catch(() => false);

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

    // Get first song row and click edit
    const firstRow = page.locator('tbody tr').first();
    const hasEditButton = await firstRow.getByTestId('song-list-edit-button').isVisible().catch(() => false);

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

    const editButton = firstRow.getByTestId('song-list-edit-button');
    await editButton.click();

    // Wait for modal to appear
    await page.waitForTimeout(300);

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

    // Verify there is NO explicit save button
    const saveButton = page.locator('button:has-text("Speichern")');
    const saveButtonExists = await saveButton.isVisible().catch(() => false);
    expect(saveButtonExists).toBe(false);

    // Verify auto-save indicator exists (shows "Speichert…" or "Gespeichert")
    const titleInput = page.getByTestId('song-edit-modal-title-input');
    const currentValue = await titleInput.inputValue();

    // Type a character to trigger auto-save
    await titleInput.fill(currentValue + 'X');

    // Wait for debounce (500ms) + save request
    await page.waitForTimeout(700);

    // Verify save indicator appears (either "Speichert…" or "Gespeichert")
    const savingIndicator = page.getByText(/Speichert…|Gespeichert/);
    const indicatorVisible = await savingIndicator.isVisible().catch(() => false);
    expect(indicatorVisible).toBe(true);

    // Restore original value (remove the 'X')
    await titleInput.fill(currentValue);
    await page.waitForTimeout(700);
});

// Test 4: Arrangement configurator is embedded in modal
test('arrangement configurator is embedded in modal', async ({ page }) => {
    await page.goto('/songs');
    await page.waitForLoadState('networkidle');

    // Check if songs exist
    const songTable = page.locator('table');
    const hasTable = await songTable.isVisible().catch(() => false);

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

    // Get first song row and click edit
    const firstRow = page.locator('tbody tr').first();
    const hasEditButton = await firstRow.getByTestId('song-list-edit-button').isVisible().catch(() => false);

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

    const editButton = firstRow.getByTestId('song-list-edit-button');
    await editButton.click();

    // Wait for modal to appear
    await page.waitForTimeout(300);

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

    // Verify arrangement configurator section is visible
    await expect(page.getByText('Arrangements')).toBeVisible();

    // Verify arrangement configurator component is rendered
    const arrangementConfigurator = page.getByTestId('arrangement-configurator');
    const configuratorVisible = await arrangementConfigurator.isVisible().catch(() => false);
    expect(configuratorVisible).toBe(true);
});

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

    // Check if songs exist
    const songTable = page.locator('table');
    const hasTable = await songTable.isVisible().catch(() => false);

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

    // Get first song row and click edit
    const firstRow = page.locator('tbody tr').first();
    const hasEditButton = await firstRow.getByTestId('song-list-edit-button').isVisible().catch(() => false);

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

    const editButton = firstRow.getByTestId('song-list-edit-button');
    await editButton.click();

    // Wait for modal to appear
    await page.waitForTimeout(300);

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

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

    // Wait for modal to close
    await page.waitForTimeout(300);

    // Verify modal is gone
    const modalGone = await editModal.isVisible().catch(() => false);
    expect(modalGone).toBe(false);
});

// Test 6: Close modal with overlay click
test('close modal with overlay click', async ({ page }) => {
    await page.goto('/songs');
    await page.waitForLoadState('networkidle');

    // Check if songs exist
    const songTable = page.locator('table');
    const hasTable = await songTable.isVisible().catch(() => false);

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

    // Get first song row and click edit
    const firstRow = page.locator('tbody tr').first();
    const hasEditButton = await firstRow.getByTestId('song-list-edit-button').isVisible().catch(() => false);

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

    const editButton = firstRow.getByTestId('song-list-edit-button');
    await editButton.click();

    // Wait for modal to appear
    await page.waitForTimeout(300);

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

    // Click on the overlay (outside the modal)
    const overlay = page.locator('div').filter({
        has: editModal,
    }).first();
    
    // Get the overlay's bounding box and click outside the modal
    const modalBox = await editModal.boundingBox();
    if (modalBox) {
        // Click on the left side of the overlay (outside modal)
        await page.click('div[class*="fixed"][class*="inset-0"]', {
            position: { x: 10, y: 10 },
        });
    }

    // Wait for modal to close
    await page.waitForTimeout(300);

    // Verify modal is gone
    const modalGone = await editModal.isVisible().catch(() => false);
    expect(modalGone).toBe(false);
});
