import { Page } from "@playwright/test";
import { test, expect } from "../../src/fixture/base-test";
import { TIMEOUT } from "../../src/constant/timeout";
import {
  openBoHoSo,
  openTabCauTrucHoSo,
  openManCapNhatThuMuc,
  getThuMucModal,
  getActiveTabPane,
  getCauTrucRow,
  luuModalThuMuc,
  THU_MUC_FIELD,
} from "../../src/screen-instructions/KHO-TAI-LIEU.functions";
import { DuLieuCapNhatThuMuc } from "./1.4.4.setup";

/**
 * Thao tác + assert dùng chung cho bộ case **1.4.4 — Cập nhật thư mục trong Cấu trúc hồ sơ**.
 *
 * Tiền điều kiện chung của mục: xem [`1.4.4.md`](./1.4.4.md).
 */

/**
 * Nút lưu ở footer modal "Cập nhật thư mục".
 *
 * 🚨 QA gọi là **"button Lưu"**, nhưng trên màn hình nút này có nhãn **"Xác nhận"**
 * (`KHO-TAI-LIEU.MODAL-TAO-THU-MUC.md` mục 5 + 6b: footer modal Thêm/Cập nhật thư mục là
 * `Xác nhận` / `Hủy`, **không** có `btn-save` như modal BHS) → khớp theo nhãn, không theo testId.
 */
const getNutLuuModalThuMuc = (page: Page) =>
  getThuMucModal(page)
    .getByRole("button", { name: /Xác nhận/ })
    .first();

/**
 * Mở lại 1 thư mục đã tạo bằng màn **"Cập nhật thư mục"**, đổi **Tên** sang `tenMoi` rồi bấm
 * nút lưu, chờ toast `"Thành công"`.
 *
 * Trước khi sửa, hàm kiểm chứng modal đã nạp đúng dữ liệu thư mục (`Tên` = tên cũ) — nếu không,
 * mọi assert sau đó sẽ vô nghĩa. Sau khi điền, kiểm chứng input **thật sự nhận** giá trị mới
 * (`toHaveValue`) rồi mới bấm lưu; nút lưu được assert **visible + enabled** vì nội dung case là
 * "kiểm tra button Lưu khi nhập thông tin hợp lệ".
 *
 * 🚨 `openManCapNhatThuMuc` đổi `page.url()` sang `itemId` của thư mục
 * (`KHO-TAI-LIEU.md` mục 4.4) → bước sau phải mở lại BHS bằng `duLieu.recordUrl`
 * (`expectTenThuMucMoiDaLuu` tự làm).
 */
export const moLaiThuMucRoiDoiTen = async (
  userPage: Page,
  duLieu: DuLieuCapNhatThuMuc,
  tenMoi: string = duLieu.tenThuMucMoi,
) => {
  await test.step(`2. Mở lại thư mục "${duLieu.tenThuMuc}" → sửa Tên thành "${tenMoi}" → bấm nút lưu (chờ toast "Thành công")`, async () => {
    await openManCapNhatThuMuc(userPage, duLieu.recordUrl, duLieu.tenThuMuc);

    const modal = getThuMucModal(userPage);
    const oTen = modal.getByTestId(THU_MUC_FIELD.TEN);

    await expect(oTen, {
      message: `Lỗi: màn "Cập nhật thư mục" không nạp đúng tên thư mục đang sửa (mong đợi "${duLieu.tenThuMuc}")`,
    }).toHaveValue(duLieu.tenThuMuc, { timeout: TIMEOUT.CONTROL_LOADING });

    await oTen.fill(tenMoi);
    await expect(oTen, {
      message: `Lỗi: ô "Tên" không nhận giá trị mới "${tenMoi}"`,
    }).toHaveValue(tenMoi, { timeout: TIMEOUT.VALIDATE_WAITING });

    // Nội dung case: button lưu phải dùng được khi thông tin nhập là hợp lệ
    const nutLuu = getNutLuuModalThuMuc(userPage);
    await expect(nutLuu, {
      message: 'Lỗi: không thấy nút lưu ("Xác nhận") ở footer màn Cập nhật thư mục',
    }).toBeVisible({ timeout: TIMEOUT.CONTROL_LOADING });
    await expect(nutLuu, {
      message:
        'Lỗi: nút lưu ("Xác nhận") đang bị disable dù thông tin nhập vào hợp lệ',
    }).toBeEnabled({ timeout: TIMEOUT.CONTROL_LOADING });

    // Bấm lưu + assert toast "Thành công" (đã gói trong luuModalThuMuc)
    await luuModalThuMuc(userPage, modal, `Đổi tên thư mục → ${tenMoi}`);
  });
};

/**
 * Mong muốn: **tên mới đã được lưu** — kiểm ở 2 chỗ độc lập nhau:
 *
 * 1. Bảng **Cấu trúc hồ sơ** của BHS: có dòng tên mới, và **không còn** dòng nào mang tên cũ
 *    (chỉ đổi tên chứ không tạo thêm thư mục).
 * 2. Mở lại màn **"Cập nhật thư mục"** theo tên mới: ô `Tên` đúng bằng tên mới → dữ liệu được ghi
 *    xuống server, không phải chỉ đổi ở UI của bảng.
 *
 * Assert "tên cũ không còn" đọc theo **chuỗi con** nên yêu cầu tên cũ **không phải tiền tố** của
 * tên mới — setup đã đặt hậu tố `-TM-CU` / `-TM-MOI` để thoả (xem `1.4.4.md` mục 2).
 */
export const expectTenThuMucMoiDaLuu = async (
  page: Page,
  duLieu: DuLieuCapNhatThuMuc,
  tenMoi: string = duLieu.tenThuMucMoi,
) => {
  await test.step(`3. Mong muốn: thư mục hiển thị + lưu với tên mới "${tenMoi}", không còn tên cũ "${duLieu.tenThuMuc}"`, async () => {
    await openBoHoSo(page, duLieu.recordUrl);
    await openTabCauTrucHoSo(page);

    const row = getCauTrucRow(page, tenMoi);
    await expect(row, {
      message: `Lỗi: không thấy thư mục "${tenMoi}" trong bảng Cấu trúc hồ sơ sau khi đổi tên`,
    }).toBeVisible({ timeout: TIMEOUT.DATA_LOADING });

    // Tên hiển thị có dạng "<mã prefix>. <tên>" (vd "A. AT-1.4.4-454-…-TM-MOI")
    await expect(
      row.locator('[data-testid^="lnk-ten-ho-so-tai-lieu-"]').first(),
      { message: `Lỗi: dòng của thư mục không hiển thị tên mới "${tenMoi}"` },
    ).toContainText(tenMoi, { timeout: TIMEOUT.CONTROL_LOADING });

    const tenCacDong = await getActiveTabPane(page)
      .locator('[data-testid^="lnk-ten-ho-so-tai-lieu-"]')
      .allInnerTexts();
    expect(tenCacDong.filter((t) => t.includes(duLieu.tenThuMuc)), {
      message:
        `Lỗi: vẫn còn dòng mang tên cũ "${duLieu.tenThuMuc}" sau khi đổi tên. ` +
        `Các dòng đang có: [${tenCacDong.map((t) => t.trim()).join(" | ")}]`,
    }).toHaveLength(0);

    await openManCapNhatThuMuc(page, duLieu.recordUrl, tenMoi);
    await expect(getThuMucModal(page).getByTestId(THU_MUC_FIELD.TEN), {
      message: `Lỗi: mở lại thư mục nhưng ô "Tên" không phải tên mới đã lưu ("${tenMoi}")`,
    }).toHaveValue(tenMoi, { timeout: TIMEOUT.CONTROL_LOADING });
  });
};
