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

export class DisabilityPersonManagementPage {
  readonly page: Page;
  readonly pageTitle: Locator;
  readonly addPersonButton: Locator;
  readonly keywordSearchInput: Locator;
  readonly searchButton: Locator;
  readonly personTable: Locator;

  constructor(page: Page) {
    this.page = page;
    this.pageTitle = page.getByText('残疾人个人管理');
    this.addPersonButton = page.getByRole('button', { name: '新增残疾人' });
    this.keywordSearchInput = page.getByPlaceholder('搜索姓名或身份证号');
    this.searchButton = page.getByRole('button', { name: '搜索' });
    this.personTable = page.locator('table');
  }

  async goto() {
    await this.page.goto('/admin/disabilities');
    await this.page.waitForLoadState('domcontentloaded');
    // 等待页面标题出现
    await this.pageTitle.waitFor({ state: 'visible', timeout: 15000 });
    // 等待表格数据加载
    await this.page.waitForSelector('table tbody tr', { state: 'visible', timeout: 20000 });
    await this.expectToBeVisible();
  }

  async expectToBeVisible() {
    await this.pageTitle.waitFor({ state: 'visible', timeout: 15000 });
    await this.addPersonButton.waitFor({ state: 'visible', timeout: 10000 });
  }

  async openCreateDialog() {
    // 监听网络请求
    const responses: any[] = [];
    this.page.on('response', async (response) => {
      if (response.url().includes('disabled-person') || response.url().includes('aggregated')) {
        try {
          const responseData = await response.json().catch(() => ({ status: response.status() }));
          responses.push({
            url: response.url(),
            status: response.status(),
            data: responseData
          });
        } catch (e) {
          responses.push({
            url: response.url(),
            status: response.status(),
            error: e
          });
        }
      }
    });

    await this.addPersonButton.click();
    await this.page.waitForSelector('[data-testid="create-disabled-person-dialog-title"]', { state: 'visible', timeout: 5000 });

    return responses;
  }

  async fillBasicForm(data: {
    name: string;
    gender: string;
    idCard: string;
    disabilityId: string;
    disabilityType: string;
    disabilityLevel: string;
    phone: string;
    idAddress: string;
    province: string;
    city: string;
  }) {
    // 等待表单出现
    await this.page.waitForSelector('form#create-form', { state: 'visible', timeout: 5000 });

    // 填写基本信息
    await this.page.getByLabel('姓名 *').fill(data.name);
    // 性别使用原生 select，直接选择（不是 Radix UI）
    await this.page.getByLabel('性别 *').selectOption(data.gender);
    await this.page.getByLabel('身份证号 *').fill(data.idCard);
    await this.page.getByLabel('残疾证号 *').fill(data.disabilityId);
    await this.selectRadixOption('残疾类型 *', data.disabilityType);
    await this.selectRadixOption('残疾等级 *', data.disabilityLevel);
    await this.page.getByLabel('联系电话 *').fill(data.phone);
    await this.page.getByLabel('身份证地址 *').fill(data.idAddress);

    // 居住地址 - 使用 Radix UI Select
    await this.selectRadixOption('省份 *', data.province);
    await this.page.waitForTimeout(500); // 等待城市加载
    await this.selectRadixOption('城市', data.city);
  }

  // 公共方法：处理 Radix UI Select 组件
  // 方法：点击 combobox 打开菜单，然后点击选项
  async selectRadixOption(label: string, value: string) {
    const combobox = this.page.getByRole('combobox', { name: label });

    // 点击 combobox 打开菜单
    await combobox.click({ timeout: 2000 });

    // 点击选项 - 使用 .first() 处理多个匹配
    const option = this.page.getByRole('option', { name: value }).first();
    await option.click({ timeout: 3000 });
    console.log(`  ✓ ${label} 选中: ${value}`);
  }

  async submitForm() {
    // 收集网络响应
    const responses: any[] = [];

    // 监听所有网络请求
    this.page.on('response', async (response) => {
      const url = response.url();
      if (url.includes('disabled-person') || url.includes('aggregated')) {
        const requestBody = response.request()?.postData();
        const responseBody = await response.text().catch(() => '');
        let jsonBody = null;
        try {
          jsonBody = JSON.parse(responseBody);
        } catch (e) {
          // 不是 JSON
        }

        responses.push({
          url,
          method: response.request()?.method(),
          status: response.status(),
          ok: response.ok(),
          requestHeaders: await response.allHeaders().catch(() => ({})),
          responseHeaders: await response.allHeaders().catch(() => ({})),
          requestBody: requestBody ? JSON.parse(requestBody) : null,
          responseBody: jsonBody || responseBody,
          statusText: response.statusText()
        });
      }
    });

    // 点击创建按钮
    const submitButton = this.page.getByRole('button', { name: '创建' });
    await submitButton.click();

    // 等待网络请求完成
    await this.page.waitForLoadState('networkidle', { timeout: 10000 });

    // 等待一段时间让 Toast 消息显示
    await this.page.waitForTimeout(2000);

    // 检查是否有错误提示
    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 = null;
    let successMessage = null;

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

    return {
      responses,
      hasError,
      hasSuccess,
      errorMessage,
      successMessage
    };
  }

  async searchByName(name: string) {
    await this.keywordSearchInput.fill(name);
    await this.searchButton.click();
    await this.page.waitForLoadState('networkidle');
    await this.page.waitForTimeout(1000);
  }

  async personExists(name: string): Promise<boolean> {
    const personRow = this.personTable.locator('tbody tr').filter({ hasText: name }).first();
    return (await personRow.count()) > 0;
  }

  /**
   * 上传照片
   * @param photoType 照片类型（身份证照片、残疾证照片、个人照片、其他照片）
   * @param fileName 文件名
   */
  async uploadPhoto(photoType: string, fileName: string) {
    // 找到对应照片类型的上传按钮区域
    const photoSection = this.page.locator('text=' + photoType).first();
    await photoSection.scrollIntoViewIfNeeded();

    // 查找该类型照片区域的"上传"按钮
    const uploadButton = photoSection.locator('xpath=ancestor::div[contains(@class, "space-y-")]').first()
      .getByRole('button', { name: /上传/ }).first();

    // 创建测试文件
    const fileInput = await uploadButton.evaluateHandle((el: any) => {
      const input = el.querySelector('input[type="file"]');
      return input;
    });

    // 使用临时文件上传
    const file = {
      name: fileName,
      mimeType: 'image/jpeg',
      buffer: Buffer.from('fake image content')
    };

    await fileInput.uploadFile(file as any);
    await this.page.waitForTimeout(500); // 等待上传处理
    console.log(`  ✓ 上传照片: ${photoType} - ${fileName}`);
  }

  /**
   * 添加银行卡
   * @param bankCard 银行卡信息
   */
  async addBankCard(bankCard: {
    bankName: string;
    subBankName: string;
    cardNumber: string;
    cardholderName: string;
    cardType?: string;
    photoFileName?: string;
  }) {
    // 点击"添加银行卡"按钮
    const addCardButton = this.page.getByRole('button', { name: /添加银行卡/ });
    await addCardButton.click();
    await this.page.waitForTimeout(300);

    // 填写银行卡信息
    await this.selectRadixOption('银行名称', bankCard.bankName);
    await this.page.getByLabel(/发卡支行/).fill(bankCard.subBankName);
    await this.page.getByLabel(/银行卡号/).fill(bankCard.cardNumber);
    await this.page.getByLabel(/持卡人姓名/).fill(bankCard.cardholderName);

    // 选择银行卡类型（可选）
    if (bankCard.cardType) {
      await this.selectRadixOption('银行卡类型', bankCard.cardType);
    }

    // 上传银行卡照片
    if (bankCard.photoFileName) {
      const photoInput = this.page.locator('input[type="file"]').last();
      await photoInput.setInputFiles({
        name: bankCard.photoFileName,
        mimeType: 'image/jpeg',
        buffer: Buffer.from('fake bank card image')
      });
      await this.page.waitForTimeout(500);
    }

    console.log(`  ✓ 添加银行卡: ${bankCard.bankName} - ${bankCard.cardNumber}`);
  }

  /**
   * 添加备注
   * @param remark 备注信息
   */
  async addRemark(remark: {
    content: string;
    isSpecialNeeds?: boolean;
  }) {
    // 点击"添加备注"按钮
    const addRemarkButton = this.page.getByRole('button', { name: /添加备注/ });
    await addRemarkButton.click();
    await this.page.waitForTimeout(300);

    // 填写备注内容
    const remarkTextarea = this.page.getByPlaceholder(/请输入备注内容/).last();
    await remarkTextarea.fill(remark.content);

    // 标记特殊需求（如果需要）
    if (remark.isSpecialNeeds) {
      const specialNeedsCheckbox = this.page.getByRole('checkbox', { name: /特殊需求/ });
      const isChecked = await specialNeedsCheckbox.isChecked();
      if (!isChecked) {
        await specialNeedsCheckbox.click();
      }
    }

    console.log(`  ✓ 添加备注: ${remark.content.substring(0, 20)}...`);
  }

  /**
   * 添加回访记录
   * @param visit 回访信息
   */
  async addVisit(visit: {
    visitDate: string;
    visitType: string;
    visitContent: string;
    visitResult?: string;
    nextVisitDate?: string;
  }) {
    // 点击"添加回访"按钮
    const addVisitButton = this.page.getByRole('button', { name: /添加回访/ });
    await addVisitButton.click();
    await this.page.waitForTimeout(300);

    // 填写回访信息
    await this.page.getByLabel(/回访日期/).fill(visit.visitDate);
    await this.selectRadixOption('回访类型', visit.visitType);

    // 查找回访内容输入框（可能有多个，使用最后一个）
    const visitContentTextarea = this.page.locator('textarea').filter({ hasText: '' }).last();
    await visitContentTextarea.fill(visit.visitContent);

    // 填写回访结果（可选）
    if (visit.visitResult) {
      const resultTextareas = this.page.locator('textarea');
      const count = await resultTextareas.count();
      if (count > 0) {
        await resultTextareas.nth(count - 1).fill(visit.visitResult);
      }
    }

    // 填写下一次回访日期（可选）
    if (visit.nextVisitDate) {
      const nextDateInput = this.page.getByLabel(/下次回访日期/);
      await nextDateInput.fill(visit.nextVisitDate);
    }

    console.log(`  ✓ 添加回访: ${visit.visitType} - ${visit.visitDate}`);
  }

  /**
   * 滚动表单到指定区域
   * @param sectionName 区域名称
   */
  async scrollToSection(sectionName: string) {
    const section = this.page.locator(`text=${sectionName}`).first();
    await section.scrollIntoViewIfNeeded();
    await this.page.waitForTimeout(300);
  }

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

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