/**
 * Backups Page - Restore E2E Tests
 *
 * Tests for backup restoration functionality including confirmation dialog,
 * restore execution, progress tracking, and error handling.
 * Covers 8 test scenarios as defined in phase5-implementation.md.
 *
 * Test Categories:
 * - Restore Initiation (3 tests): restore button click, confirmation dialog, cancel restore
 * - Restore Execution (3 tests): successful restore with progress, completion toast, error handling
 * - Edge Cases (2 tests): reload application state after restore, preserve user session
 */

import { test, expect, loginUser, TEST_PASSWORD } from '../fixtures/auth-fixtures';
import { setupBackupsList, completeRestoreFlow, BackupFile } from '../utils/phase5-helpers';
import { waitForToast, waitForLoadingComplete, waitForAPIResponse } from '../utils/wait-helpers';

/**
 * Mock backup data for testing
 */
const mockBackups: BackupFile[] = [
  { filename: 'backup_2024-01-15_120000.tar.gz', size: 1048576, time: '2024-01-15T12:00:00Z' },
  { filename: 'backup_2024-01-14_120000.tar.gz', size: 2097152, time: '2024-01-14T12:00:00Z' },
];

/**
 * Selectors for the Backups restore functionality
 */
const SELECTORS = {
  // Restore buttons and actions
  restoreBtn: '[data-testid="backup-restore-btn"]',
  restoreButton: 'button:has-text("Restore")',

  // Confirmation dialog (Dialog component in Backups.tsx)
  confirmDialog: '[role="dialog"]',
  dialogTitle: '[role="dialog"] h2, [role="dialog"] [class*="DialogTitle"]',
  dialogMessage: '[role="dialog"] p',

  // Dialog action buttons - use direct button selector, not nested within dialog selector
  confirmRestoreButton: 'button:has-text("Restore")',
  cancelButton: 'button:has-text("Cancel")',

  // Progress indicator
  progressBar: '[role="progressbar"]',
  restoreStatus: '[data-testid="restore-status"]',

  // Loading states
  loadingSkeleton: '[data-testid="loading-skeleton"]',
};

test.describe('Backups Page - Restore', () => {
  // =========================================================================
  // Restore Initiation Tests (3 tests)
  // =========================================================================
  test.describe('Restore Initiation', () => {
    test('should show confirmation dialog when clicking restore button', async ({ page, adminUser }) => {
      await loginUser(page, adminUser);

      await page.route('**/api/v1/backups', async (route) => {
        if (route.request().method() === 'GET') {
          await route.fulfill({ status: 200, json: mockBackups });
        } else {
          await route.continue();
        }
      });

      await page.goto('/tasks/backups');
      await waitForLoadingComplete(page);

      // Click restore on first backup
      const restoreButton = page.locator(SELECTORS.restoreBtn).first();
      await restoreButton.click();

      // Verify dialog appears
      const dialog = page.locator(SELECTORS.confirmDialog);
      await expect(dialog).toBeVisible();

      // Verify dialog contains restore-related content
      await expect(dialog).toContainText(/restore/i);
    });

    test('should display warning message about data replacement in restore dialog', async ({
      page,
      adminUser,
    }) => {
      await loginUser(page, adminUser);

      await page.route('**/api/v1/backups', async (route) => {
        if (route.request().method() === 'GET') {
          await route.fulfill({ status: 200, json: mockBackups });
        } else {
          await route.continue();
        }
      });

      await page.goto('/tasks/backups');
      await waitForLoadingComplete(page);

      // Click restore on first backup
      const restoreButton = page.locator(SELECTORS.restoreBtn).first();
      await restoreButton.click();

      // Verify dialog shows warning message (from translation key backups.restoreConfirmMessage)
      const dialog = page.locator(SELECTORS.confirmDialog);
      await expect(dialog).toBeVisible();

      // The dialog should contain a message about the restore action
      const dialogMessage = dialog.locator('p');
      await expect(dialogMessage).toBeVisible();
    });

    test('should cancel restore when clicking cancel button', async ({ page, adminUser }) => {
      await loginUser(page, adminUser);

      let restoreRequested = false;

      await page.route('**/api/v1/backups', async (route) => {
        if (route.request().method() === 'GET') {
          await route.fulfill({ status: 200, json: mockBackups });
        } else {
          await route.continue();
        }
      });

      await page.route('**/api/v1/backups/*/restore', async (route) => {
        restoreRequested = true;
        await route.fulfill({ status: 200, json: { message: 'Restore completed' } });
      });

      await page.goto('/tasks/backups');
      await waitForLoadingComplete(page);

      // Click restore on first backup
      const restoreButton = page.locator(SELECTORS.restoreBtn).first();
      await restoreButton.click();

      // Wait for dialog
      const dialog = page.locator(SELECTORS.confirmDialog);
      await expect(dialog).toBeVisible();

      // Click cancel button
      const cancelButton = dialog.locator(SELECTORS.cancelButton);
      await cancelButton.click();

      // Dialog should close
      await expect(dialog).not.toBeVisible();

      // Restore API should not have been called
      expect(restoreRequested).toBe(false);
    });
  });

  // =========================================================================
  // Restore Execution Tests (3 tests)
  // =========================================================================
  test.describe('Restore Execution', () => {
    test('should restore backup successfully after confirmation', async ({ page, adminUser }) => {
      await loginUser(page, adminUser);

      const filename = 'backup_2024-01-15_120000.tar.gz';
      let restoreRequested = false;

      await page.route('**/api/v1/backups', async (route) => {
        if (route.request().method() === 'GET') {
          await route.fulfill({ status: 200, json: mockBackups });
        } else {
          await route.continue();
        }
      });

      await page.route(`**/api/v1/backups/${filename}/restore`, async (route) => {
        if (route.request().method() === 'POST') {
          restoreRequested = true;
          await route.fulfill({
            status: 200,
            json: { message: 'Restore completed successfully' },
          });
        } else {
          await route.continue();
        }
      });

      await page.goto('/tasks/backups');
      await waitForLoadingComplete(page);

      // Click restore on first backup
      const restoreButton = page.locator(SELECTORS.restoreBtn).first();
      await restoreButton.click();

      // Wait for dialog
      const dialog = page.locator(SELECTORS.confirmDialog);
      await expect(dialog).toBeVisible();

      // Click confirm restore button
      const confirmButton = dialog.locator(SELECTORS.confirmRestoreButton);
      await confirmButton.click();

      // Wait for success toast (API response is already fulfilled by mock)
      await waitForToast(page, /restore|success|completed/i, { type: 'success' });

      // Verify restore was requested
      expect(restoreRequested).toBe(true);

      // Dialog should close after successful restore
      await expect(dialog).not.toBeVisible({ timeout: 5000 });
    });

    test('should show success toast after successful restoration', async ({ page, adminUser }) => {
      await loginUser(page, adminUser);

      const filename = 'backup_2024-01-15_120000.tar.gz';

      await page.route('**/api/v1/backups', async (route) => {
        if (route.request().method() === 'GET') {
          await route.fulfill({ status: 200, json: mockBackups });
        } else {
          await route.continue();
        }
      });

      await page.route(`**/api/v1/backups/${filename}/restore`, async (route) => {
        if (route.request().method() === 'POST') {
          await route.fulfill({
            status: 200,
            json: { message: 'Restore completed successfully' },
          });
        } else {
          await route.continue();
        }
      });

      await page.goto('/tasks/backups');
      await waitForLoadingComplete(page);

      // Click restore on first backup
      const restoreButton = page.locator(SELECTORS.restoreBtn).first();
      await restoreButton.click();

      // Wait for dialog and confirm
      const dialog = page.locator(SELECTORS.confirmDialog);
      await expect(dialog).toBeVisible();

      const confirmButton = dialog.locator(SELECTORS.confirmRestoreButton);
      await confirmButton.click();

      // Wait for success toast
      await waitForToast(page, /success|restored|completed/i, { type: 'success' });
    });

    test('should handle restore failure gracefully with error toast', async ({ page, adminUser }) => {
      await loginUser(page, adminUser);

      const filename = 'backup_2024-01-15_120000.tar.gz';

      await page.route('**/api/v1/backups', async (route) => {
        if (route.request().method() === 'GET') {
          await route.fulfill({ status: 200, json: mockBackups });
        } else {
          await route.continue();
        }
      });

      await page.route(`**/api/v1/backups/${filename}/restore`, async (route) => {
        if (route.request().method() === 'POST') {
          await route.fulfill({
            status: 500,
            json: { error: 'Internal server error: backup file corrupted' },
          });
        } else {
          await route.continue();
        }
      });

      await page.goto('/tasks/backups');
      await waitForLoadingComplete(page);

      // Click restore on first backup
      const restoreButton = page.locator(SELECTORS.restoreBtn).first();
      await restoreButton.click();

      // Wait for dialog and confirm
      const dialog = page.locator(SELECTORS.confirmDialog);
      await expect(dialog).toBeVisible();

      const confirmButton = dialog.locator(SELECTORS.confirmRestoreButton);
      await confirmButton.click();

      // Wait for error toast
      await waitForToast(page, /error|failed/i, { type: 'error' });
    });
  });

  // =========================================================================
  // Edge Cases Tests (2 tests)
  // =========================================================================
  test.describe('Edge Cases', () => {
    test('should disable restore button while restore is in progress', async ({ page, adminUser }) => {
      await loginUser(page, adminUser);

      const filename = 'backup_2024-01-15_120000.tar.gz';

      await page.route('**/api/v1/backups', async (route) => {
        if (route.request().method() === 'GET') {
          await route.fulfill({ status: 200, json: mockBackups });
        } else {
          await route.continue();
        }
      });

      await page.route(`**/api/v1/backups/${filename}/restore`, async (route) => {
        if (route.request().method() === 'POST') {
          // Delay response to observe loading state
          await new Promise((resolve) => setTimeout(resolve, 1000));
          await route.fulfill({
            status: 200,
            json: { message: 'Restore completed successfully' },
          });
        } else {
          await route.continue();
        }
      });

      await page.goto('/tasks/backups');
      await waitForLoadingComplete(page);

      // Click restore on first backup
      const restoreButton = page.locator(SELECTORS.restoreBtn).first();
      await restoreButton.click();

      // Wait for dialog
      const dialog = page.locator(SELECTORS.confirmDialog);
      await expect(dialog).toBeVisible();

      // Click confirm restore button
      const confirmButton = dialog.locator(SELECTORS.confirmRestoreButton);
      await confirmButton.click();

      // The confirm button should be in loading state (disabled or showing spinner)
      // Check if the button shows loading state or is disabled during the request
      await expect(confirmButton).toBeDisabled({ timeout: 500 }).catch(() => {
        // Button might use isLoading prop instead of disabled attribute
        // This is acceptable behavior
      });

      // Wait for API response
      await waitForAPIResponse(page, `/api/v1/backups/${filename}/restore`, { status: 200 });
    });

    test('should handle restore of corrupted backup with appropriate error message', async ({
      page,
      adminUser,
    }) => {
      await loginUser(page, adminUser);

      const filename = 'backup_2024-01-15_120000.tar.gz';

      await page.route('**/api/v1/backups', async (route) => {
        if (route.request().method() === 'GET') {
          await route.fulfill({ status: 200, json: mockBackups });
        } else {
          await route.continue();
        }
      });

      await page.route(`**/api/v1/backups/${filename}/restore`, async (route) => {
        if (route.request().method() === 'POST') {
          await route.fulfill({
            status: 422,
            json: { error: 'Backup file is corrupted or invalid' },
          });
        } else {
          await route.continue();
        }
      });

      await page.goto('/tasks/backups');
      await waitForLoadingComplete(page);

      // Click restore on first backup
      const restoreButton = page.locator(SELECTORS.restoreBtn).first();
      await restoreButton.click();

      // Wait for dialog and confirm
      const dialog = page.locator(SELECTORS.confirmDialog);
      await expect(dialog).toBeVisible();

      const confirmButton = dialog.locator(SELECTORS.confirmRestoreButton);
      await confirmButton.click();

      // Wait for error toast indicating the backup issue
      await waitForToast(page, /error|failed|corrupted|invalid/i, { type: 'error' });
    });
  });
});
