import { relicsScenesFetch, updateRelicsScenePosNameFetch } from "@/request";
import { computed, ref, watch } from "vue";
import { Scene, ScenePoint } from "@/request/type";
import { relics } from "./relics";
import { DeviceType, DeviceType as SceneType } from "./device";
import { conversionFactory } from "@/helper/coord-transform";
import { getTokenFetch } from "@/request";
import {
  PolygonsPointAttrib,
  getWholeLineLinesByPointId,
  PolygonsAttrib,
} from "drawing-board";
import { getDrawingDetailFetch } from "@/request/drawing";

export type { Scene, ScenePoint };

export const scenes = ref<Scene[]>([]);
export const scenePoints = computed(() =>
  scenes.value.reduce((t, scene) => {
    t.push(
      ...scene.scenePos.map((point) => ({
        ...point,
        cameraType: scene.cameraType,
      }))
    );
    return t;
  }, [] as ScenePoint[])
);

export const relicsId = computed(() => relics.value!.relicsId);

// https://4dkankan.oss-cn-shenzhen.aliyuncs.com/scene_view_data/KJ-t-OgSx9XIrvNQ/images/panoramas/22.jpg?x-oss-process=image/resize,m_fixed,w_6144&171342528615

export const getPointPano = (point: ScenePoint, tile = false) => {
  if (tile) {
    const fileNames = new Array(6).fill(0);
    return fileNames.map(
      (_, i) =>
        `https://4dkk.4dage.com/scene_view_data/${point.sceneCode}/images/tiles/4k/${point.uuid}_skybox${i}.jpg`
    );
  } else if (point.cameraType === DeviceType.VR) {
    return `https://4dkankan.oss-cn-shenzhen.aliyuncs.com/scene_view_data/${point.sceneCode}/images/panoramas/${point.uuid}.jpg`;
  } else if (point.cameraType === DeviceType.CLUNT) {
    return `https://4dkk.4dage.com/scene_view_data/${point.sceneCode}/images/pan/high/${point.uuid}.jpg`;
  }
};

export const refreshScenes = async () => {
  const sscenes = await relicsScenesFetch(relicsId.value);
  scenes.value = sscenes.map((scene) => {
    const c = scene.controlPoint;
    let conversion: ReturnType<typeof conversionFactory> | null;
    let scenesTransform: {
      [key in string]: { translate: number[]; rotate: number };
    } = {};
    if (c) {
      c.status = 0;
    }
    if (
      c &&
      c.ageControlLocation1 &&
      c.ageControlLocation1.length &&
      c.status !== 0
    ) {
      conversion = conversionFactory(
        [c.ageControlLocation1, c.ageControlLocation2],
        [c.gpsControlCoordinate1, c.gpsControlCoordinate2]
      );

      scene.datasets.forEach((dataset) => {
        scenesTransform[dataset.sceneCode] = {
          translate: conversion!.toLocal(dataset.location),
          rotate: dataset.orientation,
        };
      });
    }

    return {
      ...scene,
      scenePos: scene.scenePos
        .sort((a, b) => a.index - b.index)
        .map((pos) => {
          let coord =
            scene.calcStatus !== SceneStatus.SUCCESS ? ([] as any) : pos.pos;
          if (conversion && scene.calcStatus === SceneStatus.SUCCESS) {
            let center = scenesTransform[pos.sceneCode]?.translate || [0, 0, 0];
            let rotate = scenesTransform[pos.sceneCode]?.rotate || 0;
            let [x, y, z] = pos.location;
            console.log(pos.location);
            const cos = Math.cos(rotate);
            const sin = Math.sin(rotate);
            x = x * cos - y * sin + center[0];
            y = x * sin + y * cos + center[1];

            coord = conversion.toWGS84([x, y, z]);
          }
          return {
            ...pos,
            pos: coord,
          };
        }),
    };
  });

  await refreshBoardData();
};

export const updateScenePointName = async (point: ScenePoint) => {
  await updateRelicsScenePosNameFetch(point);
  relicsId.value && (await refreshScenes());
};

export const gotoScene = async (scene: Scene, edit = false) => {
  const params = new URLSearchParams();
  if (edit) {
    try {
      const res = await getTokenFetch(scene.sceneCode);
      params.set("token", (res as any).token);
    } catch {
      edit = false;
    }
  }
  params.set("lang", "zh");
  if (scene.sceneCode.startsWith("KJ")) {
    const qjURL = import.meta.env.VITE_QJ_URL;
    params.set("id", scene.sceneCode);
    // console.log('')
    window.open(`${qjURL}/${edit ? "edit" : "show"}.html?` + params.toString());
  } else {
    params.set("m", scene.sceneCode);
    window.open(`${import.meta.env.VITE_LASER_URL}/?` + params.toString());
  }
};

// 普通场景状态
export enum SceneStatus {
  ERR = -1,
  RUN = 0,
  SUCCESS = 1,
  // DEL = 2,
  // ARCHIVE = 3,
  // RERUN = 4,
}

export { SceneType };
export const SceneTypeDesc: { [key in SceneType]: string } = {
  [SceneType.VR]: "全景VR",
  [SceneType.CLUNT]: "点云场景",
};

export const SceneStatusDesc: { [key in SceneStatus]: string } = {
  // [SceneStatus.DEL]: "场景被删",
  // [SceneStatus.ARCHIVE]: "封存",
  // [SceneStatus.RERUN]: "重新计算中",
  [SceneStatus.RUN]: "计算中",
  [SceneStatus.ERR]: "计算失败",
  [SceneStatus.SUCCESS]: "计算成功",
};

export const boardData = ref<PolygonsAttrib & { id: string }>();
export const refreshBoardData = async () => {
  const res = await getDrawingDetailFetch(String(relicsId.value));
  const data = (res?.data || {
    points: [],
    polygons: [],
    lines: [],
  }) as PolygonsAttrib;

  boardData.value = {
    ...data,
    id: relicsId.value.toString(),
  };
};

const scenePosTransform = (scenes: Scene[]) => {
  const points: PolygonsPointAttrib[] = [];
  scenes.forEach((scene) => {
    if (scene.calcStatus !== SceneStatus.SUCCESS) {
      return;
    }
    scene.scenePos.forEach((pos) => {
      if (!pos.pos || pos.pos.length === 0) {
        return;
      }
      points.push({
        x: pos.pos[0],
        y: pos.pos[1],
        type: pos.type,
        title: pos.index
          ? pos.index + (pos.name ? "-" + pos.name : "")
          : pos.name,
        id: pos.id.toString(),
        rtk: true,
      });
    });
  });
  return points;
};

watch(
  () => ({ scenes: scenes.value, poyData: boardData.value }),
  ({ scenes, poyData }) => {
    if (!poyData) return;

    const points = scenePosTransform(scenes);
    const canDelPoint = (id: string) =>
      getWholeLineLinesByPointId(poyData, id).length === 0 &&
      !points.some(({ id: rtkId }) => id === rtkId);

    // 查看是否有多余的点，有则删除，出现原因是删除了场景
    for (let i = 0; i < poyData.points.length; i++) {
      if (canDelPoint(poyData.points[i].id)) {
        poyData.points.splice(i--, 1);
      }
    }

    // 将rtk点加入
    for (let i = 0; i < points.length; i++) {
      const ndx = poyData.points.findIndex(({ id }) => id === points[i].id);
      if (!~ndx) {
        poyData.points.push(points[i]);
      } else {
        poyData.points[ndx] = { ...points[i] };
      }
    }

    poyData.lines = poyData.lines.filter(
      (p) =>
        !p.pointIds.some(
          (id) => !poyData.points.some((point) => point.id === id)
        )
    );

    poyData.polygons.forEach((p) => {
      p.lineIds = p.lineIds.filter((lid) =>
        poyData.lines.some((l) => l.id === lid)
      );
    });
    console.log(poyData);
  },
  { immediate: true, flush: "sync" }
);
