export type AdminMenu = {
  id: string;
  parentId: string | null;
  name: string;
  url: string;
  description: string;
  sortOrder: number;
  roleId: string;
  roleName: string;
  isActive: boolean;
  isTopActive: boolean;
};

export type AdminMenuNode = AdminMenu & {
  depth: number;
  children: AdminMenuNode[];
};

export const ADMIN_MENU_ROOT_PATH = '/admins/menus';

export function toYesNo(value: boolean): string {
  return value ? 'Y' : 'N';
}

export const ACTIVE_OPTIONS = [
  { value: 'true', label: '활성' },
  { value: 'false', label: '비활성' },
] as const;

export const NEW_WINDOW_OPTIONS = [
  { value: 'true', label: '예' },
  { value: 'false', label: '아니오' },
] as const;

export function formatActiveLabel(isActive: boolean): string {
  return isActive ? '활성' : '비활성';
}

/**
 * 백엔드가 준 순서(메뉴 등록순)를 유지한 채 `parentId`로만 중첩한다.
 * 부모가 목록에 없는 행은 최상위로 올려 화면에서 사라지지 않게 한다.
 */
export function buildAdminMenuTree(menus: AdminMenu[]): AdminMenuNode[] {
  const nodes = new Map<string, AdminMenuNode>();
  for (const menu of menus) {
    nodes.set(menu.id, { ...menu, depth: 0, children: [] });
  }

  const roots: AdminMenuNode[] = [];
  for (const menu of menus) {
    const node = nodes.get(menu.id);
    if (!node) continue;

    const parent = menu.parentId ? nodes.get(menu.parentId) : undefined;
    if (parent && parent !== node) {
      parent.children.push(node);
    } else {
      roots.push(node);
    }
  }

  const assignDepth = (list: AdminMenuNode[], depth: number) => {
    for (const node of list) {
      node.depth = depth;
      assignDepth(node.children, depth + 1);
    }
  };
  assignDepth(roots, 0);

  return roots;
}

/** 트리를 화면이 그릴 순서(부모 바로 뒤에 자식)로 편다. 접힌 가지는 건너뛴다. */
export function flattenAdminMenuTree(
  roots: AdminMenuNode[],
  collapsedIds: ReadonlySet<string>
): AdminMenuNode[] {
  const rows: AdminMenuNode[] = [];

  const walk = (nodes: AdminMenuNode[]) => {
    for (const node of nodes) {
      rows.push(node);
      if (!collapsedIds.has(node.id)) {
        walk(node.children);
      }
    }
  };
  walk(roots);

  return rows;
}
