import { EnabledStatus, type EnabledStatus as EnabledStatusCode } from "../../shared/api/enums";
import type { PageResult } from "../../shared/api/types";
import {
  isUserSummary,
  type UserSummary,
} from "../auth/authTypes";

export interface OrganizationNode {
  id: string;
  orgCode: string;
  orgName: string;
  parentId: string | null;
  orgPath: string;
  sortNo: number;
  status: EnabledStatusCode;
  children: OrganizationNode[];
}

export interface OrganizationTreeQuery {
  keyword?: string;
  status?: EnabledStatusCode;
}

export interface UserQuery {
  organizationId?: string;
  includeDescendants?: boolean;
  keyword?: string;
  status?: EnabledStatusCode;
  page?: number;
  pageSize?: number;
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return !!value && typeof value === "object" && !Array.isArray(value);
}

function isId(value: unknown): value is string {
  return typeof value === "string" && /^[0-9]+$/.test(value);
}

function isNonNegativeInteger(value: unknown): value is number {
  return (
    typeof value === "number" &&
    Number.isInteger(value) &&
    value >= 0
  );
}

export function isOrganizationNode(
  value: unknown,
): value is OrganizationNode {
  if (!isRecord(value)) return false;
  return (
    isId(value.id) &&
    typeof value.orgCode === "string" &&
    typeof value.orgName === "string" &&
    (value.parentId === null || isId(value.parentId)) &&
    typeof value.orgPath === "string" &&
    isNonNegativeInteger(value.sortNo) &&
    (Object.values(EnabledStatus) as unknown[]).includes(value.status) &&
    Array.isArray(value.children) &&
    value.children.every(isOrganizationNode)
  );
}

export function isOrganizationTree(
  value: unknown,
): value is OrganizationNode[] {
  return Array.isArray(value) && value.every(isOrganizationNode);
}

export function isUserPage(value: unknown): value is PageResult<UserSummary> {
  if (!isRecord(value)) return false;
  return (
    Array.isArray(value.items) &&
    value.items.every(isUserSummary) &&
    isNonNegativeInteger(value.page) &&
    isNonNegativeInteger(value.pageSize) &&
    isNonNegativeInteger(value.total) &&
    isNonNegativeInteger(value.totalPages)
  );
}

