import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = dirname(fileURLToPath(import.meta.url));
const source = readFileSync(join(__dirname, "OrgPermissionTree.vue"), "utf8");

describe("OrgPermissionTree hierarchy lines", () => {
  it("draws connector lines only between each node and its direct children", () => {
    assert.match(source, /\.org-tree-children\s*>\s*\.org-tree-branch::before/);
    assert.match(source, /\.org-tree-children\s*>\s*\.org-tree-branch\s*>\s*\.org-tree-node::before/);
    assert.doesNotMatch(source, /\.org-tree-children::before/);
    assert.doesNotMatch(source, /^\.org-tree-branch::before/m);
    assert.match(source, /--tree-connector-x/);
    assert.match(source, /--tree-node-start/);
    assert.match(source, /--tree-arrow-gap/);
    assert.match(source, /--tree-connector-color/);
    assert.match(source, /--tree-connector-color:\s*rgba\(148,\s*163,\s*184/);
    assert.match(source, /--tree-connector-width:\s*2px/);
    assert.match(source, /border-left:\s*var\(--tree-connector-width\)\s*dashed\s*var\(--tree-connector-color\)/);
    assert.match(source, /border-top:\s*var\(--tree-connector-width\)\s*dashed\s*var\(--tree-connector-color\)/);
    assert.doesNotMatch(source, /background:\s*var\(--tree-connector-color\)/);
  });
});

describe("OrgPermissionTree employee list", () => {
  it("shows each employee organization path with full-value hover text", () => {
    assert.match(source, /<th>组织路径<\/th>/);
    assert.match(source, /employeeOrganizationPath\(employee\)/);
    assert.match(source, /class="org-path-value"\s+:title="employeeOrganizationPath\(employee\)"/);
    assert.match(source, /class="org-path-tail"\s+:title="employeeOrganizationPath\(employee\)"/);
    assert.match(source, /function employeeOrganizationTail\(employee\)/);
    assert.doesNotMatch(source, /org-path-pill/);
    assert.match(source, /<td colspan="7" class="empty-row"/);
  });

  it("keeps row action buttons inside an inner flex container instead of flexing the table cell", () => {
    assert.match(source, /<td class="action-row">\s*<div class="employee-actions">/);
    assert.match(source, /\.employee-actions\s*\{[\s\S]*?display:\s*inline-flex;/);
    assert.doesNotMatch(source, /\.action-row\s*\{[^}]*display:\s*flex;/);
  });
});

describe("OrgPermissionTree node action parity", () => {
  it("exposes a visible current-node action entry that emits the shared node context menu event", () => {
    assert.match(source, /节点操作/);
    assert.match(source, /@click\.stop="openSelectedNodeMenu"/);
    assert.match(source, /function openSelectedNodeMenu\(event\)/);
    assert.match(source, /emit\("node-contextmenu"/);
    assert.doesNotMatch(source, /function runNodeAction\(/);
    assert.doesNotMatch(source, /function nodeActions\(/);
  });

  it("keeps the original tree-node right-click path routed to the shared context menu event", () => {
    assert.match(source, /@open-menu="openNodeMenu"/);
    assert.match(source, /onContextmenu:\s*openMenu/);
    assert.match(source, /function openMenu\(event\)[\s\S]*?branchEmit\("open-menu"/);
    assert.match(source, /function openNodeMenu\(payload\)[\s\S]*?emit\("node-contextmenu",\s*payload\)/);
  });
});

describe("OrgPermissionTree manager visibility", () => {
  it("shows organization managers in both tree nodes and the selected-node header", () => {
    assert.match(source, /class="node-manager-line"\s+:title="selectedNodeManagerText"/);
    assert.match(source, /const selectedNodeManagerText = computed\(\(\) => selectedNode\.value \? nodeManagerText\(selectedNode\.value\) : "主管：未选择组织"\);/);
    assert.match(source, /class:\s*"tree-node-manager",\s*title:\s*nodeManagerText\(branchProps\.node\)/);
    assert.match(source, /function nodeManagerNames\(node\)/);
    assert.match(source, /function nodeManagerText\(node\)/);
    assert.match(source, /主管：未设置/);
  });
});
