export interface SystemMenu {
  id: string;
  parentId: string | null;
  name: string;
  idPath: string | null;
  url: string | null;
  roleName: string | null;
  sortOrder: number;
  isActive: boolean;
  isTopActive: boolean;
  isDefault: boolean;
  largeIconId: string | null;
  largeIconName: string | null;
  largeIconUrl: string | null;
  smallIconId: string | null;
  smallIconName: string | null;
  smallIconUrl: string | null;
}

export interface SystemMenuNode extends SystemMenu {
  depth: number;
  children: SystemMenuNode[];
}

export const EMPTY_FIELD_PLACEHOLDER = '-';

export function formatOptionalValue(
  value: string | number | null | undefined
): string {
  return value === null || value === undefined || value === ''
    ? EMPTY_FIELD_PLACEHOLDER
    : String(value);
}

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

/**
 * 평면 목록을 트리로 세운다. 부모가 목록에 없는 항목(권한 때문에 잘려 온 가지 등)은 뿌리로
 * 올려 화면에서 사라지지 않게 한다.
 */
export function buildMenuTree(items: SystemMenu[]): SystemMenuNode[] {
  const byId = new Map<string, SystemMenuNode>();
  for (const item of items) {
    byId.set(item.id, { ...item, depth: 0, children: [] });
  }

  const roots: SystemMenuNode[] = [];
  for (const node of byId.values()) {
    const parent = node.parentId ? byId.get(node.parentId) : undefined;
    if (parent && parent !== node) {
      parent.children.push(node);
    } else {
      roots.push(node);
    }
  }

  function order(nodes: SystemMenuNode[], depth: number): SystemMenuNode[] {
    nodes.sort((a, b) => a.sortOrder - b.sortOrder || a.id.localeCompare(b.id));
    for (const node of nodes) {
      node.depth = depth;
      order(node.children, depth + 1);
    }
    return nodes;
  }

  return order(roots, 0);
}

/** 펼쳐진 가지만 위에서부터 한 줄씩 늘어놓는다. */
export function flattenOpenNodes(
  nodes: SystemMenuNode[],
  isOpen: (id: string) => boolean
): SystemMenuNode[] {
  const rows: SystemMenuNode[] = [];

  function walk(list: SystemMenuNode[]) {
    for (const node of list) {
      rows.push(node);
      if (node.children.length > 0 && isOpen(node.id)) {
        walk(node.children);
      }
    }
  }

  walk(nodes);
  return rows;
}

export function collectNodeIds(nodes: SystemMenuNode[]): string[] {
  const ids: string[] = [];

  function walk(list: SystemMenuNode[]) {
    for (const node of list) {
      if (node.children.length > 0) {
        ids.push(node.id);
        walk(node.children);
      }
    }
  }

  walk(nodes);
  return ids;
}

/**
 * 새로 만들 메뉴의 `menuIdPath` — 조상 경로다(부모 경로 + 부모 id).
 *
 * 백엔드는 이 값을 받아 저장만 하고 만들어 주지 않는다(등록 SQL이 `IFNULL(#{menuIdPath}, '/')`).
 * 규격을 정한 곳이 없어 뿌리는 `/`, 그 아래는 `/3`, `/3/18`로 쌓는 형식을 쓴다.
 */
export function buildChildIdPath(parent: SystemMenu | null): string {
  if (!parent) {
    return '/';
  }
  const base = parent.idPath && parent.idPath !== '/' ? parent.idPath : '';
  return `${base}/${parent.id}`;
}

/** 수정·추가 팝업의 상위메뉴명 표시 — 기획의 `[3] 고객센터` 형식. */
export function formatParentLabel(parent: SystemMenu | null): string {
  return parent ? `[${parent.id}] ${parent.name}` : '';
}
