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

export interface TestData {
  id: string;
  type: string;
  data: Record<string, any>;
  createdAt: Date;
}

export class TestDataManager {
  private static instance: TestDataManager;
  private createdData: Map<string, TestData[]> = new Map();
  private _page: Page | null = null;
  private static readonly API_BASE_URL = process.env.VITE_API_BASE_URL || 'http://localhost:8084';

  static getInstance(): TestDataManager {
    if (!TestDataManager.instance) {
      TestDataManager.instance = new TestDataManager();
    }
    return TestDataManager.instance;
  }

  setPage(page: Page): void {
    this._page = page;
  }

  getPage(): Page | null {
    return this._page;
  }

  async createUser(userData: {
    username: string;
    password: string;
    email: string;
    phone?: string;
    nickname?: string;
  }): Promise<TestData> {
    const response = await fetch(`${TestDataManager.API_BASE_URL}/api/users`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        ...userData,
        status: 1,
      }),
    });

    if (!response.ok) {
      throw new Error(`Failed to create user: ${response.statusText}`);
    }

    const result = await response.json();
    const testData: TestData = {
      id: result.data?.id || result.id,
      type: 'user',
      data: userData,
      createdAt: new Date(),
    };

    this.trackData('user', testData);
    return testData;
  }

  async createRole(roleData: {
    roleName: string;
    roleKey: string;
    roleSort?: number;
  }): Promise<TestData> {
    const response = await fetch(`${TestDataManager.API_BASE_URL}/api/roles`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        ...roleData,
        status: 1,
      }),
    });

    if (!response.ok) {
      throw new Error(`Failed to create role: ${response.statusText}`);
    }

    const result = await response.json();
    const testData: TestData = {
      id: result.data?.id || result.id,
      type: 'role',
      data: roleData,
      createdAt: new Date(),
    };

    this.trackData('role', testData);
    return testData;
  }

  async cleanup(type?: string): Promise<void> {
    const typesToClean = type ? [type] : Array.from(this.createdData.keys());

    for (const dataType of typesToClean) {
      const items = this.createdData.get(dataType) || [];
      
      for (const item of items.reverse()) {
        try {
          await this.deleteData(item);
        } catch (error) {
          console.error(`Failed to cleanup ${dataType} ${item.id}:`, error);
        }
      }

      this.createdData.delete(dataType);
    }
  }

  private async deleteData(data: TestData): Promise<void> {
    const endpoint = this.getEndpoint(data.type);
    await fetch(`${TestDataManager.API_BASE_URL}${endpoint}/${data.id}`, {
      method: 'DELETE',
    });
  }

  private getEndpoint(type: string): string {
    const endpoints: Record<string, string> = {
      user: '/api/users',
      role: '/api/roles',
      menu: '/api/menus',
      config: '/api/configs',
    };
    return endpoints[type] || `/api/${type}s`;
  }

  private trackData(type: string, data: TestData): void {
    if (!this.createdData.has(type)) {
      this.createdData.set(type, []);
    }
    this.createdData.get(type)!.push(data);
  }

  getCreatedData(type: string): TestData[] {
    return this.createdData.get(type) || [];
  }

  clearTracking(): void {
    this.createdData.clear();
  }
}

export function getTestDataManager(): TestDataManager {
  return TestDataManager.getInstance();
}
