import { reject } from 'lodash-es';
import { generateUUID } from '../src/tool';

/**
 * 使用turf工具进行切割面
 * @param line 线段数据
 * @param outerPolygon 面数据
 * return  返回切割的面数据
 */
export function splitPolygonByLine(line, outerPolygon) {

  let splitAfterFeatures = [];
  // 判断outerpolygon类型
  if(outerPolygon.geometry.type == "MultiPolygon"){
    // 如果是MultiPolygon图斑 遍历数据 转换为Polygon分割 后合成数组
    
    outerPolygon.geometry.coordinates.forEach((item,index)=>{
      let tempPolygon = {
          "type": "Feature",
          "properties": {
              "id": generateUUID(),
          },
          "geometry": {
              "type": "Polygon",
              "coordinates":null
          }
      };
      tempPolygon.properties.id = generateUUID();
      tempPolygon.geometry.type = "Polygon"
      tempPolygon.geometry.coordinates = item;
      let splitRes = splitByLine(line,tempPolygon);
      // 如果有数据就拼接数据
      if(splitRes){
        splitAfterFeatures = splitAfterFeatures.concat(splitRes);
      }else{
        // 如果没有分割结果直接把这个元素添加到结果中
        splitAfterFeatures = splitAfterFeatures.concat(tempPolygon);
      }
    })

  }else if(outerPolygon.geometry.type == "Polygon"){
    // 如果是Polygon的单图斑 直接获取分割结果
    let splitRes = splitByLine(line,outerPolygon);
   
    // 如果有数据就拼接数据
    if(splitRes){
      splitAfterFeatures = splitAfterFeatures.concat(splitRes);
    }else{
      // 如果没有分割结果直接把这个元素添加到结果中
      splitAfterFeatures = splitAfterFeatures.concat(outerPolygon);
    }
  }
  return splitAfterFeatures;


  let dealOptions = {
    precision: 8,    // 小数点后保留位数
    coordinates: 3,   // 小数点前保留位数
  }
  
  //console.log("************** 分割开始 start **************")


  //console.log("第1步：传入的分割线数据",line);

  //console.log("第2步：传入的分割面数据",outerPolygon)


  // 处理被分割的面数据坐标小数点保留多少位
  let truncatedSplitter = turf.truncate(turf.lineString(outerPolygon.geometry.coordinates[0]), dealOptions);
  //console.log("第3步：分割面转换为线数据",truncatedSplitter);
  //求交点
  let intersectCollection = turf.lineIntersect(line, truncatedSplitter);
  //console.log("第4步：与分割面的交点",intersectCollection);
  // printLngLat(intersectCollection.geometry.coordinates);
  // 交点小于2个 返回null
  if (intersectCollection.features.length < 2) {
    return null;
  }
  //将点合并成MultiPoint
  let intersectCombined = turf.combine(intersectCollection).features[0];
  
  //console.log("第5步：分割后所有点数据",intersectCombined)


  //分别获取切割线
  let outerPieceCollection = turf.lineSplit(line, intersectCombined);
  let splitterPieceCollection = turf.lineSplit(truncatedSplitter, intersectCombined);

  //console.log("第6步：切割线被分割后所有线段",outerPieceCollection);

  //console.log("第7步：切割面被分割后所有线段",splitterPieceCollection);
  
  //将所有的线段放到一起
  let pieceCollection = turf.featureCollection(
    outerPieceCollection.features.concat(splitterPieceCollection.features),
  );
  //console.log("第8步：所有分割线段",pieceCollection);
  //使用turf将闭合线组成多边形
  let polygonCollection = turf.polygonize(pieceCollection);

  //console.log("第9步：分割线合并面数据",polygonCollection)

  //对多边形进行判断，切割外的多边形丢弃
  let innerPolygons = polygonCollection.features.filter((polygon) => {
    // 获取多边形质心 多边形不规则时有问题
    // let newcenter = turf.centroid(polygon);
    let randomCenterPoint =  getRandomPointInPolygon(polygon);

    // 获取多边形表面一点
    let newcenter = turf.pointOnFeature(polygon);
    // 图斑中心点 
    let centerPoint = turf.point(randomCenterPoint.geometry.coordinates);
    //console.log('第10步：封闭图形中心点数据',randomCenterPoint,centerPoint)
    return turf.booleanWithin(centerPoint, outerPolygon);

  });

  //console.log("第11步：返回最终处理后的数据",innerPolygons)
  //   let innerPolygons = polygonCollection.features;

  //处理镂空数据（多处镂空数据会导致计算错误，因为polygonize方法无法正常的返回数据）
  if (outerPolygon.geometry.coordinates?.length > 1) {
    //获取镂空的面数据
    let holeCollection = turf.featureCollection(
      outerPolygon.geometry.coordinates.slice(1).map((item) => turf.polygon([item])),
    );

    //剔除掉镂空的部分数据
    innerPolygons = innerPolygons.map((polygon) => {
      let diff = polygon;
      turf.featureEach(holeCollection, (hole) => {
        // diff = turf.difference(diff, hole);
        diff = turf.difference(turf.featureCollection([diff, hole]))
      });
      return diff;
    });
  }

  // 每个图斑配置UUID 处理每个数据保留8位数
  innerPolygons.forEach((item, index) => {
    
    innerPolygons[index] = turf.truncate(turf.polygon(innerPolygons[index].geometry.coordinates),dealOptions)

    innerPolygons[index].properties.id = generateUUID();
    //console.log("item",item);


  });
  //console.log("************** 分割结束 end **************")
  return innerPolygons;
}

function splitByLine(line,outerPolygon){

  let dealOptions = {
    precision: 8,    // 小数点后保留位数
    coordinates: 3,   // 小数点前保留位数
  }
  
  //console.log("************** 分割开始 start **************")


  //console.log("第1步：传入的分割线数据",line);

  // console.log("第2步：传入的分割面数据",outerPolygon)


  // 处理被分割的面数据坐标小数点保留多少位
  let truncatedSplitter = turf.truncate(turf.lineString(outerPolygon.geometry.coordinates[0]), dealOptions);
  //console.log("第3步：分割面转换为线数据",truncatedSplitter);
  //求交点
  let intersectCollection = turf.lineIntersect(line, truncatedSplitter);
  //console.log("第4步：与分割面的交点",intersectCollection);
  // printLngLat(intersectCollection.geometry.coordinates);
  // 交点小于2个 返回null
  if (intersectCollection.features.length < 2) {
    return null;
  }
  //将点合并成MultiPoint
  let intersectCombined = turf.combine(intersectCollection).features[0];
  
  console.log("第5步：分割后所有点数据",intersectCombined)


  //分别获取切割线
  let outerPieceCollection = turf.lineSplit(line, intersectCombined);
  let splitterPieceCollection = turf.lineSplit(truncatedSplitter, intersectCombined);

  //console.log("第6步：切割线被分割后所有线段",outerPieceCollection);

  //console.log("第7步：切割面被分割后所有线段",splitterPieceCollection);
  
  //将所有的线段放到一起
  let pieceCollection = turf.featureCollection(
    outerPieceCollection.features.concat(splitterPieceCollection.features),
  );
  console.log("第8步：所有分割线段",pieceCollection);
  //使用turf将闭合线组成多边形
  let polygonCollection = turf.polygonize(pieceCollection);

  // console.log("第9步：分割线合并面数据",polygonCollection)

  //对多边形进行判断，切割外的多边形丢弃
  let innerPolygons = polygonCollection.features.filter((polygon) => {
    // 获取多边形质心 多边形不规则时有问题
    // let newcenter = turf.centroid(polygon);
    let randomCenterPoint =  getRandomPointInPolygon(polygon);

    // 获取多边形表面一点
    let newcenter = turf.pointOnFeature(polygon);
    // 图斑中心点 
    let centerPoint = turf.point(randomCenterPoint.geometry.coordinates);
    //console.log('第10步：封闭图形中心点数据',randomCenterPoint,centerPoint)
    return turf.booleanWithin(centerPoint, outerPolygon);

  });

  //console.log("第11步：返回最终处理后的数据",innerPolygons)
  //   let innerPolygons = polygonCollection.features;

  //处理镂空数据（多处镂空数据会导致计算错误，因为polygonize方法无法正常的返回数据）
  if (outerPolygon.geometry.coordinates?.length > 1) {
    //获取镂空的面数据
    let holeCollection = turf.featureCollection(
      outerPolygon.geometry.coordinates.slice(1).map((item) => turf.polygon([item])),
    );

    //剔除掉镂空的部分数据
    innerPolygons = innerPolygons.map((polygon) => {
      let diff = polygon;
      turf.featureEach(holeCollection, (hole) => {
        // diff = turf.difference(diff, hole);
        diff = turf.difference(turf.featureCollection([diff, hole]))
      });
      return diff;
    });
  }

  // 每个图斑配置UUID 处理每个数据保留8位数
  innerPolygons.forEach((item, index) => {
    innerPolygons[index] = turf.truncate(turf.polygon(innerPolygons[index].geometry.coordinates),dealOptions)
    innerPolygons[index].properties.id = generateUUID();
    //console.log("item",item);
  });
  //console.log("************** 分割结束 end **************")
  return innerPolygons;
}
// 获取多边形内随机点
function getRandomPointInPolygon(polygon) {
  const bbox = turf.bbox(polygon); // 获取多边形的边界框
  let point;

  do {
      point = turf.randomPoint(1, {bbox: bbox}).features[0]; // 从边界框中生成一个随机点
  } while (!turf.booleanWithin(point, polygon)); // 检查点是否在多边形内部
  // 直到找到在内部的点再返回数据
  return point;
}

// 单个面数据分割
// 单个面数据分割
export async function splitPolygonByFill(drawPolygon, outerPolygon) {
  return new Promise((resolve,reject)=>{
    try{
      //console.log("第1步：传入的绘制面数据",drawPolygon);
      //console.log("第2步：传入的被切割面数据",outerPolygon)
      
      var polygon1 = turf.polygon(drawPolygon.geometry.coordinates);

      // 判断被分割的面类型
      var polygon2 = null;

      if(outerPolygon.geometry.type == "MultiPolygon"){
        polygon2 = turf.multiPolygon(outerPolygon.geometry.coordinates);
      }else if(outerPolygon.geometry.type == "Polygon"){
        polygon2 = turf.polygon(outerPolygon.geometry.coordinates);
      }
      
  
      let intersection = turf.intersect(turf.featureCollection([polygon1, polygon2]));
      //console.log("第4步：获取绘制图斑和分割图斑的交集",JSON.stringify(polygon2),JSON.stringify(polygon1),intersection);
      
      var difference = turf.difference(turf.featureCollection([polygon2, polygon1]));
      //console.log("第3步：获取绘制图斑和分割图斑的差集",difference);

      let splitAfterFeatures = [intersection,difference];

      resolve(splitAfterFeatures)
    }catch(e){
        //console.log(e);
        reject(null);
    }
  })

}

// 多面数据分割裁剪
export async function splitPolygonByMultiFill(drawPolygons,outerPolygon){

  return new Promise((resolve,reject)=>{
      try{
        let dealOptions = {
          precision: 8,    // 小数点后保留位数
          coordinates: 3,   // 小数点前保留位数
        }
        //console.log("💩第1步：传入的绘制面数据",drawPolygons);
        //console.log("💩第2步：传入的被切割面数据",outerPolygon);

        // 所有结果集合
        let resultArray = [];

        // 绘制图斑和分割图斑数组集合
        let featuresArray = [];

        let turfOuterPolygon = null;


        if(outerPolygon.geometry.type == "Polygon"){ 
          // 如果是单面
          turfOuterPolygon = turf.polygon(outerPolygon.geometry.coordinates)
        }else if(outerPolygon.geometry.type == "MultiPolygon"){
          // 如果是多面
          turfOuterPolygon = turf.multiPolygon(outerPolygon.geometry.coordinates)
        }

        featuresArray.push(turf.truncate(turfOuterPolygon,dealOptions));
        //console.log("💩第3步：处理精度后的被分割图斑",featuresArray);
        
        // 绘制图斑数组
        let splitFeaturesArray = [];

        // 求交集图斑
        drawPolygons.forEach((item,index)=>{
          try{
            let splitPolygonItem = null;
            if(item.geometry.type == "Polygon"){
              // 如果分割图斑是单面
              splitPolygonItem = turf.polygon(item.geometry.coordinates);
            }else if(item.geometry.type == "MultiPolygon"){
              // 如果分割图斑是多面
              splitPolygonItem = turf.multiPolygon(item.geometry.coordinates);
            }
            // 处理精度后绘制图斑
            let turfPolygon = turf.truncate(splitPolygonItem,dealOptions);
            //console.log("💩第4步：处理精度后绘制图斑",turfPolygon);
            console.log("求交集的处理数据：",turf.featureCollection([featuresArray[0],turfPolygon]));
            // 取交集 
            let intersection = turf.intersect(turf.featureCollection([featuresArray[0],turfPolygon]),dealOptions);

            if(intersection){
              resultArray.push(intersection);
            }
            //console.log("💩第5步：交集"+index+"：",intersection)
            splitFeaturesArray.push(turfPolygon);
          }catch(e){
            console.log(e);
          }
        })

        // 取差集
        console.log("求差集的处理数据：",turf.featureCollection(featuresArray.concat(splitFeaturesArray)));
        var difference = turf.difference(turf.featureCollection(featuresArray.concat(splitFeaturesArray)));
        //console.log("💩第6步：差集",difference);
        if(difference){
          resultArray.push(difference);
        }

        // 全部图斑
        //console.log("💩第7步：分割后所有图斑",resultArray);

        resolve(resultArray)
        
      }catch(e){
        //console.log(e);
        reject("分割失败！");
      }
  })
}

// MultiPolygon转换Polygon
export function handlerMultiPolygonToPolygon(sourcePolygons){
  let polygons = [];
  sourcePolygons.forEach((item,ndex)=>{
    if(item.geometry.type == "MultiPolygon"){
      item.geometry.coordinates.forEach((coorItem,idx)=>{
        let polygonItem = {
            "type": "Feature",
            "geometry": {
                "type": "Polygon",
                "coordinates": coorItem
            },
            "properties": {}
        }
        polygons.push(polygonItem);
      })
    }else if(item.geometry.type == "Polygon"){
      polygons.push(item);
    }
  })
  return polygons;
}

export function printLngLat(arr){
  arr.forEach((item,index)=>{
    //console.log(item[1]+","+item[0]+"\n");
  })
}

// 将绑定的多个features的geojson数据处理为multiPolygon数据
export function handlerToMultiPolygonGeoJson(geojson){

  let handlerAfterGeoJson = null;

  if(geojson?.features?.length>1){

    let multiFeature =  {
      "id":generateUUID(),
      "type": "Feature",
      "properties": {
          "id": generateUUID(),
      },
      "geometry": {
          "type": "MultiPolygon",
          "coordinates":[]
      }
    }

    geojson.features?.forEach((item,index)=>{
      if(item.geometry.type == "MultiPolygon"){
        multiFeature.geometry.coordinates = multiFeature.geometry.coordinates.concat(item.geometry.coordinates);
      }else if(item.geometry.type == "Polygon"){
        console.log("item.geometry.coordinates",item.geometry.coordinates)
        multiFeature.geometry.coordinates = multiFeature.geometry.coordinates.concat([item.geometry.coordinates])
      }
    })

    handlerAfterGeoJson =     {
      "type": "FeatureCollection",
      "features": [
        multiFeature
      ]
    };
  }else if(geojson.features?.length == 1){
    handlerAfterGeoJson = {...geojson};
  }
  return handlerAfterGeoJson;
}