import * as THREE from 'three';

const NODE_TYPES = {
  pbsGrp: 1,
  major: 2,
  model: 3,
};

// 处理mesh数据，生成drawObjs
function processMeshData(input, options) {
  const drawObjMap = new Map();

  if (!input.mesh) {
    return [];
  }

  const mergeMaterialByMeshId = new Map();
  const mergeMaterialList = input.mergeMaterial;
  if (Array.isArray(mergeMaterialList)) {
    for (let i = 0; i < mergeMaterialList.length; i++) {
      const it = mergeMaterialList[i];
      if (!it || it.id == null) continue;
      mergeMaterialByMeshId.set(String(it.id), it);
    }
  }

  input.mesh.forEach(meshItem => {
    const geomList = [];
    meshItem.primitives.forEach(primitive => {
      const primitiveData = input.primitive.find(g => g.id === primitive.prmid);
      if (primitiveData) {
        const baseMaterial = input.material?.find(m => m.id === primitiveData.material);
        const mergedMaterial = mergeMaterialByMeshId.get(String(meshItem.id));
        const material = mergedMaterial || baseMaterial;
        const sourceVisible =
          mergedMaterial?.visible === false || baseMaterial?.visible === false ? false : true;
        const prop = {
          color: material?.color || [255, 255, 255, 1],
          fontsize: material?.fontsize !== undefined ? material?.fontsize : 20,
          frontname: material?.frontname !== undefined ? material?.frontname : '',
          italic: material?.italic,
          linepacing: 1, // 默认值
          linewidth: material?.linewidth !== undefined ? material?.linewidth : 1, // 默认值
          visible: sourceVisible,
          sourceVisible,
          transparent: material?.transp !== undefined ? material?.transp : 0,
        };

        const identity = new THREE.Matrix4().identity();

        geomList.push({
          matrix: {
            val: primitive.matrix?.length ? primitive.matrix : identity.elements,
            // val: identity.elements,
          },
          // originMatrix: meshItem.id == primitive.prmid ? [] : identity.elements,
          prmid: primitive.prmid,
          geomId: primitiveData.id,
          type: primitiveData.geomType,
          text: primitiveData.geomText,
          points: primitiveData.position,
          alignType: primitiveData.alignType,
          normals: primitiveData.normal,
          triangles: primitiveData.indices || [],
          max: primitiveData.max,
          min: primitiveData.min,
          prop: prop,
        });
      }
    });

    drawObjMap.set(meshItem.id, {
      drawObjId: meshItem.id,
      geoms: geomList,
      // lodLevel: meshItem.type || 2,
    });
  });

  return Array.from(drawObjMap.values());
}

// 处理node数据，生成instances
function processNodeData(input, options) {
  const flatNode = options?.flatNode;

  function flattenAndComputeWorldMatrices(
    nodes,
    result = [],
    // parentWorldMatrix = null,
    fatherId = ''
  ) {
    for (const node of nodes) {
      const { category, instanceId, matrix, children, drawObject, groupId, nodeType } = node;

      // 构造本地矩阵
      let localMatrix;
      if (matrix && matrix.val) {
        localMatrix = new THREE.Matrix4().fromArray(matrix.val);
      } else {
        localMatrix = new THREE.Matrix4().identity(); // 默认为单位矩阵
      }

      // 计算世界矩阵
      // const worldMatrix = parentWorldMatrix
      //   ? parentWorldMatrix.clone().multiply(localMatrix)
      //   : localMatrix.clone();
      const worldMatrix = localMatrix.clone();

      // 构造输出节点
      result.push({
        drawObject,
        category,
        instanceId,
        // matrix,
        matrix: {
          val: Array.from(worldMatrix.toArray()),
        },
        fatherId,
        groupId,
        nodeType,
      });

      // 递归处理子节点，传递当前世界矩阵
      if (children) {
        flattenAndComputeWorldMatrices(children, result, instanceId);
      }
    }

    return result;
  }

  if (!flatNode) {
    const formatInstances = [];
    const preNode = input.node ? input.node : generateNode(input.mesh);
    const rootInstances = parseNode(preNode);
    flattenAndComputeWorldMatrices(rootInstances, formatInstances);

    return formatInstances;
  } else {
    return parseNode(input.node, flatNode);
  }
}

// 处理一个primitive，生成多个drawObj
function processOnePrimtiveToMultiMesh(primitive) {
  return {
    instanceId: primitive.drawObjId, // 实例与drawObj一对多关系
    drawObject: primitive.geoms[0]?.prmid || '',
    matrix: primitive.geoms[0]?.matrix || [],
  };
}

// 主解析函数，整合两个独立模块的结果
function parseData(input, options) {
  const drawObjs = processMeshData(input, options);
  const instances = drawObjs.map(item => {
    return processOnePrimtiveToMultiMesh(item); // 实例与drawObj一对多关系
  });
  // const instances = drawObjs.map((item) => {
  //   return {
  //     instanceId: item.drawObjId, // 实例与drawObj一对一关系
  //     drawObject: item.drawObjId,
  //   }
  // })
  // const instances = processNodeData(input);

  const map = {
    drawObjs,
    instances,
  };
  // console.log('parseData', map);
  return map;
}

// 递归处理节点实例
function parseNode(node, isFlatNode) {
  function processInstance(instance, parentInstanceId, instanceMap, groupId, isFlatNode) {
    const newInstance = {
      category: instance.category || instance.name,
      drawObject: instance.drawObject || instance.mesh,
      fatherId: parentInstanceId || '',
      instanceId: instance.id || instance.batchId,
      matrix: instance.matrix,
      children: [],
      nodeType: instance.nodeType,
      groupId: instance.nodeType === NODE_TYPES.pbsGrp ? instance._batchId : groupId,
    };

    if (!isFlatNode) {
      // 处理子实例
      if (instance.children && instance.children.length > 0) {
        instance.children.forEach(childId => {
          const childInstance = instanceMap.get(childId);
          if (childInstance) {
            const processedChild = processInstance(
              childInstance,
              instance._batchId,
              instanceMap,
              newInstance.groupId
            );
            newInstance.children.push(processedChild);
          }
        });
      }
    }

    return newInstance;
  }

  const rootInstances = [];
  // 创建实例映射
  if (!isFlatNode) {
    const instanceMap = new Map();
    node.forEach(instance => {
      instanceMap.set(instance.id, instance);
    });

    // 处理根实例
    instanceMap.forEach(instance => {
      let isRoot = true;
      instanceMap.forEach(otherInstance => {
        if (otherInstance.children && otherInstance.children.includes(instance.id)) {
          isRoot = false;
        }
      });
      if (isRoot) {
        const processed = processInstance(instance, instance._batchId, instanceMap);
        rootInstances.push(processed);
      }
    });
  } else {
    // 处理根实例
    node.forEach(instance => {
      const processed = processInstance(instance, instance._batchId, {}, 0, isFlatNode);
      rootInstances.push(processed);
    });
  }
  return rootInstances;
}
// 生成默认node节点
function generateNode(mesh) {
  let nodes = [];
  mesh.forEach(item => {
    if (item.primitives.length) {
      let tempNode = {
        id: item.id,
        _batchId: item.id,
        name: item.id,
        mesh: item.id,
        matrix: {},
        nodeType: 3,
      };
      nodes.push(tempNode);
    }
  });

  return nodes;
}

export { parseData, parseNode, processMeshData, processNodeData };
