import pako from "pako"; // 解密gzip插件
import { useWebSocket } from "@vueuse/core";
import { useUserStore } from "@/pinia/user";
import pinia from "@/pinia";
import { getRealTimeList, getFenceList } from "@/request/map";

const userStore = useUserStore(pinia);
const pls_ip = userStore.getUserInfo.POST_URL;
// const pls_ip = "http://121.22.38.202:8084";
let entityArr = [];
let billboardArr = [];
const fencesArr = [];
const leftObj = {
  perDataList: [],
  armDataList: [],
  regPerDataList: [], // 区域人员统计
  deptDataList: [], // 部门统计
};
const { open, close } = useWebSocket(
  encodeURI("ws://" + pls_ip.replace("http://", "") + "/netty/test.io?u=1"),
  // encodeURI("ws://58.58.162.14:8084/netty/test.io?userid=1"),
  {
    immediate: false,
    heartbeat: {
      message: "ping",
      interval: 5000,
      pongTimeout: 1000,
    },
    delay: 1000,
    onMessage: (ws, event) => {
      const msg = unzip(event.data);
      const decodedMsg = JSON.parse(decodeURIComponent(msg));
      if (decodedMsg.msg === "000") {
        peoMovement(decodedMsg.data);
      }
      if (decodedMsg.msg === "006") {
        addNewPerson(decodedMsg.data);
      }
      if (decodedMsg.msg === "008") {
        removePerson(decodedMsg.data);
      }
      changeLeftObjData(decodedMsg);
    },
    onDisconnected: () => {
      if (entityArr && entityArr.children) {
        entityArr.children.forEach((e) => {
          e.destroy();
        });
        billboardArr.children.forEach((e) => {
          e.destroy();
        });
        entityArr = [];
        billboardArr = [];
      }
    },
  }
);
export const handleGetPerList = async () => {
  return leftObj;
};
export const handleInit = async () => {
  getOnlineUser();
  open();
};
export const handleTrajectory = (b) => {
  if (b) {
    getOnlineUser();
    open();
  } else {
    close();
  }
};

const getOnlineUser = async () => {
  entityArr = new window.CustomCesium.GroupModel("人物模型");
  billboardArr = new window.CustomCesium.GroupModel("人物姓名");
  await getRealTimeList();
  const { data } = await getRealTimeList();
  const userList = data.data.list;

  userList.forEach((item) => {
    const user = item.split(",");
    addEntity(user[0], user[5], user[1], user[2], user[3], user[8], user[6]);
    addBillboard(user[0], user[5], user[1], user[2], user[3], user[8], user[7]);
  });
  entityArr.show(true);
  billboardArr.show(true);
};

const addEntity = (id, name, lon, lat, height, floor, gltf) => {
  const obj = new window.CustomCesium.Model(window.$icy, {
    url: "/src/assets/glb/" + gltf + ".gltf",
    height: 0,
    scale: 1,
    angle: [-90, 0, 0],
  });
  let e;
  // eslint-disable-next-line prefer-const
  e = obj.clone(e);
  const enModule = new window.CustomCesium.Model(
    window.$icy,
    {
      name: "人物",
      floor,
      peoName: name,
      height,
      id,
      lon,
      lat, // 位置
      scale: 1, // 大小
      angle: [-90, 0, 0],
    },
    e
  );
  // 修改模型方向 第一个参数是航向角
  // enModule.updateAngle([-90,20,20]);
  entityArr.add(enModule);
};

const addBillboard = (id, name, lon, lat, height, floor, type) => {
  // 创建广告牌
  const bulletinBoard = new window.CustomCesium.BulletinBoard(window.$icy);
  bulletinBoard.loadCanvas(drawCanvas(name, floor), {
    name: "人物铭牌",
    floor,
    peoName: name,
    id: id + "_name",
    lon,
    lat,
    height: Number(height) + 2.05,
    url: "/src/assets/glb/" + type + ".png",
  });
  billboardArr.add(bulletinBoard);
};

// eslint-disable-next-line no-unused-vars
const drawCanvas = (name, floor) => {
  const canvas = document.createElement("canvas");
  const width = 160;
  const height = 46;
  canvas.width = width;
  canvas.height = height;
  const borderRadius = 5; // 圆角半径

  const ctx = canvas.getContext("2d");

  ctx.beginPath();
  ctx.moveTo(borderRadius, 0);
  ctx.lineTo(width - borderRadius, 0);
  ctx.arcTo(width, 0, width, borderRadius, borderRadius);
  ctx.lineTo(width, height - borderRadius);
  ctx.arcTo(width, height, width - borderRadius, height, borderRadius);
  ctx.lineTo(borderRadius, height);
  ctx.arcTo(0, height, 0, height - borderRadius, borderRadius);
  ctx.lineTo(0, borderRadius);
  ctx.arcTo(0, 0, borderRadius, 0, borderRadius);
  ctx.closePath();

  ctx.fillStyle = "rgba(42, 86, 158, 1)";
  ctx.fill();

  ctx.fillStyle = "#fff";
  ctx.font = "normal 28px 'Microsoft YaHei'";
  ctx.textAlign = "center";
  ctx.textBaseline = "middle";
  ctx.fillText((name || "未知人员") + `(${floor}F)`, width / 2, height / 2);
  return canvas;
};
const changeLeftObjData = (decodedMsg) => {
  if (decodedMsg.msg === "005") {
    leftObj.perDataList = decodedMsg.data;
  }
  if (decodedMsg.msg === "003") {
    leftObj.armDataList = decodedMsg.data;
  }
  if (decodedMsg.msg === "002") {
    leftObj.regPerDataList = decodedMsg.data;
  }
  if (decodedMsg.msg === "008") {
    leftObj.deptDataList = decodedMsg.data;
  }
};
const addNewPerson = (data) => {
  data.forEach((item) => {
    const entity = item.split(",");
    addEntity(
      entity[0],
      entity[5],
      entity[1],
      entity[2],
      entity[4],
      1,
      entity[6]
    );
    addBillboard(
      entity[0],
      entity[5],
      entity[1],
      entity[2],
      entity[4],
      1,
      entity[7]
    );
  });
};

const removePerson = (data) => {
  data.forEach((item) => {
    entityArr.children.forEach((e) => {
      if (e.entity._id === item) {
        e.destroy();
      }
    });
    billboardArr.children.forEach((e) => {
      if (e.entity._id === item + "_name") {
        e.destroy();
      }
    });
  });
};

const unzip = (b64Data) => {
  let strData = atob(b64Data);

  const charData = strData.split("").map(function (x) {
    return x.charCodeAt(0);
  });

  const binData = new Uint8Array(charData);

  const data = pako.inflate(binData);

  strData = String.fromCharCode.apply(null, new Uint16Array(data));

  return strData;
};
/**
 * moveData 接收webscoket人物移动数据
 * entityArr 接收人物模型分组
 * billboardArr 接收人物铭牌分组
 */
function peoMovement(moveData) {
  const map = new Map();
  moveData.forEach((i, n) => {
    map.set(i.split(",")[0], n);
  });
  entityArr.children.forEach((b, m) => {
    const index = map.get(b.entity._id);
    const item = moveData[index];
    if (index !== undefined) {
      const itData = item.split(","); // itData下标:0=【卡号】,(1,2,4)=【lon,lat,alt】,3=【人物朝向角度】,5=【工号】,6=【当前楼层】
      if (itData[4] != null && itData.length >= 6) {
        b.updateAngle([itData[3], 0, 0]); // 改变人物朝向
        b.animationMove(
          itData[1],
          itData[2],
          Number(itData[4]),
          2000,
          () => {}
        ); // 人物平滑移动
        billboardArr.children[m].animationMove(
          itData[1],
          itData[2],
          Number(Number(itData[4]) + 2.05),
          2000
        ); // 人物铭牌平滑移动
        if (Number(itData[6]) !== Number(b.entity.floor)) {
          b.entity.floor = itData[6];
          billboardArr.children[m].uopdateImg(
            drawCanvas(b.entity.peoName, itData[6]),
            !0
          );
        }
      } else {
        console.log(`人物移动数据错误,错误参数:'${item}'`);
      }
    }
  });
}

export const trackUser = (id, b) => {
  if (b) {
    const t = window.$icy.viewer.entities.getById(id);
    window.$icy.viewer.trackedEntity = t;
    window.$icy.viewer._selectedEntity = t;
    t.viewFrom = new window.Cesium.Cartesian3(-30, 60, 30);
  } else {
    window.$icy.viewer._selectedEntity = undefined;
    window.$icy.viewer.trackedEntity = undefined;
    window.$icy.viewer.camera.lookAtTransform(window.Cesium.Matrix4.IDENTITY);
  }
};

export const handleFence = async (b) => {
  if (b) {
    const { data } = await getFenceList();
    const fences = data.rows;
    fences.forEach((fence) => {
      if (fence.list.length > 0) {
        const enclosure = new window.CustomCesium.Enclosure(window.$icy);
        enclosure.showDataSource(
          fence.list, // 数据
          30, // 高度
          "yellow" // 颜色默认黄色
        );
        fencesArr.push(enclosure);
      }
    });
  } else {
    if (fencesArr) {
      fencesArr.forEach((fence) => {
        fence.clear();
        fence.destroy();
      });
    }
  }
};