import { TIMEOUTS } from '../../utils/timeouts';
import { Page, Locator } from '@playwright/test';
import { selectRadixOptionAsync } from '@d8d/e2e-test-utils';

/**
 * API 基础 URL
 */
const API_BASE_URL = process.env.E2E_BASE_URL || 'http://localhost:8080';

/**
 * 公司状态常量
 */
export const COMPANY_STATUS = {
  ENABLED: 1,
  DISABLED: 0,
} as const;

/**
 * 公司状态类型
 */
export type CompanyStatus = typeof COMPANY_STATUS[keyof typeof COMPANY_STATUS];

/**
 * 公司状态显示名称映射
 */
export const COMPANY_STATUS_LABELS: Record<CompanyStatus, string> = {
  1: '启用',
  0: '禁用',
} as const;

/**
 * 公司数据接口
 */
export interface CompanyData {
  /** 平台ID（可选） */
  platformId?: number;
  /** 公司名称（必填） */
  companyName: string;
  /** 联系人（可选） */
  contactPerson?: string;
  /** 联系电话（可选） */
  contactPhone?: string;
  /** 联系邮箱（可选） */
  contactEmail?: string;
  /** 地址（可选） */
  address?: 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/companies
 *
 * @example
 * ```typescript
 * const companyPage = new CompanyManagementPage(page);
 * await companyPage.goto();
 * await companyPage.createCompany({ companyName: '测试公司' });
 * ```
 */
export class CompanyManagementPage {
  readonly page: Page;

  // ===== API 端点常量 =====
  /** 获取所有公司列表 API */
  private static readonly API_GET_ALL_COMPANIES = `${API_BASE_URL}/api/v1/company/getAllCompanies`;
  /** 删除公司 API */
  private static readonly API_DELETE_COMPANY = `${API_BASE_URL}/api/v1/company/deleteCompany`;

  // ===== 页面级选择器 =====
  /** 页面标题 */
  readonly pageTitle: Locator;
  /** 创建公司按钮 */
  readonly createCompanyButton: Locator;
  /** 搜索输入框 */
  readonly searchInput: Locator;
  /** 搜索按钮 */
  readonly searchButton: Locator;
  /** 公司列表表格 */
  readonly companyTable: Locator;

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

  // ===== 表单字段选择器 =====
  /** 平台选择器容器 */
  readonly platformSelector: Locator;
  /** 公司名称输入框 */
  readonly companyNameInput: Locator;
  /** 联系人输入框 */
  readonly contactPersonInput: Locator;
  /** 联系电话输入框 */
  readonly contactPhoneInput: Locator;
  /** 联系邮箱输入框 */
  readonly contactEmailInput: Locator;
  /** 地址输入框 */
  readonly addressInput: Locator;

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

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

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

    // 初始化页面级选择器
    // 使用 heading role 精确定位页面标题（避免与侧边栏按钮冲突）
    this.pageTitle = page.locator('[data-slot="card-title"]').filter({ hasText: '公司管理' });
    // 使用 data-testid 定位创建公司按钮
    this.createCompanyButton = page.getByTestId('create-company-button');
    // 使用 data-testid 定位搜索相关元素
    this.searchInput = page.getByTestId('search-company-input');
    this.searchButton = page.getByTestId('search-company-button');
    // 公司列表表格
    this.companyTable = page.locator('table');

    // 对话框标题选择器
    this.createDialogTitle = page.getByRole('dialog').getByText('创建公司');
    this.editDialogTitle = page.getByRole('dialog').getByText('编辑公司');

    // 表单字段选择器 - 使用 data-testid（创建表单）
    // 平台选择器使用 label 文本定位，因为 data-testid 可能不存在
    // 实际标签文本是 "平台（可选）" 或 "平台"
    this.platformSelector = page.getByRole('dialog').getByText(/^平台/);
    this.companyNameInput = page.locator('[data-testid="create-company-name-input"]');
    this.contactPersonInput = page.locator('[data-testid="create-company-contact-person-input"]');
    this.contactPhoneInput = page.locator('[data-testid="create-company-contact-phone-input"]');
    this.contactEmailInput = page.locator('[data-testid="create-company-contact-email-input"]');
    this.addressInput = page.locator('[data-testid="create-company-address-input"]');

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

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

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

  /**
   * 导航到公司管理页面
   */
  async goto(): Promise<void> {
    await this.page.goto('/admin/companies');
    await this.page.waitForLoadState('domcontentloaded');
    // 等待页面标题出现
    await this.pageTitle.waitFor({ state: 'visible', timeout: TIMEOUTS.PAGE_LOAD });
    // 等待表格数据加载
    await this.companyTable.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.createCompanyButton.waitFor({ state: 'visible', timeout: TIMEOUTS.TABLE_LOAD });
  }

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

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

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

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

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

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

  /**
   * 填写公司表单
   * @param data 公司数据
   * @param platformName 平台名称（当需要选择平台时必须提供）
   */
  async fillCompanyForm(data: CompanyData, platformName?: string): Promise<void> {
    // 等待表单出现
    await this.page.waitForSelector('form', { state: 'visible', timeout: TIMEOUTS.DIALOG });

    // 填写平台选择器（可选字段）
    if (data.platformId !== undefined && platformName) {
      // 使用 @d8d/e2e-test-utils 的 selectRadixOptionAsync 选择平台
      await selectRadixOptionAsync(this.page, '平台', platformName);
    }

    // 填写公司名称（必填字段）
    if (data.companyName) {
      await this.companyNameInput.fill(data.companyName);
    }

    // 填写联系人（可选字段）
    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);
    }

    // 填写地址（可选字段）
    if (data.address !== undefined) {
      await this.addressInput.fill(data.address);
    }
  }

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

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

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

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

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

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

      await submitButton.click();

      // 等待 API 响应并收集
      const [createResponse, updateResponse, getAllResponse] = await Promise.all([
        createCompanyPromise,
        updateCompanyPromise,
        getAllCompaniesPromise
      ]);

      // 处理捕获到的响应（创建或更新）
      const mainResponse = createResponse || updateResponse;
      if (mainResponse) {
        const responseBody = await mainResponse.text().catch(() => '');
        let jsonBody = null;
        try {
          jsonBody = JSON.parse(responseBody);
        } catch { }
        responses.push({
          url: mainResponse.url(),
          method: mainResponse.request()?.method() ?? 'UNKNOWN',
          status: mainResponse.status(),
          ok: mainResponse.ok(),
          responseHeaders: await mainResponse.allHeaders().catch(() => ({})),
          responseBody: jsonBody || responseBody,
        });
      }

      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,
        });
      }

      // 等待网络请求完成
      try {
        await this.page.waitForLoadState('networkidle', { timeout: TIMEOUTS.DIALOG });
      } catch {
        // 继续检查 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();
    }

    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) {
      return;
    }

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

    // 额外等待以确保 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(() => {
        // 继续执行
      });
    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(() => {
        // 继续执行
      });
  }

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

  /**
   * 创建公司（完整流程）
   * @param data 公司数据
   * @param platformName 平台名称（当需要选择平台时必须提供）
   * @returns 表单提交结果
   */
  async createCompany(data: CompanyData, platformName?: string): Promise<FormSubmitResult> {
    await this.openCreateDialog();
    await this.fillCompanyForm(data, platformName);
    const result = await this.submitForm();
    await this.waitForDialogClosed();
    return result;
  }

  /**
   * 编辑公司（完整流程）
   * @param companyName 公司名称
   * @param data 更新的公司数据
   * @param platformName 平台名称（当需要选择平台时必须提供）
   * @returns 表单提交结果
   */
  async editCompany(companyName: string, data: CompanyData, platformName?: string): Promise<FormSubmitResult> {
    await this.openEditDialog(companyName);
    await this.fillCompanyForm(data, platformName);
    const result = await this.submitForm();
    await this.waitForDialogClosed();
    return result;
  }

  /**
   * 删除公司（使用 API 直接删除，绕过 UI）
   * @param companyName 公司名称
   * @returns 是否成功删除
   */
  async deleteCompany(companyName: string): Promise<boolean> {
    try {
      // 使用 API 直接删除，添加超时保护
      const result = await Promise.race([
        this.page.evaluate(async ({ companyName, apiGetAll, apiDelete }) => {
          // 尝试获取 token（使用标准键名）
          let token = localStorage.getItem('token') ||
                      localStorage.getItem('auth_token') ||
                      localStorage.getItem('accessToken');

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

          try {
            // 先获取公司列表，找到公司的 ID（限制 100 条）
            const listResponse = await fetch(`${apiGetAll}?skip=0&take=100`, {
              headers: { 'Authorization': `Bearer ${token}` }
            });

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

            const listData = await listResponse.json();

            // 根据公司名称查找公司 ID
            const company = listData.data?.find((c: { companyName: string }) =>
              c.companyName === companyName
            );

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

            // 使用公司 ID 删除 - POST 方法
            const deleteResponse = await fetch(apiDelete, {
              method: 'POST',
              headers: {
                'Authorization': `Bearer ${token}`,
                'Content-Type': 'application/json'
              },
              body: JSON.stringify({ id: company.id })
            });

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

            return { success: true };
          } catch (error) {
            return { success: false, notFound: false };
          }
        }, {
          companyName,
          apiGetAll: CompanyManagementPage.API_GET_ALL_COMPANIES,
          apiDelete: CompanyManagementPage.API_DELETE_COMPANY
        }),
        // 10 秒超时
        new Promise((resolve) => setTimeout(() => resolve({ success: false, timeout: true }), 10000))
      ]) as any;

      // 如果超时：打印警告但返回 true（允许测试继续）
      if (result.timeout) {
        console.debug(`删除公司 "${companyName}" 超时，但允许测试继续`);
        return true;
      }

      // 如果公司找不到：认为删除成功（可能已被其他测试删除）
      if (result.notFound) {
        console.debug(`删除公司 "${companyName}": 公司不存在，认为已删除`);
        return true;
      }

      if (result.noToken) {
        console.debug('删除公司失败: 未找到认证 token');
        return false;
      }

      if (!result.success) {
        console.debug(`删除公司 "${companyName}" 失败: 未知错误`);
        return false;
      }

      // 删除成功后刷新页面，确保列表更新
      await this.page.reload();
      await this.page.waitForLoadState('domcontentloaded');
      return true;
    } catch (error) {
      console.debug(`删除公司 "${companyName}" 异常:`, 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.companyExists(name);
  }

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

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