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

/**
 * 区域层级常量
 */
export const REGION_LEVEL = {
  PROVINCE: 1,
  CITY: 2,
  DISTRICT: 3,
} as const;

/**
 * 区域层级类型
 */
export type RegionLevel = typeof REGION_LEVEL[keyof typeof REGION_LEVEL];

/**
 * 区域状态常量
 */
export const REGION_STATUS = {
  ENABLED: 0,
  DISABLED: 1,
} as const;

/**
 * 区域数据接口
 */
export interface RegionData {
  /** 区域名称 */
  name: string;
  /** 行政区划代码 */
  code?: string;
  /** 区域层级（1=省, 2=市, 3=区） */
  level?: RegionLevel;
  /** 父级区域ID */
  parentId?: number | null;
  /** 状态（0=启用, 1=禁用） */
  isDisabled?: typeof REGION_STATUS[keyof typeof REGION_STATUS];
}

/**
 * 网络响应数据
 */
export interface NetworkResponse {
  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/areas
 *
 * @example
 * ```typescript
 * const regionPage = new RegionManagementPage(page);
 * await regionPage.goto();
 * await regionPage.createProvince({ name: '测试省', code: '110000' });
 * ```
 */
export class RegionManagementPage {
  readonly page: Page;

  // 页面级选择器
  readonly pageTitle: Locator;
  readonly addProvinceButton: Locator;
  readonly treeContainer: Locator;

  constructor(page: Page) {
    this.page = page;
    // 使用精确文本匹配获取页面标题
    this.pageTitle = page.getByText('省市区树形管理', { exact: true });
    // 使用 role + name 组合获取新增按钮（比单独 text 更健壮）
    this.addProvinceButton = page.getByRole('button', { name: '新增省', exact: true });
    // 使用 Card 组件的结构来定位树形容器（比 Tailwind 类更健壮）
    // 根据实际 DOM: Card > CardContent > AreaTreeAsync > div.border.rounded-lg.bg-background
    this.treeContainer = page.locator('.border.rounded-lg').first();
  }

  /**
   * 导航到区域管理页面
   */
  async goto() {
    await this.page.goto('/admin/areas');
    await this.page.waitForLoadState('domcontentloaded');
    // 等待页面标题出现
    await this.pageTitle.waitFor({ state: 'visible', timeout: TIMEOUTS.PAGE_LOAD });
    // 等待树形结构加载
    await this.treeContainer.waitFor({ state: 'visible', timeout: TIMEOUTS.PAGE_LOAD_LONG });
    await this.expectToBeVisible();
  }

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

  /**
   * 打开新增省对话框
   */
  async openCreateProvinceDialog() {
    await this.addProvinceButton.click();
    // 等待对话框出现
    await this.page.waitForSelector('[role="dialog"]', { state: 'visible', timeout: TIMEOUTS.DIALOG });
  }

  /**
   * 打开新增子区域对话框
   * @param parentName 父级区域名称
   * @param childType 子区域类型（'市'、'区' 或 '街道'）
   */
  async openAddChildDialog(parentName: string, childType: '市' | '区' | '街道') {
    // 首先确保父级节点可见
    const parentText = this.treeContainer.getByText(parentName);
    await parentText.waitFor({ state: 'visible', timeout: TIMEOUTS.DIALOG });

    // 找到父级节点并悬停，使操作按钮可见
    const regionRow = parentText.locator('xpath=ancestor::div[contains(@class, "group")][1]');
    await regionRow.hover();

    // 找到对应的"新增市"、"新增区"或"新增街道"按钮
    const buttonName = childType === '市' ? '新增市' : childType === '区' ? '新增区' : '新增街道';
    const button = regionRow.getByRole('button', { name: buttonName });

    // 等待按钮可见并可点击
    await button.waitFor({ state: 'visible', timeout: TIMEOUTS.ELEMENT_VISIBLE_SHORT });
    await button.click({ timeout: TIMEOUTS.DIALOG });

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

  /**
   * 打开编辑区域对话框
   * @param regionName 区域名称
   */
  async openEditDialog(regionName: string) {
    await this.waitForTreeLoaded();

    // 先尝试直接查找区域
    const allRegions = this.treeContainer.getByText(regionName, { exact: true });
    let count = await allRegions.count();

    // 如果找不到，可能区域在折叠的父节点下
    // 对于市级或区级区域，需要展开对应的省级节点
    if (count === 0 && (regionName.includes('市') || regionName.includes('区'))) {
      console.debug(`区域 "${regionName}" 未找到，尝试展开所有可能的省级节点`);

      // 查找所有省级节点（以"省"结尾的区域名称）
      const provinceTexts = this.treeContainer.getByText(/省$/);
      const provinceCount = await provinceTexts.count();
      console.debug(`找到 ${provinceCount} 个省级节点`);

      // 展开所有省级节点（不提前退出）
      for (let i = 0; i < provinceCount; i++) {
        try {
          const provinceName = await provinceTexts.nth(i).textContent();
          if (provinceName) {
            const trimmedName = provinceName.trim();
            console.debug(`尝试展开省节点: ${trimmedName}`);
            await this.expandNode(trimmedName);
            await this.page.waitForTimeout(TIMEOUTS.SHORT);
          }
        } catch (error) {
          // 忽略展开失败，继续下一个
        }
      }

      // 再次检查目标区域
      count = await allRegions.count();
      console.debug(`展开所有省节点后，目标区域 "${regionName}" 数量: ${count}`);
    }

    if (count === 0) {
      throw new Error(`区域 "${regionName}" 未找到，即使展开所有省级节点后`);
    }

    // 找到目标区域（如果有多个，使用最后一个）
    const targetIndex = count - 1;
    const regionText = allRegions.nth(targetIndex >= 0 ? targetIndex : 0);

    await regionText.scrollIntoViewIfNeeded();
    await this.page.waitForTimeout(TIMEOUTS.MEDIUM);

    const regionRow = regionText.locator('xpath=ancestor::div[contains(@class, "group")][1]');
    await regionRow.hover();
    await this.page.waitForTimeout(TIMEOUTS.SHORT);

    const button = regionRow.getByRole('button', { name: '编辑' });
    await button.waitFor({ state: 'visible', timeout: TIMEOUTS.ELEMENT_VISIBLE_SHORT });
    await button.click({ timeout: TIMEOUTS.DIALOG });

    await this.page.waitForSelector('[role="dialog"]', { state: 'visible', timeout: TIMEOUTS.DIALOG });
  }

  /**
   * 打开删除确认对话框
   * @param regionName 区域名称
   */
  async openDeleteDialog(regionName: string) {
    await this.waitForTreeLoaded();

    // 先尝试直接查找区域
    const allRegions = this.treeContainer.getByText(regionName, { exact: true });
    let count = await allRegions.count();

    // 如果找不到，可能区域在折叠的父节点下
    // 对于市级或区级区域，需要展开对应的省级节点
    if (count === 0 && (regionName.includes('市') || regionName.includes('区') || regionName.includes('街道'))) {
      console.debug(`区域 "${regionName}" 未找到，尝试展开所有可能的省级节点`);

      // 查找所有省级节点（以"省"结尾的区域名称）
      const provinceTexts = this.treeContainer.getByText(/省$/);
      const provinceCount = await provinceTexts.count();
      console.debug(`找到 ${provinceCount} 个省级节点`);

      // 展开所有省级节点（不提前退出）
      for (let i = 0; i < provinceCount; i++) {
        try {
          const provinceName = await provinceTexts.nth(i).textContent();
          if (provinceName) {
            const trimmedName = provinceName.trim();
            console.debug(`尝试展开省节点: ${trimmedName}`);
            await this.expandNode(trimmedName);
            await this.page.waitForTimeout(TIMEOUTS.SHORT);
          }
        } catch (error) {
          // 忽略展开失败，继续下一个
        }
      }

      // 再次检查目标区域
      count = await allRegions.count();
      console.debug(`展开所有省节点后，目标区域 "${regionName}" 数量: ${count}`);
    }

    // 如果还是找不到，尝试展开市级节点（用于区级和街道）
    if (count === 0 && (regionName.includes('区') || regionName.includes('街道'))) {
      console.debug(`区域 "${regionName}" 仍未找到，尝试展开所有市级节点`);

      const cityTexts = this.treeContainer.getByText(/市$/);
      const cityCount = await cityTexts.count();
      console.debug(`找到 ${cityCount} 个市级节点`);

      for (let i = 0; i < cityCount; i++) {
        try {
          const cityName = await cityTexts.nth(i).textContent();
          if (cityName) {
            const trimmedName = cityName.trim();
            console.debug(`尝试展开市节点: ${trimmedName}`);
            await this.expandNode(trimmedName);
            await this.page.waitForTimeout(TIMEOUTS.SHORT);
          }
        } catch (error) {
          // 忽略展开失败，继续下一个
        }
      }

      count = await allRegions.count();
      console.debug(`展开所有市节点后，目标区域 "${regionName}" 数量: ${count}`);
    }

    if (count === 0) {
      throw new Error(`区域 "${regionName}" 未找到，即使展开所有节点后`);
    }

    // 找到目标区域（如果有多个，使用最后一个）
    const targetIndex = count - 1;
    const regionText = allRegions.nth(targetIndex >= 0 ? targetIndex : 0);

    await regionText.scrollIntoViewIfNeeded();
    await this.page.waitForTimeout(TIMEOUTS.MEDIUM);

    const regionRow = regionText.locator('xpath=ancestor::div[contains(@class, "group")][1]');
    await regionRow.hover();
    await this.page.waitForTimeout(TIMEOUTS.SHORT);

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

  /**
   * 打开状态切换确认对话框
   * @param regionName 区域名称
   */
  async openToggleStatusDialog(regionName: string) {
    // 等待树形结构加载完成
    await this.waitForTreeLoaded();

    // 找到所有匹配的区域文本，使用最后一个（最新创建的）
    const allRegions = this.treeContainer.getByText(regionName, { exact: true });
    const count = await allRegions.count();
    if (count === 0) {
      throw new Error(`区域 "${regionName}" 未找到`);
    }

    // 使用最后一个匹配项（最新创建的）
    const targetIndex = count - 1;
    const regionText = allRegions.nth(targetIndex);
    await regionText.waitFor({ state: 'visible', timeout: TIMEOUTS.DIALOG });

    // 滚动到元素位置
    await regionText.scrollIntoViewIfNeeded();
    await this.page.waitForTimeout(TIMEOUTS.SHORT);

    const regionRow = regionText.locator('xpath=ancestor::div[contains(@class, "group")][1]');
    await regionRow.hover();
    await this.page.waitForTimeout(TIMEOUTS.SHORT);

    // 在区域行内查找"启用"或"禁用"按钮（操作按钮组中的状态切换按钮）
    const statusButton = regionRow.getByRole('button', { name: /^(启用|禁用)$/ });
    await statusButton.waitFor({ state: 'visible', timeout: TIMEOUTS.ELEMENT_VISIBLE_SHORT });
    await statusButton.click({ timeout: TIMEOUTS.DIALOG });

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

  /**
   * 填写区域表单
   * @param data 区域数据
   */
  async fillRegionForm(data: RegionData) {
    // 等待表单出现
    await this.page.waitForSelector('form', { state: 'visible', timeout: TIMEOUTS.DIALOG });

    // 填写区域名称
    if (data.name) {
      await this.page.getByLabel('区域名称').fill(data.name);
    }

    // 填写行政区划代码
    if (data.code) {
      await this.page.getByLabel('行政区划代码').fill(data.code);
    }
  }

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

    // 监听所有网络请求
    const responseHandler = async (response: Response) => {
      const url = response.url();
      // 监听区域管理相关的 API 请求
      if (url.includes('/areas') || url.includes('area')) {
        const requestBody = response.request()?.postData();
        const responseBody = await response.text().catch(() => '');
        let jsonBody = null;
        try {
          jsonBody = JSON.parse(responseBody);
        } catch {
          // 不是 JSON 响应
        }

        responses.push({
          url,
          method: response.request()?.method() ?? 'UNKNOWN',
          status: response.status(),
          ok: response.ok(),
          responseHeaders: await response.allHeaders().catch(() => ({})),
          responseBody: jsonBody || responseBody,
        });
      }
    };

    this.page.on('response', responseHandler);

    // 点击提交按钮（创建或更新）
    const submitButton = this.page.getByRole('button', { name: /^(创建|更新)$/ });
    await submitButton.click();

    // 等待网络请求完成 - 使用更宽松的策略
    // networkidle 可能因后台轮询而失败，使用 domcontentloaded 代替
    try {
      await this.page.waitForLoadState('domcontentloaded', { timeout: TIMEOUTS.DIALOG });
    } catch {
      // domcontentloaded 也可能失败，继续执行
    }
    // 额外等待，给 API 响应一些时间
    await this.page.waitForTimeout(TIMEOUTS.LONG);

    // 移除监听器
    this.page.off('response', responseHandler);

    // 等待对话框关闭或错误出现
    await this.page.waitForTimeout(TIMEOUTS.LONGER);

    // 检查 Toast 消息
    const errorToast = this.page.locator('[data-sonner-toast][data-type="error"]');
    const successToast = this.page.locator('[data-sonner-toast][data-type="success"]');

    const hasError = await errorToast.count() > 0;
    const hasSuccess = await successToast.count() > 0;

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

    if (hasError) {
      errorMessage = await errorToast.first().textContent();
    }
    if (hasSuccess) {
      successMessage = await successToast.first().textContent();
    }

    return {
      success: hasSuccess || (!hasError && !hasSuccess),
      hasError,
      hasSuccess,
      errorMessage: errorMessage ?? undefined,
      successMessage: successMessage ?? undefined,
      responses,
    };
  }

  /**
   * 取消对话框
   */
  async cancelDialog() {
    const cancelButton = this.page.getByRole('button', { name: '取消' });
    await cancelButton.click();
    await this.waitForDialogClosed();
  }

  /**
   * 等待对话框关闭
   */
  async waitForDialogClosed() {
    const dialog = this.page.locator('[role="dialog"]');
    await dialog.waitFor({ state: 'hidden', timeout: TIMEOUTS.DIALOG }).catch(() => {});
    await this.page.waitForTimeout(TIMEOUTS.MEDIUM);
  }

  /**
   * 确认删除操作
   */
  async confirmDelete() {
    const confirmButton = this.page.getByRole('button', { name: /^确认删除$/ });
    await confirmButton.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() {
    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(() => {});
  }

  /**
   * 确认状态切换操作
   */
  async confirmToggleStatus() {
    // 监听 API 响应
    let apiResponse: any = null;
    const responseHandler = async (response: Response) => {
      const url = response.url();
      if (url.includes('/areas') || url.includes('area')) {
        try {
          const responseBody = await response.text();
          apiResponse = {
            url,
            status: response.status(),
            body: responseBody,
          };
          console.debug(`API 响应: ${url}, status=${response.status()}`);
        } catch {
          // ignore
        }
      }
    };

    this.page.on('response', responseHandler);

    const confirmButton = this.page.locator('[role="alertdialog"]').getByRole('button', { name: '确认' });
    await confirmButton.click();

    // 等待 API 响应
    await this.page.waitForTimeout(TIMEOUTS.VERY_LONG);

    this.page.off('response', responseHandler);

    if (apiResponse) {
      console.debug(`状态切换 API 响应: status=${apiResponse.status}, body=${apiResponse.body}`);
    }

    // 等待确认对话框关闭和网络请求完成
    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 cancelToggleStatus() {
    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(() => {});
  }

  /**
   * 验证区域是否存在
   * @param regionName 区域名称
   * @returns 区域是否存在
   */
  async regionExists(regionName: string): Promise<boolean> {
    console.debug(`regionExists: 查找 "${regionName}"`);
    try {
      // 等待元素出现，最多等待 5 秒
      const regionElement = this.treeContainer.getByText(regionName, { exact: true });
      await regionElement.waitFor({ state: 'attached', timeout: TIMEOUTS.DIALOG });
      console.debug(`regionExists: 找到 "${regionName}"`);
      return true;
    } catch (error) {
      console.debug(`regionExists: 未找到 "${regionName}", error:`, error);
      // 元素未出现
      return false;
    }
  }

  /**
   * 展开区域节点
   * @param regionName 区域名称
   */
  async expandNode(regionName: string) {
    console.debug(`expandNode: 尝试展开 "${regionName}"`);

    // 找到区域文本元素 - 使用更精确的定位策略
    // 使用 filter 确保只匹配完全独立的文本节点，而不是包含按钮的元素
    const allRegionTexts = this.treeContainer.getByText(regionName, { exact: true });
    const count = await allRegionTexts.count();
    console.debug(`expandNode: 找到 ${count} 个匹配 "${regionName}" 的元素`);

    if (count === 0) {
      throw new Error(`区域 "${regionName}" 未找到`);
    }

    // 使用第一个匹配项
    const regionText = allRegionTexts.first();
    await regionText.waitFor({ state: 'visible', timeout: TIMEOUTS.DIALOG });

    // 滚动到元素位置
    await regionText.scrollIntoViewIfNeeded();
    await this.page.waitForTimeout(TIMEOUTS.SHORT);

    // 找到区域节点的展开按钮
    const regionRow = regionText.locator('xpath=ancestor::div[contains(@class, "group")][1]');
    const expandButton = regionRow.locator('button').filter({ has: regionRow.locator('svg') }).first();

    const buttonCount = await expandButton.count();
    console.debug(`expandNode: 展开按钮数量: ${buttonCount}`);

    if (buttonCount > 0) {
      // 悬停以确保按钮可见
      await regionRow.hover();
      await this.page.waitForTimeout(TIMEOUTS.VERY_SHORT);

      // 点击展开按钮
      await expandButton.click({ timeout: TIMEOUTS.DIALOG });

      // 等待懒加载的子节点出现
      await this.page.waitForTimeout(TIMEOUTS.MEDIUM);

      console.debug(`expandNode: 成功展开 "${regionName}"`);
    } else {
      console.debug(`expandNode: 没有找到展开按钮，可能已经是展开状态或没有子节点`);
    }
  }

  /**
   * 收起区域节点
   * @param regionName 区域名称
   */
  async collapseNode(regionName: string) {
    // 找到区域节点的收起按钮
    const regionRow = this.treeContainer.getByText(regionName, { exact: true }).locator('xpath=ancestor::div[contains(@class, "group")][1]');
    const collapseButton = regionRow.locator('button').filter({ has: regionRow.locator('svg') }).first();

    const count = await collapseButton.count();
    if (count > 0) {
      await collapseButton.click();
      await this.page.waitForTimeout(TIMEOUTS.MEDIUM);
    }
  }

  /**
   * 获取区域的状态
   * @param regionName 区域名称
   * @returns 区域状态（'启用' 或 '禁用'）
   */
  async getRegionStatus(regionName: string): Promise<'启用' | '禁用' | null> {
    // 等待树形结构加载完成
    await this.waitForTreeLoaded();

    // 找到所有匹配的区域文本
    const allRegions = this.treeContainer.getByText(regionName, { exact: true });
    const count = await allRegions.count();
    console.debug(`getRegionStatus: 查找 "${regionName}", 找到 ${count} 个匹配`);

    if (count === 0) return null;

    // 如果有多个匹配，尝试找到最后一个（最新创建的）
    // 因为新创建的区域通常在列表的末尾
    const targetIndex = count - 1;
    const regionText = allRegions.nth(targetIndex);

    // 确保元素可见
    await regionText.scrollIntoViewIfNeeded();
    await this.page.waitForTimeout(TIMEOUTS.MEDIUM);

    // 根据DOM结构，状态是区域名称后的第4个 generic 元素
    // regionName 的父级 generic 下有: name, level, code, status
    const regionNameParent = regionText.locator('xpath=..');
    // 获取所有子元素
    const children = regionNameParent.locator('xpath=./generic');
    const childCount = await children.count();
    console.debug(`getRegionStatus: regionNameParent 下有 ${childCount} 个子元素`);

    // 状态通常是最后一个子元素或倒数第二个
    // 根据DOM结构，状态在第4个位置（索引3，从0开始）
    if (childCount >= 4) {
      const statusElement = children.nth(3);
      const statusText = await statusElement.textContent();
      console.debug(`getRegionStatus: 从位置3获取状态: "${statusText}"`);
      if (statusText === '启用' || statusText === '禁用') {
        return statusText;
      }
    }

    // 如果上述方法失败，尝试在父级内查找状态
    const enabledText = regionNameParent.getByText('启用', { exact: true });
    const disabledText = regionNameParent.getByText('禁用', { exact: true });

    const hasEnabled = await enabledText.count() > 0;
    const hasDisabled = await disabledText.count() > 0;

    console.debug(`getRegionStatus: "${regionName}" hasEnabled=${hasEnabled}, hasDisabled=${hasDisabled}`);

    if (hasEnabled && !hasDisabled) return '启用';
    if (hasDisabled && !hasEnabled) return '禁用';

    // 如果两者都有，需要更精确的选择器
    // 状态在操作按钮之前，所以应该先找到状态元素
    const allTexts = await regionNameParent.allTextContents();
    console.debug(`getRegionStatus: 所有文本内容:`, allTexts);

    // 检查最后一个非空文本是否是状态
    for (const text of allTexts) {
      if (text === '启用') return '启用';
      if (text === '禁用') return '禁用';
    }

    return null;
  }

  /**
   * 创建省
   * @param data 省份数据
   * @returns 表单提交结果
   */
  async createProvince(data: RegionData): Promise<FormSubmitResult> {
    await this.openCreateProvinceDialog();
    await this.fillRegionForm(data);
    const result = await this.submitForm();
    await this.waitForDialogClosed();
    return result;
  }

  /**
   * 创建子区域（市、区或街道）
   * @param parentName 父级区域名称
   * @param childType 子区域类型（'市'、'区' 或 '街道'）
   * @param data 子区域数据
   * @returns 表单提交结果
   */
  async createChildRegion(
    parentName: string,
    childType: '市' | '区' | '街道',
    data: RegionData
  ): Promise<FormSubmitResult> {
    await this.openAddChildDialog(parentName, childType);
    await this.fillRegionForm(data);
    const result = await this.submitForm();
    await this.waitForDialogClosed();
    return result;
  }

  /**
   * 编辑区域
   * @param regionName 区域名称
   * @param data 更新的区域数据
   * @returns 表单提交结果
   */
  async editRegion(regionName: string, data: RegionData): Promise<FormSubmitResult> {
    await this.openEditDialog(regionName);
    await this.fillRegionForm(data);
    const result = await this.submitForm();
    await this.waitForDialogClosed();
    return result;
  }

  /**
   * 删除区域
   * @param regionName 区域名称
   * @returns 是否成功（true = 成功删除, false = 删除失败或取消）
   */
  async deleteRegion(regionName: string): Promise<boolean> {
    await this.openDeleteDialog(regionName);
    await this.confirmDelete();

    // 等待并检查 Toast 消息
    await this.page.waitForTimeout(TIMEOUTS.LONG);
    const successToast = this.page.locator('[data-sonner-toast][data-type="success"]');
    const hasSuccess = await successToast.count() > 0;

    return hasSuccess;
  }

  /**
   * 切换区域状态（启用/禁用）
   * @param regionName 区域名称
   * @returns 是否成功
   */
  async toggleRegionStatus(regionName: string): Promise<boolean> {
    // 先确保区域在树中可见
    await this.waitForTreeLoaded();
    const exists = await this.regionExists(regionName);
    if (!exists) {
      console.debug(`⚠️ toggleRegionStatus: 区域 "${regionName}" 在树中未找到`);
    }

    await this.openToggleStatusDialog(regionName);
    await this.confirmToggleStatus();

    // 等待并检查 Toast 消息
    await this.page.waitForTimeout(TIMEOUTS.LONG);
    const successToast = this.page.locator('[data-sonner-toast][data-type="success"]');
    const hasSuccess = await successToast.count() > 0;

    // 等待树形结构刷新以显示更新后的状态
    try {
      await this.page.waitForLoadState('domcontentloaded', { timeout: TIMEOUTS.DIALOG });
    } catch {
      // 继续执行
    }
    await this.waitForTreeLoaded();

    console.debug(`toggleRegionStatus 完成: 区域="${regionName}", hasSuccess=${hasSuccess}`);

    return hasSuccess;
  }

  /**
   * 等待树形结构加载完成
   */
  async waitForTreeLoaded() {
    await this.treeContainer.waitFor({ state: 'visible', timeout: TIMEOUTS.PAGE_LOAD_LONG });
    // 等待加载文本消失（使用更健壮的选择器）
    // 加载文本位于 CardContent 中，带有 text-muted-foreground 类
    await this.page.locator('.text-muted-foreground', { hasText: '加载中' }).waitFor({ state: 'hidden', timeout: TIMEOUTS.TABLE_LOAD }).catch(() => {});
  }

  /**
   * 刷新树形结构（用于创建新区域后强制刷新）
   * 由于树组件使用懒加载缓存，新创建的区域不会自动显示
   * 此方法通过重新导航到页面来强制刷新树数据
   */
  async refreshTree() {
    console.debug('刷新树形结构以显示新创建的区域');
    // 重新导航到当前页面，强制刷新所有数据
    await this.page.reload();
    // 等待页面加载完成
    await this.page.waitForLoadState('domcontentloaded', { timeout: TIMEOUTS.PAGE_LOAD });
    // 等待树形结构加载完成
    await this.treeContainer.waitFor({ state: 'visible', timeout: TIMEOUTS.PAGE_LOAD_LONG });
    await this.pageTitle.waitFor({ state: 'visible', timeout: TIMEOUTS.PAGE_LOAD });
    // 等待懒加载完成
    await this.page.locator('.text-muted-foreground', { hasText: '加载中' }).waitFor({ state: 'hidden', timeout: TIMEOUTS.TABLE_LOAD }).catch(() => {});
    console.debug('树形结构刷新完成');
  }
}
