import { Page } from "@playwright/test";
import { test, expect, ACCOUNT, GROUP } from "../../src/fixture/base-test";
import {
  openPhanQuyenNangCao,
  moItemPhanQuyen,
  getCodeCuaItemPhanQuyen,
  ngatKeThua,
  checkKeThua,
  checkNguoiCoQuyenO5Cot,
  getQuyen5Cot,
  checkQuyen5CotNhuCu,
  PQ_COT_QUYEN,
  Quyen5Cot,
  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 607 (QA): Kiểm tra phân quyền của các TM, TL con của thư mục vừa phân quyền
 *                — trường hợp item con KHÔNG kế thừa
 * ============================================================================
 *
 * ── 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.
 * Tiền điều kiện thêm:
 *   - **TM/TL con KHÔNG áp dụng kế thừa quyền.**
 * Thao tác:
 *   1. Thực hiện cập nhật lại đối tượng phân quyền tại thư mục cha thành công
 *   2. Kiểm tra phân quyền của các TM, TL con
 * Mong muốn:
 *   Các TM/TL con **giữ nguyên phân quyền**.
 *
 * (Đây là mặt ngược của case 606: 606 kiểm tra item con ĐANG kế thừa thì nhận quyền
 * mới của thư mục cha; 607 kiểm tra item con đã ngắt kế thừa thì KHÔNG bị ghi đè.)
 *
 * ── CÁC BƯỚC SCRIPT THỰC HIỆN ───────────────────────────────────────────────
 * B0. Dựng tiền điều kiện thêm: Owner BHS mở "Kiểm tra phân quyền" → **ngắt kế thừa**
 *     cho cả thư mục con và tài liệu con → ghi lại (snapshot) danh sách người ở cả 5
 *     cột quyền của 2 item con ngay lúc này, để cuối case so lại.
 * B1. Cập nhật phân quyền cho thư mục cha rồi lưu (như case 587): mở màn cập nhật TM
 *     → "Đặt quyền độc lập" → "Xác nhận" → thêm 1 người dùng vào cả 5 trường quyền
 *     → "Xác nhận" để lưu → hệ thống báo "Thành công".
 * B2. Mở lại "Kiểm tra phân quyền" bằng tài khoản Owner BHS rồi đối chiếu:
 *     - Thư mục cha: cột Kế thừa = "Quyền riêng tư", cả 5 cột quyền có người vừa thêm
 *       (xác nhận B1 lưu thành công — nếu B1 không ăn thì mọi so sánh phía dưới vô nghĩa).
 *     - Thư mục con và Tài liệu: vẫn "Quyền riêng tư", quyền ở cả 5 cột **đúng như
 *       snapshot ở B0**, và **không xuất hiện** người vừa được thêm ở thư mục cha.
 *
 * ── 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 ở B1 | 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 cha, case cập nhật quyền tại đây
 *          ├─ 1 thư mục con → B0 NGẮT KẾ THỪA    ← item con cần kiểm tra
 *          └─ 1 tài liệu   → B0 NGẮT KẾ THỪA     ← item con cần kiểm tra
 *
 * - Ngắt kế thừa và mọi bước kiểm tra đều 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
 *   (xem KHO-TAI-LIEU.PHAN-QUYEN-THEO-VAI.md mục 2).
 * - Test 3, 4 thao tác bằng `ecm06` nên B1 phải thêm người khác (`ecm07`).
 * - 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 → không đè lên nhau, chạy song song được.
 */

/**
 * B0 — Ngắt kế thừa cho thư mục con + tài liệu con, rồi snapshot quyền của chúng.
 * `ownerPage` phải là tài khoản Owner BHS.
 */
const ngatKeThuaItemCon = async (ownerPage: Page, duLieu: DuLieu) => {
  const snapshot: Record<string, Quyen5Cot> = {};

  await test.step("0. Tiền điều kiện thêm: ngắt kế thừa cho thư mục con + tài liệu con", async () => {
    await openPhanQuyenNangCao(ownerPage, duLieu.recordUrl);

    const codeCha = await getCodeCuaItemPhanQuyen(ownerPage, duLieu.tenThuMuc);

    for (const tenItemCon of [duLieu.tenThuMucCon, duLieu.tenTaiLieuCon]) {
      // ⚠️ Phải bảo đảm thư mục cha đang expand ở MỖI vòng lặp: `ngatKeThua` mở rồi đóng
      // modal con làm bảng re-mount → cây thu gọn lại, dòng con biến mất khỏi DOM.
      await moItemPhanQuyen(ownerPage, codeCha);
      const codeCon = await getCodeCuaItemPhanQuyen(ownerPage, tenItemCon);
      await ngatKeThua(ownerPage, codeCon);

      await moItemPhanQuyen(ownerPage, codeCha);
      await checkKeThua(ownerPage, codeCon, "Quyền riêng tư", tenItemCon);
      // Snapshot NGAY SAU khi ngắt kế thừa — đây là mốc "giữ nguyên phân quyền"
      snapshot[tenItemCon] = await getQuyen5Cot(ownerPage, codeCon);
    }
  });

  return snapshot;
};

/**
 * B2 — Mong muốn: item con đã ngắt kế thừa thì giữ nguyên phân quyền, không bị quyền
 * mới của thư mục cha ghi đè.
 */
const checkItemConGiuNguyenQuyen = async (
  ownerPage: Page,
  duLieu: DuLieu,
  nguoiDuocThem: DoiTuongPhanQuyen,
  snapshot: Record<string, Quyen5Cot>,
) => {
  const tenHienThi = await layTenDoiTuongPhanQuyen(nguoiDuocThem);

  await test.step("2. Kiểm tra phân quyền của các TM, TL con", async () => {
    await openPhanQuyenNangCao(ownerPage, duLieu.recordUrl);

    // --- Thư mục cha: đã nhận người mới (chứng minh B1 lưu thành công) ---
    const codeCha = await getCodeCuaItemPhanQuyen(ownerPage, duLieu.tenThuMuc);
    await checkKeThua(ownerPage, codeCha, "Quyền riêng tư", duLieu.tenThuMuc);
    await checkNguoiCoQuyenO5Cot(
      ownerPage,
      codeCha,
      tenHienThi,
      duLieu.tenThuMuc,
    );

    await moItemPhanQuyen(ownerPage, codeCha);

    for (const tenItemCon of [duLieu.tenThuMucCon, duLieu.tenTaiLieuCon]) {
      const codeCon = await getCodeCuaItemPhanQuyen(ownerPage, tenItemCon);
      // Vẫn là quyền riêng tư (không bị kéo về kế thừa)
      await checkKeThua(ownerPage, codeCon, "Quyền riêng tư", tenItemCon);
      // Quyền y như lúc trước khi cập nhật thư mục cha
      await checkQuyen5CotNhuCu(
        ownerPage,
        codeCon,
        snapshot[tenItemCon],
        tenItemCon,
      );
      // Và người mới thêm ở thư mục cha KHÔNG được lọt xuống item con
      for (const cot of PQ_COT_QUYEN) {
        expect(snapshot[tenItemCon][cot], {
          message: `Lỗi: "${tenHienThi}" lọt vào cột [${cot}] của item con "${tenItemCon}" dù item này đã ngắt kế thừa`,
        }).not.toContain(tenHienThi);
      }
    }
  });
};

/* -------------------------------------------------------------------------- */
/* 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: `607-${maCase}`,
    taoItemCon: true,
  });

  const snapshot = await ngatKeThuaItemCon(page, duLieu);
  await capNhatVaLuuPhanQuyenThuMuc(page, duLieu, nguoiDuocThem.account);
  await checkItemConGiuNguyenQuyen(page, duLieu, nguoiDuocThem, snapshot);
};

/**
 * TEST 1 — Thủ thư (ecm01), vai "được phân quyền Tạo mới bộ hồ sơ".
 * Tự tạo BHS `AT-UC25-607-TT-<ts>` (Khai báo) → thư mục + thư mục con + tài liệu,
 * ngắt kế thừa 2 item con, rồi thêm `ecm06` vào 5 trường quyền của thư mục cha.
 */
test(
  "UC25 607 - Kiểm tra phân quyền của các TM, TL con không kế thừa của thư mục vừa phân quyền - 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 607 - Kiểm tra phân quyền của các TM, TL con không kế thừa của thư mục vừa phân quyền - 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 + ngắt kế thừa + kiểm tra, 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: `607-${maCase}`,
    quyenBanDau: { permTestId: vai.permTestId, account: vai.account },
    taoItemCon: true,
    chuyenSangHoatDong: true,
  });

  const snapshot = await ngatKeThuaItemCon(librarian, duLieu);
  await capNhatVaLuuPhanQuyenThuMuc(userPage, duLieu, nguoiDuocThem.account);
  await checkItemConGiuNguyenQuyen(librarian, duLieu, nguoiDuocThem, snapshot);
};

/**
 * TEST 3 — `ecm06` được phân quyền **Owner** (cấp ở BHS, thư mục kế thừa).
 * B1 thêm `ecm07`.
 */
test(
  "UC25 607 - Kiểm tra phân quyền của các TM, TL con không kế thừa của thư mục vừa phân quyền - 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). B1 thêm `ecm07`.
 */
test(
  "UC25 607 - Kiểm tra phân quyền của các TM, TL con không kế thừa của thư mục vừa phân quyền - 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 },
    );
  },
);

/**
 * TEST 5 — `ecm05` được phân quyền **Cập nhật** — nhánh tiền điều kiện
 * "Người dùng/Nhóm được phân quyền Cập nhật tại TM/TL". B1 thêm `ecm06`.
 */
test(
  "UC25 607 - Kiểm tra phân quyền của các TM, TL con không kế thừa của thư mục vừa phân quyền - Người dùng có quyền Cập nhật tại TMecm05",
  async ({ librarian, ecm05, ecm06 }) => {
    await runTestVaiDuocPhanQuyen(
      librarian,
      ecm05,
      "EDIT",
      { account: "ecm05", permTestId: DOC_PERM.EDIT },
      { account: "ecm06", page: ecm06 },
    );
  },
);
