import { Page } from '@playwright/test';

export class TestDataManager {
  private readonly page: Page;
  private testData: Map<string, any> = new Map();
  private cleanupCallbacks: Array<() => Promise<void>> = [];

  constructor(page: Page) {
    this.page = page;
  }

  generateUniquePrefix(prefix: string): string {
    const timestamp = Date.now();
    const random = Math.random().toString(36).substring(2, 8);
    return `${prefix}_${timestamp}_${random}`;
  }

  generateTestEmail(prefix: string = 'test'): string {
    const uniquePart = this.generateUniquePrefix(prefix);
    return `${uniquePart}@novalon-test.com`;
  }

  generateTestUsername(prefix: string = 'testuser'): string {
    return this.generateUniquePrefix(prefix);
  }

  generateTestFileName(prefix: string = 'testfile'): string {
    const uniquePart = this.generateUniquePrefix(prefix);
    return `${uniquePart}.txt`;
  }

  generateTestConfigName(prefix: string = 'testconfig'): string {
    return this.generateUniquePrefix(prefix);
  }

  generateTestDictName(prefix: string = 'testdict'): string {
    return this.generateUniquePrefix(prefix);
  }

  generateTestNotificationTitle(prefix: string = 'testnotify'): string {
    return this.generateUniquePrefix(prefix);
  }

  generateTestContent(prefix: string = 'content'): string {
    const timestamp = new Date().toLocaleString('zh-CN');
    return `测试内容_${prefix}_${timestamp}`;
  }

  set(key: string, value: any): void {
    this.testData.set(key, value);
  }

  get(key: string): any {
    return this.testData.get(key);
  }

  has(key: string): boolean {
    return this.testData.has(key);
  }

  remove(key: string): boolean {
    return this.testData.delete(key);
  }

  clear(): void {
    this.testData.clear();
  }

  registerCleanup(callback: () => Promise<void>): void {
    this.cleanupCallbacks.push(callback);
  }

  async cleanup(): Promise<void> {
    console.log('Starting test data cleanup...');
    
    for (const callback of this.cleanupCallbacks) {
      try {
        await callback();
      } catch (error) {
        console.error('Cleanup callback failed:', error);
      }
    }
    
    this.cleanupCallbacks = [];
    this.testData.clear();
    console.log('Test data cleanup completed');
  }

  async cleanupTestConfigs(): Promise<void> {
    console.log('Cleaning up test configurations...');
    try {
      await this.page.goto('/system/config');
      await this.page.waitForLoadState('networkidle');
      
      const testRows = this.page.locator('.el-table__row').filter({ hasText: 'test' });
      const count = await testRows.count();
      
      for (let i = 0; i < count; i++) {
        const row = testRows.nth(i);
        const deleteButton = row.locator('.el-button--danger').first();
        
        if (await deleteButton.isVisible()) {
          await deleteButton.click();
          
          const confirmButton = this.page.getByRole('button', { name: '确定' });
          await confirmButton.click();
          
          await this.page.waitForTimeout(500);
        }
      }
      
      console.log(`Cleaned up ${count} test configurations`);
    } catch (error) {
      console.error('Failed to cleanup test configurations:', error);
    }
  }

  async cleanupTestNotifications(): Promise<void> {
    console.log('Cleaning up test notifications...');
    try {
      await this.page.goto('/system/notice');
      await this.page.waitForLoadState('networkidle');
      
      const testRows = this.page.locator('.el-table__row').filter({ hasText: '测试通知' });
      const count = await testRows.count();
      
      for (let i = 0; i < count; i++) {
        const row = testRows.nth(i);
        const deleteButton = row.locator('.el-button--danger').first();
        
        if (await deleteButton.isVisible()) {
          await deleteButton.click();
          
          const confirmButton = this.page.getByRole('button', { name: '确定' });
          await confirmButton.click();
          
          await this.page.waitForTimeout(500);
        }
      }
      
      console.log(`Cleaned up ${count} test notifications`);
    } catch (error) {
      console.error('Failed to cleanup test notifications:', error);
    }
  }

  async cleanupTestFiles(): Promise<void> {
    console.log('Cleaning up test files...');
    try {
      await this.page.goto('/files');
      await this.page.waitForLoadState('networkidle');
      
      const testRows = this.page.locator('.el-table__row').filter({ hasText: 'test' });
      const count = await testRows.count();
      
      for (let i = 0; i < count; i++) {
        const row = testRows.nth(i);
        const deleteButton = row.locator('.el-button--danger').first();
        
        if (await deleteButton.isVisible()) {
          await deleteButton.click();
          
          const confirmButton = this.page.getByRole('button', { name: '确定' });
          await confirmButton.click();
          
          await this.page.waitForTimeout(500);
        }
      }
      
      console.log(`Cleaned up ${count} test files`);
    } catch (error) {
      console.error('Failed to cleanup test files:', error);
    }
  }

  createTestFileContent(fileName: string): string {
    const timestamp = new Date().toISOString();
    return `Test file created at ${timestamp}\nFilename: ${fileName}\nThis is a test file for E2E testing purposes.`;
  }

  async setupTestData(): Promise<void> {
    console.log('Setting up test data...');
    this.set('setupTime', new Date().toISOString());
  }

  getTestSummary(): Record<string, any> {
    return {
      testDataCount: this.testData.size,
      cleanupCallbacksCount: this.cleanupCallbacks.length,
      testDataKeys: Array.from(this.testData.keys()),
      setupTime: this.get('setupTime'),
    };
  }
}