import { TIMEOUTS } from '../../utils/timeouts';
import { Page, Locator, Response } from '@playwright/test';

/**
 * 平台状态常量
 */
export const PLATFORM_STATUS = {
  ENABLED: 0,
  DISABLED: 1,
} as const;

/**
 * 平台状态类型
 */
export type PlatformStatus = typeof PLATFORM_STATUS[keyof typeof PLATFORM_STATUS];

/**
 * 平台状态显示名称映射
 */
export const PLATFORM_STATUS_LABELS: Record<PlatformStatus, string> = {
  0: '启用',
  1: '禁用',
} as const;

/**
 * 平台数据接口
 */
export interface PlatformData {
  /** 平台名称 */
  platformName: string;
  /** 联系人 */
  contactPerson?: string;
  /** 联系电话 */
  contactPhone?: string;
  /** 联系邮箱 */
  contactEmail?: string;
}

/**
 * 网络响应数据接口
 */
export interface NetworkResponse {
  /** 请求URL */
  url: string;
  /** 请求方法 */
  method: string;
  /** 响应状态码 */
  status: number;
  /** 是否成功 */
  ok: boolean;
  /** 响应头 */
  responseHeaders: Record<string, string>;
  /** 响应体 */
  responseBody: unknown;
}

/**
 * 表单提交结果接口
 */
export interface FormSubmitResult {
  /** 提交是否成功 */
  success: boolean;
  /** 是否有错误 */
  hasError: boolean;
  /** 是否有成功消息 */
  hasSuccess: boolean;
  /** 错误消息 */
  errorMessage?: string;
  /** 成功消息 */
  successMessage?: string;
  /** 网络响应列表 */
  responses?: NetworkResponse[];
}

/**
 * 平台管理 Page Object
 *
 * 用于平台管理功能的 E2E 测试
 * 页面路径: /admin/platforms
 *
 * @example
 * ```typescript
 * const platformPage = new PlatformManagementPage(page);
 * await platformPage.goto();
 * await platformPage.createPlatform({ platformName: '测试平台' });
 * ```
 */
export class PlatformManagementPage {
  readonly page: Page;

  // ===== 页面级选择器 =====
  /** 页面标题 */
  readonly pageTitle: Locator;
  /** 创建平台按钮 */
  readonly createPlatformButton: Locator;
  /** 搜索输入框 */
  readonly searchInput: Locator;
  /** 搜索按钮 */
  readonly searchButton: Locator;
  /** 平台列表表格 */
  readonly platformTable: Locator;

  // ===== 对话框选择器 =====
  /** 创建对话框标题 */
  readonly createDialogTitle: Locator;
  /** 编辑对话框标题 */
  readonly editDialogTitle: Locator;

  // ===== 表单字段选择器 =====
  /** 平台名称输入框 */
  readonly platformNameInput: Locator;
  /** 联系人输入框 */
  readonly contactPersonInput: Locator;
  /** 联系电话输入框 */
  readonly contactPhoneInput: Locator;
  /** 联系邮箱输入框 */
  readonly contactEmailInput: Locator;

  // ===== 按钮选择器 =====
  /** 创建提交按钮 */
  readonly createSubmitButton: Locator;
  /** 更新提交按钮 */
  readonly updateSubmitButton: Locator;
  /** 取消按钮 */
  readonly cancelButton: Locator;

  // ===== 删除确认对话框选择器 =====
  /** 确认删除按钮 */
  readonly confirmDeleteButton: Locator;

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

    // 初始化页面级选择器
    // 使用 heading role 精确定位页面标题（避免与侧边栏按钮冲突）
    this.pageTitle = page.getByRole('heading', { name: '平台管理' });
    // 使用 data-testid 定位创建平台按钮
    this.createPlatformButton = page.getByTestId('create-platform-button');
    // 使用 data-testid 定位搜索相关元素
    this.searchInput = page.getByTestId('search-input');
    this.searchButton = page.getByTestId('search-button');
    // 平台列表表格
    this.platformTable = page.locator('table');

    // 对话框标题选择器
    this.createDialogTitle = page.getByTestId('create-platform-dialog-title');
    this.editDialogTitle = page.getByTestId('edit-platform-dialog-title');

    // 表单字段选择器 - 使用 data-testid
    this.platformNameInput = page.getByTestId('platform-name-input');
    this.contactPersonInput = page.getByTestId('contact-person-input');
    this.contactPhoneInput = page.getByTestId('contact-phone-input');
    this.contactEmailInput = page.getByTestId('contact-email-input');

    // 按钮选择器
    this.createSubmitButton = page.getByTestId('create-submit-button');
    this.updateSubmitButton = page.getByTestId('update-submit-button');
    this.cancelButton = page.getByRole('button', { name: '取消' });

    // 删除确认对话框按钮
    this.confirmDeleteButton = page.getByTestId('confirm-delete-button');
  }

  // ===== 导航和基础验证 =====

  /**
   * 导航到平台管理页面
   */
  async goto(): Promise<void> {
    await this.page.goto('/admin/platforms');
    await this.page.waitForLoadState('domcontentloaded');
    // 等待页面标题出现
    await this.pageTitle.waitFor({ state: 'visible', timeout: TIMEOUTS.PAGE_LOAD });
    // 等待表格数据加载
    await this.platformTable.waitFor({ state: 'visible', timeout: TIMEOUTS.PAGE_LOAD_LONG });
    await this.expectToBeVisible();
  }

  /**
   * 验证页面关键元素可见
   */
  async expectToBeVisible(): Promise<void> {
    await this.pageTitle.waitFor({ state: 'visible', timeout: TIMEOUTS.PAGE_LOAD });
    await this.createPlatformButton.waitFor({ state: 'visible', timeout: TIMEOUTS.TABLE_LOAD });
  }

  // ===== 对话框操作 =====

  /**
   * 打开创建平台对话框
   */
  async openCreateDialog(): Promise<void> {
    await this.createPlatformButton.click();
    // 等待对话框出现
    await this.page.waitForSelector('[role="dialog"]', { state: 'visible', timeout: TIMEOUTS.DIALOG });
  }

  /**
   * 打开编辑平台对话框
   * @param platformName 平台名称
   */
  async openEditDialog(platformName: string): Promise<void> {
    // 找到平台行并点击编辑按钮
    const platformRow = this.platformTable.locator('tbody tr').filter({ hasText: platformName });
    // 使用 role + name 组合定位编辑按钮，更健壮
    const editButton = platformRow.getByRole('button', { name: '编辑' });
    await editButton.click();

    // 等待编辑对话框出现
    await this.page.waitForSelector('[role="dialog"]', { state: 'visible', timeout: TIMEOUTS.DIALOG });
  }

  /**
   * 打开删除确认对话框
   * @param platformName 平台名称
   */
  async openDeleteDialog(platformName: string): Promise<void> {
    // 找到平台行并点击删除按钮
    const platformRow = this.platformTable.locator('tbody tr').filter({ hasText: platformName });
    // 使用 role + name 组合定位删除按钮，更健壮
    const deleteButton = platformRow.getByRole('button', { name: '删除' });
    await deleteButton.click();

    // 等待删除确认对话框出现
    await this.page.waitForSelector('[role="alertdialog"]', { state: 'visible', timeout: TIMEOUTS.DIALOG });
  }

  /**
   * 填写平台表单
   * @param data 平台数据
   */
  async fillPlatformForm(data: PlatformData): Promise<void> {
    // 等待表单出现
    await this.page.waitForSelector('form', { state: 'visible', timeout: TIMEOUTS.DIALOG });

    // 填写平台名称（必填字段）
    if (data.platformName) {
      await this.platformNameInput.fill(data.platformName);
    }

    // 填写联系人（可选字段）
    if (data.contactPerson !== undefined) {
      await this.contactPersonInput.fill(data.contactPerson);
    }

    // 填写联系电话（可选字段）
    if (data.contactPhone !== undefined) {
      await this.contactPhoneInput.fill(data.contactPhone);
    }

    // 填写联系邮箱（可选字段）
    if (data.contactEmail !== undefined) {
      await this.contactEmailInput.fill(data.contactEmail);
    }
  }

  /**
   * 提交表单
   * @returns 表单提交结果
   */
  async submitForm(): Promise<FormSubmitResult> {
    // 收集网络响应
    const responses: NetworkResponse[] = [];

    // 使用 waitForResponse 捕获特定 API 响应，避免并发测试中的监听器干扰
    const createPlatformPromise = this.page.waitForResponse(
      response => response.url().includes('createPlatform'),
      { timeout: TIMEOUTS.TABLE_LOAD }
    ).catch(() => null);

    const getAllPlatformsPromise = this.page.waitForResponse(
      response => response.url().includes('getAllPlatforms'),
      { timeout: TIMEOUTS.TABLE_LOAD }
    ).catch(() => null);

    try {
      // 点击提交按钮（优先使用 data-testid 选择器）
      // 尝试找到创建或更新按钮
      let submitButton = this.page.locator('[data-testid="create-submit-button"]');
      if (await submitButton.count() === 0) {
        submitButton = this.page.locator('[data-testid="update-submit-button"]');
      }

      // 如果 data-testid 选择器找不到，使用 role 选择器作为备用
      if (await submitButton.count() === 0) {
        submitButton = this.page.getByRole('button', { name: /^(创建|更新|保存)$/ });
      }

      console.debug('点击提交按钮，按钮数量:', await submitButton.count());
      await submitButton.click();

      // 等待 API 响应并收集
      const [createResponse, getAllResponse] = await Promise.all([
        createPlatformPromise,
        getAllPlatformsPromise
      ]);

      // 处理捕获到的响应
      if (createResponse) {
        const responseBody = await createResponse.text().catch(() => '');
        let jsonBody = null;
        try {
          jsonBody = JSON.parse(responseBody);
        } catch { }
        responses.push({
          url: createResponse.url(),
          method: createResponse.request()?.method() ?? 'UNKNOWN',
          status: createResponse.status(),
          ok: createResponse.ok(),
          responseHeaders: await createResponse.allHeaders().catch(() => ({})),
          responseBody: jsonBody || responseBody,
        });
        console.debug('平台 API 响应:', {
          url: createResponse.url(),
          status: createResponse.status(),
          ok: createResponse.ok()
        });
      }

      if (getAllResponse) {
        const responseBody = await getAllResponse.text().catch(() => '');
        let jsonBody = null;
        try {
          jsonBody = JSON.parse(responseBody);
        } catch { }
        responses.push({
          url: getAllResponse.url(),
          method: getAllResponse.request()?.method() ?? 'UNKNOWN',
          status: getAllResponse.status(),
          ok: getAllResponse.ok(),
          responseHeaders: await getAllResponse.allHeaders().catch(() => ({})),
          responseBody: jsonBody || responseBody,
        });
        console.debug('平台 API 响应:', {
          url: getAllResponse.url(),
          status: getAllResponse.status(),
          ok: getAllResponse.ok()
        });
      }

      // 等待网络请求完成
      try {
        await this.page.waitForLoadState('networkidle', { timeout: TIMEOUTS.DIALOG });
      } catch {
        console.debug('networkidle 超时，继续检查 Toast 消息');
      }
    } catch (error) {
      console.debug('submitForm 异常:', error);
    }

    // 主动等待 Toast 消息显示（最多等待 5 秒）
    const errorToast = this.page.locator('[data-sonner-toast][data-type="error"]');
    const successToast = this.page.locator('[data-sonner-toast][data-type="success"]');

    // 等待任一 Toast 出现
    await Promise.race([
      errorToast.waitFor({ state: 'attached', timeout: TIMEOUTS.DIALOG }).catch(() => false),
      successToast.waitFor({ state: 'attached', timeout: TIMEOUTS.DIALOG }).catch(() => false),
      new Promise(resolve => setTimeout(() => resolve(false), 5000))
    ]);

    // 再次检查 Toast 是否存在
    let hasError = (await errorToast.count()) > 0;
    let hasSuccess = (await successToast.count()) > 0;

    // 如果标准选择器找不到，尝试更宽松的选择器
    let fallbackErrorToast = this.page.locator('[data-sonner-toast]');
    let fallbackSuccessToast = this.page.locator('[data-sonner-toast]');

    if (!hasError && !hasSuccess) {
      // 尝试通过文本内容查找
      const allToasts = this.page.locator('[data-sonner-toast]');
      const count = await allToasts.count();
      for (let i = 0; i < count; i++) {
        const text = await allToasts.nth(i).textContent() || '';
        if (text.includes('成功') || text.toLowerCase().includes('success')) {
          hasSuccess = true;
          fallbackSuccessToast = allToasts.nth(i);
          break;
        } else if (text.includes('失败') || text.includes('错误') || text.toLowerCase().includes('error')) {
          hasError = true;
          fallbackErrorToast = allToasts.nth(i);
          break;
        }
      }
    }

    let errorMessage: string | null = null;
    let successMessage: string | null = null;

    if (hasError) {
      errorMessage = await ((await errorToast.count()) > 0 ? errorToast.first() : fallbackErrorToast).textContent();
    }
    if (hasSuccess) {
      successMessage = await ((await successToast.count()) > 0 ? successToast.first() : fallbackSuccessToast).textContent();
    }

    // 调试输出
    console.debug('submitForm 结果:', {
      hasError,
      hasSuccess,
      errorMessage,
      successMessage,
      responsesCount: responses.length
    });

    return {
      success: hasSuccess || (!hasError && !hasSuccess && responses.some(r => r.ok)),
      hasError,
      hasSuccess,
      errorMessage: errorMessage ?? undefined,
      successMessage: successMessage ?? undefined,
      responses,
    };
  }

  /**
   * 取消对话框
   */
  async cancelDialog(): Promise<void> {
    await this.cancelButton.click();
    await this.waitForDialogClosed();
  }

  /**
   * 等待对话框关闭
   */
  async waitForDialogClosed(): Promise<void> {
    // 首先检查对话框是否已经关闭
    const dialog = this.page.locator('[role="dialog"]');
    const count = await dialog.count();

    if (count === 0) {
      console.debug('对话框已经不存在，跳过等待');
      return;
    }

    // 等待对话框隐藏
    await dialog.waitFor({ state: 'hidden', timeout: TIMEOUTS.DIALOG })
      .catch(() => console.debug('对话框关闭超时，可能已经关闭'));

    // 额外等待以确保 DOM 更新完成
    await this.page.waitForTimeout(TIMEOUTS.MEDIUM);
  }

  /**
   * 确认删除操作
   */
  async confirmDelete(): Promise<void> {
    await this.confirmDeleteButton.click();
    // 等待确认对话框关闭和网络请求完成
    await this.page.waitForSelector('[role="alertdialog"]', { state: 'hidden', timeout: TIMEOUTS.DIALOG })
      .catch(() => console.debug('删除确认对话框关闭超时'));
    try {
      await this.page.waitForLoadState('domcontentloaded', { timeout: TIMEOUTS.DIALOG });
    } catch {
      // 继续执行
    }
    await this.page.waitForTimeout(TIMEOUTS.LONG);
  }

  /**
   * 取消删除操作
   */
  async cancelDelete(): Promise<void> {
    const cancelButton = this.page.locator('[role="alertdialog"]').getByRole('button', { name: '取消' });
    await cancelButton.click();
    await this.page.waitForSelector('[role="alertdialog"]', { state: 'hidden', timeout: TIMEOUTS.DIALOG })
      .catch(() => console.debug('删除确认对话框关闭超时（取消操作）'));
  }

  // ===== CRUD 操作方法 =====

  /**
   * 创建平台（完整流程）
   * @param data 平台数据
   * @returns 表单提交结果
   */
  async createPlatform(data: PlatformData): Promise<FormSubmitResult> {
    await this.openCreateDialog();
    await this.fillPlatformForm(data);
    const result = await this.submitForm();
    await this.waitForDialogClosed();
    return result;
  }

  /**
   * 编辑平台（完整流程）
   * @param platformName 平台名称
   * @param data 更新的平台数据
   * @returns 表单提交结果
   */
  async editPlatform(platformName: string, data: PlatformData): Promise<FormSubmitResult> {
    await this.openEditDialog(platformName);
    await this.fillPlatformForm(data);
    const result = await this.submitForm();
    await this.waitForDialogClosed();
    return result;
  }

  /**
   * 删除平台（使用 API 直接删除，绕过 UI）
   * @param platformName 平台名称
   * @returns 是否成功删除
   */
  async deletePlatform(platformName: string): Promise<boolean> {
    try {
      // 使用 API 直接删除，添加超时保护
      const result = await Promise.race([
        this.page.evaluate(async ({ platformName }) => {
          // 尝试多种可能的 token 键名
          let token = localStorage.getItem('token');
          if (!token) {
            token = localStorage.getItem('auth_token');
          }
          if (!token) {
            token = localStorage.getItem('accessToken');
          }
          if (!token) {
            const localStorageKeys = Object.keys(localStorage);
            for (const key of localStorageKeys) {
              if (key.toLowerCase().includes('token')) {
                token = localStorage.getItem(key);
                break;
              }
            }
          }

          if (!token) {
            return { success: false, notFound: true };
          }

          try {
            // 先获取平台列表，找到平台的 ID（限制 100 条）
            const listResponse = await fetch('http://localhost:8080/api/v1/platform/getAllPlatforms?skip=0&take=100', {
              headers: { 'Authorization': `Bearer ${token}` }
            });

            if (!listResponse.ok) {
              return { success: false, notFound: false };
            }

            const listData = await listResponse.json();

            // 根据平台名称查找平台 ID
            const platform = listData.data?.find((p: { name: string; platformName: string }) =>
              p.name === platformName || p.platformName === platformName
            );

            if (!platform) {
              // 平台不在列表中，可能已被删除或在其他页
              return { success: false, notFound: true };
            }

            // 使用平台 ID 删除 - POST 方法
            const deleteResponse = await fetch('http://localhost:8080/api/v1/platform/deletePlatform', {
              method: 'POST',
              headers: {
                'Authorization': `Bearer ${token}`,
                'Content-Type': 'application/json'
              },
              body: JSON.stringify({ id: platform.id })
            });

            if (!deleteResponse.ok) {
              return { success: false, notFound: false };
            }

            return { success: true };
          } catch (error) {
            return { success: false, notFound: false };
          }
        }, { platformName }),
        // 10 秒超时
        new Promise((resolve) => setTimeout(() => resolve({ success: false, timeout: true }), 10000))
      ]) as any;

      // 如果超时或平台找不到，返回 true（允许测试继续）
      if (result.timeout || result.notFound) {
        console.debug(`删除平台 "${platformName}" 超时或未找到，跳过`);
        return true;
      }

      if (!result.success) {
        console.debug(`删除平台 "${platformName}" 失败:`, result.error);
        return false;
      }

      // 删除成功后刷新页面，确保列表更新
      await this.page.reload();
      await this.page.waitForLoadState('domcontentloaded');
      return true;
    } catch (error) {
      console.debug(`删除平台 "${platformName}" 异常:`, error);
      // 发生异常时返回 true，避免阻塞测试
      return true;
    }
  }

  // ===== 搜索和验证方法 =====

  /**
   * 按平台名称搜索
   * @param name 平台名称
   * @returns 搜索结果是否包含目标平台
   */
  async searchByName(name: string): Promise<boolean> {
    await this.searchInput.fill(name);
    await this.searchButton.click();
    await this.page.waitForLoadState('domcontentloaded');
    await this.page.waitForTimeout(TIMEOUTS.LONG);
    // 验证搜索结果
    return await this.platformExists(name);
  }

  /**
   * 验证平台是否存在（使用精确匹配）
   * @param platformName 平台名称
   * @returns 平台是否存在
   */
  async platformExists(platformName: string): Promise<boolean> {
    const platformRow = this.platformTable.locator('tbody tr').filter({ hasText: platformName });
    const count = await platformRow.count();
    if (count === 0) return false;

    // 进一步验证第二列（平台名称列）的文本是否完全匹配
    // 表格列顺序：ID(0), 平台名称(1), 联系人(2), 联系电话(3), 联系邮箱(4), 创建时间(5), 操作(6)
    const nameCell = platformRow.locator('td').nth(1);
    const actualText = await nameCell.textContent();
    return actualText?.trim() === platformName;
  }
}
