import { Page } from "@playwright/test";
import { test, ACCOUNT, GROUP } from "../../src/fixture/base-test";
import {
  openPhanQuyenNangCao,
  moItemPhanQuyen,
  getCodeCuaItemPhanQuyen,
  checkKeThua,
  checkNguoiCoQuyenO5Cot,
  layTenDoiTuongPhanQuyen,
  DoiTuongPhanQuyen,
  DOC_PERM,
} from "../../src/screen-instructions/KHO-TAI-LIEU.functions";
import { dungDuLieuThuMuc, DuLieu } from "./1.4.6.setup";
import { capNhatVaLuuPhanQuyenThuMuc } from "./1.4.6.steps";

/**
 * ============================================================================
 * UC25 — 1.4.6 Cập nhật quyền của thư mục, tài liệu trong Cấu trúc hồ sơ
 * Case 587 (QA): Kiểm tra Lưu cập nhật phân quyền cho TM
 * ============================================================================
 *
 * ── NGUYÊN VĂN TESTCASE ─────────────────────────────────────────────────────
 * Tiền điều kiện (chung của bộ 1.4.6):
 *   - Thủ thư / ITAdmin / Người dùng được phân quyền Tạo mới bộ hồ sơ, BHS ở
 *     trạng thái Khai báo hoặc Đang hoạt động.
 *   - Người dùng / Nhóm (AUTO_GROUP_ECM06, có ecm06) được phân quyền Owner
 *     của TM/TL, trạng thái TL đang hoạt động.
 *   - Người dùng / Nhóm được phân quyền Cập nhật tại TM/TL, trạng thái TL đang
 *     hoạt động.
 * Thao tác:
 *   1. Mở màn hình cập nhật TM
 *   2. Click Đặt quyền độc lập
 *   3. Click Xác nhận
 *   4. Thực hiện cập nhật lại các đối tượng được phân quyền
 *   5. Nhấn Xác nhận
 * Mong muốn:
 *   Người dùng/Nhóm được phân quyền tại Thư mục đang cập nhật sẽ thay thế cho
 *   người dùng/nhóm đã được phân quyền tương ứng tại item con trong Thư mục.
 *
 * ── CÁC BƯỚC SCRIPT THỰC HIỆN ───────────────────────────────────────────────
 * B1. Mở Bộ hồ sơ → tab "Cấu trúc hồ sơ" → menu của dòng thư mục → "Cập nhật"
 *     → màn "Cập nhật thư mục <tên TM>" → vào tab "Phân quyền" (đang là "Kế thừa").
 * B2. Bấm "Đặt quyền độc lập" ở thanh thông báo đầu màn hình.
 * B3. Hộp thoại xác nhận → bấm "Xác nhận" → nhãn tab đổi sang "Độc lập",
 *     5 trường quyền cho chỉnh sửa.
 * B4. Cập nhật lại đối tượng được phân quyền: thêm 1 người dùng vào **cả 5 trường**
 *     Quyền Owner / Tạo mới / Cập nhật / Tải file / Xem (chỉ thêm, không xoá người
 *     đang kế thừa).
 * B5. Bấm "Xác nhận" ở cuối màn hình để lưu → hệ thống báo "Đang xử lý" rồi
 *     "Thành công".
 * Mong muốn. Mở "Kiểm tra phân quyền" của Bộ hồ sơ bằng tài khoản Owner BHS rồi đối chiếu:
 *     - Thư mục vừa cập nhật: cột Kế thừa = "Quyền riêng tư", cả 5 cột quyền đều
 *       có người vừa được thêm.
 *     - Thư mục con và Tài liệu bên trong: vẫn "Kế thừa", và cả 5 cột quyền cũng
 *       đã có người vừa được thêm → quyền của thư mục cha đã áp xuống item con.
 *
 * ── 5 TEST = 5 BỘ HỒ SƠ RIÊNG (mỗi test tự dựng dữ liệu của nó) ─────────────
 * | # | Vai thao tác      | Ai dựng dữ liệu | Quyền của vai tại thư mục        | Người thêm ở B4 | Trạng thái BHS |
 * |---|-------------------|-----------------|----------------------------------|-----------------|----------------|
 * | 1 | Thủ thư (ecm01)   | chính nó        | Owner (vì tự tạo BHS)            | ecm06           | Khai báo       |
 * | 2 | Admin   (ecm09)   | chính nó        | Owner (vì tự tạo BHS)            | ecm06           | Khai báo       |
 * | 3 | ecm06             | Thủ thư         | Owner — cấp ở BHS, TM kế thừa    | ecm07           | Hoạt động      |
 * | 4 | ecm06 (qua nhóm)  | Thủ thư         | Owner cấp cho AUTO_GROUP_ECM06    | ecm07           | Hoạt động      |
 * | 5 | ecm05             | Thủ thư         | Cập nhật — cấp ở BHS, TM kế thừa | ecm06           | Hoạt động      |
 *
 * Dữ liệu mỗi test (xem `1.4.6.setup.ts`):
 *     BHS  (Owner = người tạo; test 3–5 cấp thêm quyền cho vai cần test)
 *      └─ thư mục ở gốc BHS, đang KẾ THỪA      ← thư mục case thao tác trên
 *          ├─ 1 thư mục con, đang KẾ THỪA      ← item con để đối chiếu mong muốn
 *          └─ 1 tài liệu, đang KẾ THỪA         ← item con để đối chiếu mong muốn
 *
 * - Test 3, 4 thao tác bằng `ecm06` nên B4 phải thêm người khác (`ecm07`) — thêm
 *   chính mình thì không chứng minh được gì vì `ecm06` đã có quyền kế thừa sẵn.
 * - Phần kiểm tra kết quả **luôn dùng tài khoản Owner BHS** (người tạo BHS): modal
 *   "Phân quyền nâng cao" chỉ Owner BHS mở được, và đọc bằng Owner cho kết quả tổng
 *   quát nhất (xem KHO-TAI-LIEU.PHAN-QUYEN-THEO-VAI.md mục 2).
 * - 5 test dùng **5 BHS tách biệt**, tên có timestamp riêng, chạy trên phiên đăng
 *   nhập riêng → quyền của test này không đè lên test khác, chạy song song được.
 */

/**
 * Mong muốn: quyền mới của thư mục đã áp xuống thư mục con + tài liệu bên trong.
 * `ownerPage` phải là tài khoản Owner BHS (chỉ vai này mở được modal Phân quyền nâng cao).
 */
const checkQuyenDaApXuongItemCon = async (
  ownerPage: Page,
  duLieu: DuLieu,
  nguoiDuocThem: DoiTuongPhanQuyen,
) => {
  const tenHienThi = await layTenDoiTuongPhanQuyen(nguoiDuocThem);

  await test.step(`Mong muốn: thư mục và các item con đều có "${tenHienThi}" ở cả 5 quyền`, async () => {
    await openPhanQuyenNangCao(ownerPage, duLieu.recordUrl);

    // --- Thư mục vừa cập nhật: đã tách kế thừa và có người mới ---
    const codeThuMuc = await getCodeCuaItemPhanQuyen(
      ownerPage,
      duLieu.tenThuMuc,
    );
    await checkKeThua(
      ownerPage,
      codeThuMuc,
      "Quyền riêng tư",
      duLieu.tenThuMuc,
    );
    await checkNguoiCoQuyenO5Cot(
      ownerPage,
      codeThuMuc,
      tenHienThi,
      duLieu.tenThuMuc,
    );

    // --- Item con: bảng là cây nên phải expand thư mục cha mới thấy dòng con ---
    await moItemPhanQuyen(ownerPage, codeThuMuc);

    for (const tenItemCon of [duLieu.tenThuMucCon, duLieu.tenTaiLieuCon]) {
      const codeItemCon = await getCodeCuaItemPhanQuyen(ownerPage, tenItemCon);
      // Item con vẫn kế thừa → quyền của nó phải khớp quyền mới của thư mục cha
      await checkKeThua(ownerPage, codeItemCon, "Kế thừa", tenItemCon);
      await checkNguoiCoQuyenO5Cot(
        ownerPage,
        codeItemCon,
        tenHienThi,
        tenItemCon,
      );
    }
  });
};

/* -------------------------------------------------------------------------- */
/* Vai tự tạo BHS (Thủ thư / Admin) — vừa thao tác vừa kiểm tra kết quả        */
/* -------------------------------------------------------------------------- */

const runTestOwnerBoHoSo = async (
  page: Page,
  maCase: string,
  nguoiDuocThem: DoiTuongPhanQuyen,
) => {
  const duLieu = await dungDuLieuThuMuc(page, {
    maCase: `587-${maCase}`,
    taoItemCon: true,
  });

  await capNhatVaLuuPhanQuyenThuMuc(page, duLieu, nguoiDuocThem.account);
  await checkQuyenDaApXuongItemCon(page, duLieu, nguoiDuocThem);
};

/**
 * TEST 1 — Thủ thư (ecm01), vai "được phân quyền Tạo mới bộ hồ sơ".
 * Tự tạo BHS `AT-UC25-587-TT-<ts>` (Khai báo) → thư mục + thư mục con + tài liệu.
 * B4 thêm `ecm06` vào cả 5 trường quyền của thư mục.
 */
test(
  "UC25 587 - Kiểm tra Lưu cập nhật phân quyền cho TM - Thủ thư" +
    ACCOUNT.LIBRARIAN,
  async ({ librarian, ecm06 }) => {
    await runTestOwnerBoHoSo(librarian, "TT", {
      account: "ecm06",
      page: ecm06,
    });
  },
);

/**
 * TEST 2 — ITAdmin (ecm09). Dữ liệu & thao tác y hệt TEST 1, chỉ khác tài khoản.
 */
test(
  "UC25 587 - Kiểm tra Lưu cập nhật phân quyền cho TM - Admin" + ACCOUNT.ADMIN,
  async ({ admin, ecm06 }) => {
    await runTestOwnerBoHoSo(admin, "AD", {
      account: "ecm06",
      page: ecm06,
    });
  },
);

/* -------------------------------------------------------------------------- */
/* Vai được phân quyền tại thư mục (không phải người tạo BHS)                   */
/* Thủ thư dựng dữ liệu + kiểm tra kết quả, vai kia thực hiện thao tác          */
/* -------------------------------------------------------------------------- */

const runTestVaiDuocPhanQuyen = async (
  librarian: Page,
  userPage: Page,
  maCase: string,
  vai: { account: string; permTestId: string },
  nguoiDuocThem: DoiTuongPhanQuyen,
) => {
  const duLieu = await dungDuLieuThuMuc(librarian, {
    maCase: `587-${maCase}`,
    quyenBanDau: { permTestId: vai.permTestId, account: vai.account },
    taoItemCon: true,
    chuyenSangHoatDong: true,
  });

  await capNhatVaLuuPhanQuyenThuMuc(userPage, duLieu, nguoiDuocThem.account);
  await checkQuyenDaApXuongItemCon(librarian, duLieu, nguoiDuocThem);
};

/**
 * TEST 3 — `ecm06` được phân quyền **Owner** (cấp ở BHS, thư mục kế thừa).
 * B4 thêm `ecm07` — không dùng `ecm06` vì chính nó đang thao tác
 * và đã có quyền kế thừa sẵn.
 */
test("UC25 587 - Kiểm tra Lưu cập nhật phân quyền cho TM - Người dùng có quyền Owner tại TMecm06", async ({
  librarian,
  ecm06,
  ecm07,
}) => {
  await runTestVaiDuocPhanQuyen(
    librarian,
    ecm06,
    "OWN",
    { account: "ecm06", permTestId: DOC_PERM.OWNER },
    { account: "ecm07", page: ecm07 },
  );
});

/**
 * TEST 4 — **NHÓM** `AUTO_GROUP_ECM06` được phân quyền **Owner**; thao tác bằng
 * `ecm06` (thành viên của nhóm) để kiểm tra quyền có hiệu lực qua nhóm.
 * B4 thêm `ecm07`.
 */
test("UC25 587 - Kiểm tra Lưu cập nhật phân quyền cho TM - Nhóm có quyền Owner tại TMecm06", async ({
  librarian,
  ecm06,
  ecm07,
}) => {
  await runTestVaiDuocPhanQuyen(
    librarian,
    ecm06,
    "GRP",
    { account: GROUP.ECM06, permTestId: DOC_PERM.OWNER },
    { account: "ecm07", page: ecm07 },
  );
});
