// usePermission Hook 单测
// 依据：project_rules §3.1（前端禁止 role === "xxx" 硬编码，统一用 hasPermission）
// 覆盖：hasPermission / hasAnyPermission / hasAllPermissions / isAuthenticated / 无用户态

import { describe, it, expect, beforeEach, afterEach } from "vitest";
import { renderHook, cleanup } from "@testing-library/react";
import { usePermission } from "./usePermission";
import { setUser, clearAuth } from "@/lib/auth";
import { PERMISSIONS } from "@/lib/permissions";
import { mockParent } from "@/test/mocks/fixtures";

beforeEach(() => {
  localStorage.clear();
  clearAuth();
});

afterEach(() => {
  cleanup();
});

describe("usePermission", () => {
  it("无用户时 permissions 为空且未认证", () => {
    const { result } = renderHook(() => usePermission());
    expect(result.current.permissions).toEqual([]);
    expect(result.current.isAuthenticated).toBe(false);
  });

  it("无用户时 hasPermission 返回 false", () => {
    const { result } = renderHook(() => usePermission());
    expect(result.current.hasPermission(PERMISSIONS.DASHBOARD_VIEW)).toBe(
      false,
    );
  });

  it("无用户时 hasAnyPermission 返回 false", () => {
    const { result } = renderHook(() => usePermission());
    expect(
      result.current.hasAnyPermission(
        PERMISSIONS.DASHBOARD_VIEW,
        PERMISSIONS.CHILD_GRADE_VIEW,
      ),
    ).toBe(false);
  });

  it("无用户时 hasAllPermissions 返回 false", () => {
    const { result } = renderHook(() => usePermission());
    expect(
      result.current.hasAllPermissions(
        PERMISSIONS.DASHBOARD_VIEW,
        PERMISSIONS.CHILD_GRADE_VIEW,
      ),
    ).toBe(false);
  });

  it("有用户时 isAuthenticated 为 true", () => {
    setUser(mockParent);
    const { result } = renderHook(() => usePermission());
    expect(result.current.isAuthenticated).toBe(true);
  });

  it("有用户时 permissions 返回用户权限列表", () => {
    setUser(mockParent);
    const { result } = renderHook(() => usePermission());
    expect(result.current.permissions).toContain("DASHBOARD_VIEW");
    expect(result.current.permissions).toContain("CHILD_GRADE_VIEW");
    expect(result.current.permissions).toContain("NOTIFICATION_VIEW");
  });

  it("hasPermission 拥有该权限时返回 true", () => {
    setUser(mockParent);
    const { result } = renderHook(() => usePermission());
    expect(result.current.hasPermission(PERMISSIONS.DASHBOARD_VIEW)).toBe(true);
    expect(result.current.hasPermission(PERMISSIONS.CHILD_GRADE_VIEW)).toBe(
      true,
    );
    expect(result.current.hasPermission(PERMISSIONS.NOTIFICATION_VIEW)).toBe(
      true,
    );
  });

  it("hasPermission 未拥有该权限时返回 false", () => {
    setUser(mockParent);
    const { result } = renderHook(() => usePermission());
    // mockParent 没有 ADMIN 权限
    expect(result.current.hasPermission("ADMIN" as never)).toBe(false);
  });

  it("hasAnyPermission 任一权限满足时返回 true", () => {
    setUser(mockParent);
    const { result } = renderHook(() => usePermission());
    expect(
      result.current.hasAnyPermission(
        PERMISSIONS.DASHBOARD_VIEW,
        "ADMIN" as never,
      ),
    ).toBe(true);
  });

  it("hasAnyPermission 所有权限都不满足时返回 false", () => {
    setUser(mockParent);
    const { result } = renderHook(() => usePermission());
    expect(
      result.current.hasAnyPermission("ADMIN" as never, "SUPER" as never),
    ).toBe(false);
  });

  it("hasAnyPermission 空参数返回 false", () => {
    setUser(mockParent);
    const { result } = renderHook(() => usePermission());
    expect(result.current.hasAnyPermission()).toBe(false);
  });

  it("hasAllPermissions 所有权限满足时返回 true", () => {
    setUser(mockParent);
    const { result } = renderHook(() => usePermission());
    expect(
      result.current.hasAllPermissions(
        PERMISSIONS.DASHBOARD_VIEW,
        PERMISSIONS.CHILD_GRADE_VIEW,
        PERMISSIONS.NOTIFICATION_VIEW,
      ),
    ).toBe(true);
  });

  it("hasAllPermissions 部分权限不满足时返回 false", () => {
    setUser(mockParent);
    const { result } = renderHook(() => usePermission());
    expect(
      result.current.hasAllPermissions(
        PERMISSIONS.DASHBOARD_VIEW,
        "ADMIN" as never,
      ),
    ).toBe(false);
  });

  it("hasAllPermissions 空参数返回 true", () => {
    setUser(mockParent);
    const { result } = renderHook(() => usePermission());
    expect(result.current.hasAllPermissions()).toBe(true);
  });
});
