// Copyright (c) Huawei Technologies Co., Ltd. 2022-2024. All rights reserved.
// 
// this file licensed under the Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
// PURPOSE.
// See the Mulan PSL v2 for more details.
export interface Part {
  [k: string]: any;
  name: string;
  visible?: boolean;
}

export interface CreateApplyPartsOptions {
  /** 分类名（用于写入 categoryMap）如 'Dimm' | 'Disk' */
  category: string;
  /** 三个映射/容器（沿用现有引用，不新建） */
  partMap: Record<string, Part>;
  categoryMap: Record<string, string[]>;
  infoMap: Record<string, boolean>;
  /** 可选：侧栏白名单（有数据才显示） */
  sidebarAllow?: Record<string, boolean>;
  /** 取 three 中的全量模型部件 */
  getServerParts: () => Part[];
  /** 如何筛选该类部件（保持你现在的正则/逻辑） */
  modelFilter: (m: Part) => boolean;
  /** 子组件提供的“后端真实名称”数组（与模型部件按索引对齐） */
  getChildNames: () => string[] | undefined;
}

export function createApplyParts(opts: CreateApplyPartsOptions): () => void {
  /**
   * 按索引用后端名称重命名模型部件，并同步分类、侧栏与 infoMap。
   * - 未命名项保留在分类末尾（leftovers）
   */
  const {
    category,
    partMap,
    categoryMap,
    infoMap,
    sidebarAllow,
    getServerParts,
    modelFilter,
    getChildNames,
  } = opts;

  return function apply(): void {
    const sps = getServerParts();
    const models = sps.filter(modelFilter);

    if (!models.length) {
      categoryMap[category] = [];
      return;
    }

    const child = getChildNames() ?? [];
    const renamed: string[] = [];
    const leftovers: string[] = [];

    models.forEach((m, i) => {
      const oldName = m.name;
      const newName = child[i]; // 与当前实现一致：索引对齐

      if (newName) {
        m.name = newName;
        partMap[newName] = m;

        if (oldName && oldName !== newName) {
          delete partMap[oldName];
        }

        renamed.push(newName);

        if (sidebarAllow) {
          sidebarAllow[newName] = true;
        }

        infoMap[newName] = true;
      } else {
        leftovers.push(oldName);
      }

      m.visible = true;
    });

    categoryMap[category] = [...renamed, ...leftovers];
  };
}
