import { describe, expect, it } from "vitest";
import {
  buildWorksmobilePasswordManageUrl,
  canCreateWorksmobileRow,
  canOpenWorksmobilePasswordManage,
  canSelectWorksmobileRow,
  comparisonFilterOptions,
  filterVisibleWorksmobileComparisonRows,
  filterWorksmobileComparisonRows,
  filterWorksmobileComparisonRowsBySearch,
  formatWorksmobileOrgDetails,
  formatWorksmobilePersonName,
  formatWorksmobileUpdateDetails,
  getDefaultGroupComparisonFilters,
  getDefaultWorksmobileComparisonColumns,
  getWorksmobileComparisonStatusLabel,
  getWorksmobileRowSelectionKey,
  getWorksmobileSelectedActionIds,
  getWorksmobileSelectedMissingExternalKeyOrgUnitIds,
  getWorksmobileSelectedWorksOnlyOrgUnitIds,
  isImmutableWorksmobileAccount,
  summarizeWorksmobileComparison,
  userFilterOptions,
} from "./worksmobileComparison";

describe("TenantWorksmobilePage comparison helpers", () => {
  it("summarizes comparison rows by status", () => {
    const summary = summarizeWorksmobileComparison([
      { resourceType: "USER", status: "matched" },
      { resourceType: "GROUP", status: "needs_update" },
      { resourceType: "USER", status: "missing_in_worksmobile" },
      { resourceType: "USER", status: "missing_in_baron" },
      { resourceType: "USER", status: "missing_external_key" },
      { resourceType: "USER", status: "missing_in_baron" },
    ]);

    expect(summary).toEqual({
      total: 6,
      matched: 1,
      needsUpdate: 1,
      missingInWorksmobile: 1,
      missingInBaron: 2,
      missingExternalKey: 1,
    });
  });

  it("returns Korean labels for known comparison statuses", () => {
    expect(getWorksmobileComparisonStatusLabel("matched")).toBe("일치");
    expect(getWorksmobileComparisonStatusLabel("missing_in_worksmobile")).toBe(
      "WORKS 없음",
    );
    expect(getWorksmobileComparisonStatusLabel("missing_in_baron")).toBe(
      "Baron 없음",
    );
    expect(getWorksmobileComparisonStatusLabel("missing_external_key")).toBe(
      "ex_key 없음",
    );
    expect(getWorksmobileComparisonStatusLabel("needs_update")).toBe(
      "업데이트 필요",
    );
    expect(getWorksmobileComparisonStatusLabel("unknown_status")).toBe(
      "unknown_status",
    );
  });

  it("allows WORKS creation only for Baron rows missing in WORKS", () => {
    expect(
      canCreateWorksmobileRow({
        resourceType: "USER",
        status: "missing_in_worksmobile",
        baronId: "user-1",
      }),
    ).toBe(true);

    expect(
      canCreateWorksmobileRow({
        resourceType: "USER",
        status: "missing_in_worksmobile",
      }),
    ).toBe(false);

    expect(
      canCreateWorksmobileRow({
        resourceType: "USER",
        status: "missing_in_baron",
        worksmobileId: "works-user-1",
      }),
    ).toBe(false);
  });

  it("allows selection for Baron-only, WORKS-only, and matched rows", () => {
    expect(
      canSelectWorksmobileRow({
        resourceType: "USER",
        status: "missing_in_worksmobile",
        baronId: "user-1",
      }),
    ).toBe(true);
    expect(
      canSelectWorksmobileRow({
        resourceType: "USER",
        status: "missing_in_baron",
        worksmobileId: "works-user-1",
      }),
    ).toBe(true);
    expect(
      canSelectWorksmobileRow({
        resourceType: "USER",
        status: "matched",
        baronId: "user-2",
        worksmobileId: "works-user-2",
      }),
    ).toBe(true);
  });

  it("does not allow selection for immutable WORKS accounts", () => {
    expect(
      isImmutableWorksmobileAccount({
        resourceType: "USER",
        status: "missing_in_baron",
        worksmobileEmail: "cyhan@samaneng.com",
        worksmobileId: "works-cyhan",
      }),
    ).toBe(true);
    expect(
      canSelectWorksmobileRow({
        resourceType: "USER",
        status: "missing_in_baron",
        worksmobileEmail: "CYHAN1@HANMACENG.CO.KR",
        worksmobileId: "works-cyhan1",
      }),
    ).toBe(false);
    expect(
      canSelectWorksmobileRow({
        resourceType: "USER",
        status: "missing_in_baron",
        worksmobileEmail: "normal@samaneng.com",
        worksmobileId: "works-normal",
      }),
    ).toBe(true);
  });

  it("does not allow password management for immutable WORKS accounts", () => {
    expect(
      canOpenWorksmobilePasswordManage(
        {
          resourceType: "USER",
          status: "missing_in_baron",
          worksmobileEmail: "su-@samaneng.com",
          worksmobileDomainId: 300285955,
          worksmobileId: "works-su",
        },
        "works-tenant-1",
      ),
    ).toBe(false);
  });

  it("hides protected WORKS member accounts from comparison lists", () => {
    const rows = [
      {
        resourceType: "USER",
        status: "missing_in_baron",
        worksmobileEmail: "su-@samaneng.com",
        worksmobileId: "works-su",
      },
      {
        resourceType: "USER",
        status: "matched",
        baronEmail: "CYHAN1@HANMACENG.CO.KR",
        baronId: "baron-cyhan1",
        worksmobileEmail: "cyhan1@hanmaceng.co.kr",
        worksmobileId: "works-cyhan1",
      },
      {
        resourceType: "USER",
        status: "missing_in_baron",
        worksmobileEmail: "normal@samaneng.com",
        worksmobileId: "works-normal",
      },
      {
        resourceType: "GROUP",
        status: "missing_in_baron",
        worksmobileEmail: "su-@samaneng.com",
        worksmobileId: "works-group",
      },
    ];

    expect(filterVisibleWorksmobileComparisonRows(rows)).toEqual([
      rows[2],
      rows[3],
    ]);
  });

  it("keeps row selection keys separate from Baron action ids", () => {
    const rows = [
      {
        resourceType: "USER",
        status: "missing_in_worksmobile",
        baronId: "baron-only",
      },
      {
        resourceType: "USER",
        status: "missing_in_baron",
        worksmobileId: "works-only",
      },
      {
        resourceType: "USER",
        status: "matched",
        baronId: "matched-baron",
        worksmobileId: "matched-works",
      },
    ];

    const selectedKeys = rows.map(getWorksmobileRowSelectionKey);

    expect(selectedKeys).toEqual([
      "USER:baron:baron-only",
      "USER:works:works-only",
      "USER:baron:matched-baron",
    ]);
    expect(getWorksmobileSelectedActionIds(rows, selectedKeys)).toEqual([
      "baron-only",
      "matched-baron",
    ]);
  });

  it("uses compact comparison columns by default", () => {
    expect(getDefaultWorksmobileComparisonColumns()).toEqual({
      status: true,
      baronId: false,
      baron: true,
      baronOrg: true,
      worksmobileId: false,
      externalKey: false,
      worksmobileDomain: true,
      worksmobile: true,
      worksmobileOrg: true,
      manage: true,
    });
  });

  it("filters user comparison rows by selected relationship", () => {
    const rows = [
      {
        resourceType: "USER",
        status: "missing_in_worksmobile",
        baronId: "baron-only",
        baronName: "Baron only",
      },
      {
        resourceType: "USER",
        status: "missing_in_baron",
        worksmobileId: "works-only",
        worksmobileName: "WORKS only",
      },
      {
        resourceType: "USER",
        status: "matched",
        baronId: "matched",
        worksmobileId: "works-matched",
      },
      {
        resourceType: "USER",
        status: "missing_external_key",
        worksmobileId: "missing-external-key",
      },
    ];

    expect(filterWorksmobileComparisonRows(rows, ["baron_only"])).toEqual([
      rows[0],
    ]);
    expect(filterWorksmobileComparisonRows(rows, ["works_only"])).toEqual([
      rows[1],
      rows[3],
    ]);
    expect(filterWorksmobileComparisonRows(rows, ["matched"])).toEqual([
      rows[2],
    ]);
    expect(
      filterWorksmobileComparisonRows(rows, ["baron_only", "works_only"]),
    ).toEqual([rows[0], rows[1], rows[3]]);
    expect(filterWorksmobileComparisonRows(rows, [], true)).toEqual([]);
    expect(filterWorksmobileComparisonRows(rows, [])).toEqual([]);
    expect(
      filterWorksmobileComparisonRows(rows, [
        "baron_only",
        "works_only",
        "matched",
      ]),
    ).toEqual(rows);
    expect(
      filterWorksmobileComparisonRows(
        rows,
        ["baron_only", "works_only", "matched"],
        true,
      ),
    ).toEqual([rows[0], rows[2], rows[3]]);
  });

  it("narrows works-only rows to missing external key rows from the detail filter", () => {
    const rows = [
      {
        resourceType: "GROUP",
        status: "missing_in_worksmobile",
        baronId: "baron-only",
        baronName: "Baron only",
      },
      {
        resourceType: "GROUP",
        status: "missing_in_baron",
        worksmobileId: "works-only",
        worksmobileName: "WORKS only",
      },
      {
        resourceType: "GROUP",
        status: "missing_external_key",
        worksmobileId: "missing-external-key",
      },
      {
        resourceType: "GROUP",
        status: "matched",
        baronId: "matched",
        worksmobileId: "works-matched",
      },
    ];

    expect(
      filterWorksmobileComparisonRows(rows, ["works_only"], false),
    ).toEqual([rows[1], rows[2]]);
    expect(filterWorksmobileComparisonRows(rows, ["works_only"], true)).toEqual(
      [rows[2]],
    );
    expect(filterWorksmobileComparisonRows(rows, [], true)).toEqual([]);
    expect(filterWorksmobileComparisonRows(rows, ["baron_only"], true)).toEqual(
      [rows[0]],
    );
  });

  it("filters comparison rows by names and identifiers in real time", () => {
    const rows = [
      {
        resourceType: "USER",
        status: "matched",
        baronId: "baron-user-uuid",
        baronName: "홍길동",
        worksmobileName: "Hong Gildong",
      },
      {
        resourceType: "GROUP",
        status: "missing_external_key",
        worksmobileId: "works-org-uuid",
        worksmobileName: "기술연구소",
        worksmobileParentName: "한맥가족",
      },
      {
        resourceType: "GROUP",
        status: "missing_in_worksmobile",
        baronId: "baron-org-uuid",
        baronSlug: "baron-group-design",
        baronName: "디자인팀",
      },
    ];

    expect(filterWorksmobileComparisonRowsBySearch(rows, "")).toEqual(rows);
    expect(filterWorksmobileComparisonRowsBySearch(rows, "홍길동")).toEqual([
      rows[0],
    ]);
    expect(filterWorksmobileComparisonRowsBySearch(rows, "WORKS-ORG")).toEqual([
      rows[1],
    ]);
    expect(filterWorksmobileComparisonRowsBySearch(rows, "design")).toEqual([
      rows[2],
    ]);
    expect(filterWorksmobileComparisonRowsBySearch(rows, "없음")).toEqual([]);
  });

  it("returns only selected missing-external-key WORKS orgunit ids for delete", () => {
    const rows = [
      {
        resourceType: "GROUP",
        status: "missing_external_key",
        worksmobileId: "works-missing-key",
      },
      {
        resourceType: "GROUP",
        status: "missing_in_baron",
        worksmobileId: "works-only",
      },
      {
        resourceType: "USER",
        status: "missing_external_key",
        worksmobileId: "works-user-missing-key",
      },
    ];

    expect(
      getWorksmobileSelectedMissingExternalKeyOrgUnitIds(rows, [
        getWorksmobileRowSelectionKey(rows[0]),
        getWorksmobileRowSelectionKey(rows[1]),
        getWorksmobileRowSelectionKey(rows[2]),
      ]),
    ).toEqual(["works-missing-key"]);
  });

  it("returns selected WORKS-only orgunit ids for Baron SSOT cleanup", () => {
    const rows = [
      {
        resourceType: "GROUP",
        status: "missing_external_key",
        worksmobileId: "works-missing-key",
      },
      {
        resourceType: "GROUP",
        status: "missing_in_baron",
        worksmobileId: "works-only",
        externalKey: "legacy-external-key",
      },
      {
        resourceType: "GROUP",
        status: "matched",
        baronId: "baron-matched",
        worksmobileId: "works-matched",
      },
    ];

    expect(
      getWorksmobileSelectedWorksOnlyOrgUnitIds(
        rows,
        rows.map(getWorksmobileRowSelectionKey),
      ),
    ).toEqual(["works-missing-key", "works-only"]);
  });

  it("orders user comparison filter options from Baron-only first", () => {
    expect(userFilterOptions.map((option) => option.value)).toEqual([
      "baron_only",
      "needs_update",
      "works_only",
      "matched",
    ]);
  });

  it("keeps all organization/group comparison filter labels available", () => {
    expect(comparisonFilterOptions).toEqual([
      { value: "baron_only", label: "바론에만 있음" },
      { value: "needs_update", label: "업데이트 필요" },
      { value: "works_only", label: "웍스에만 있음" },
      { value: "matched", label: "양쪽 다 있음" },
    ]);
  });

  it("shows update-needed group rows by default", () => {
    const rows = [
      { resourceType: "GROUP", status: "needs_update", baronId: "org-1" },
      { resourceType: "GROUP", status: "matched", baronId: "org-2" },
    ];

    expect(
      filterWorksmobileComparisonRows(rows, getDefaultGroupComparisonFilters()),
    ).toEqual([rows[0]]);
  });

  it("formats update details for changed organization rows", () => {
    expect(
      formatWorksmobileUpdateDetails({
        resourceType: "GROUP",
        status: "needs_update",
        baronId: "818c856b-9545-442f-b827-d1c569f200b0",
        baronName: "삼안기술개발센터(조직도용)",
        worksmobileName: "기술개발센터(조직도용)",
        baronParentId: "9caf62e1-297d-4e8f-870b-61780998bbeb",
        baronParentWorksmobileId: "works-saman",
        baronParentWorksmobileName: "삼안",
        worksmobileParentId: "works-other",
        worksmobileParentName: "다른 상위",
      }),
    ).toEqual([
      "이름: 기술개발센터(조직도용) -> 삼안기술개발센터(조직도용)",
      "상위: 다른 상위 -> 삼안",
    ]);
  });

  it("formats WORKS account name with level on one line", () => {
    expect(
      formatWorksmobilePersonName({
        resourceType: "USER",
        status: "matched",
        worksmobileName: "홍길동",
        worksmobileLevelName: "책임",
      }),
    ).toBe("홍길동 책임");
  });

  it("formats WORKS organization details with task and manager status", () => {
    expect(
      formatWorksmobileOrgDetails({
        resourceType: "USER",
        status: "matched",
        worksmobileTask: "기술검토",
        worksmobilePrimaryOrgPositionName: "팀장",
        worksmobilePrimaryOrgIsManager: true,
      }),
    ).toEqual(["직책 팀장", "직무 기술검토", "조직장"]);
  });

  it("builds the WORKS admin password management URL from remote user identifiers", () => {
    const url = buildWorksmobilePasswordManageUrl({
      tenantId: " works-tenant-1 ",
      domainId: 300285955,
      userIdNo: " works-user-1 ",
    });

    const parsed = new URL(url);
    expect(parsed.origin + parsed.pathname).toBe(
      "https://auth.worksmobile.com/integrate/password/manage",
    );
    expect(parsed.searchParams.get("usage")).toBe("admin");
    expect(parsed.searchParams.get("targetUserTenantId")).toBe(
      "works-tenant-1",
    );
    expect(parsed.searchParams.get("targetUserDomainId")).toBe("300285955");
    expect(parsed.searchParams.get("targetUserIdNo")).toBe("works-user-1");
    expect(parsed.searchParams.get("accessUrl")).toBe(
      "https://admin.worksmobile.com/assets/self-close.html",
    );
  });

  it("does not open WORKS password management without required identifiers", () => {
    const row = {
      resourceType: "USER",
      status: "matched",
      worksmobileDomainId: 300285955,
      worksmobileId: "works-user-1",
    };

    expect(canOpenWorksmobilePasswordManage(row, "works-tenant-1")).toBe(true);
    expect(canOpenWorksmobilePasswordManage(row, undefined)).toBe(false);
    expect(
      canOpenWorksmobilePasswordManage(
        { ...row, worksmobileDomainId: undefined },
        "works-tenant-1",
      ),
    ).toBe(false);
    expect(
      canOpenWorksmobilePasswordManage(
        { ...row, worksmobileId: undefined },
        "works-tenant-1",
      ),
    ).toBe(false);
    expect(
      canOpenWorksmobilePasswordManage(
        { ...row, resourceType: "GROUP" },
        "works-tenant-1",
      ),
    ).toBe(false);
    expect(
      buildWorksmobilePasswordManageUrl({
        tenantId: "works-tenant-1",
        domainId: 0,
        userIdNo: "works-user-1",
      }),
    ).toBe("");
  });

  it("allows WORKS password management for WORKS-only user rows", () => {
    expect(
      canOpenWorksmobilePasswordManage(
        {
          resourceType: "USER",
          status: "missing_in_baron",
          worksmobileDomainId: 300285955,
          worksmobileId: "works-user-1",
        },
        "works-tenant-1",
      ),
    ).toBe(true);
  });
});
