/**
 *
 * 当前应用queen5接受的消息处理。
 *   目前文件依赖 设计为 当前文件 依赖于modules/ediotor/controllers下的文件，这样避免share页面打包
 *   当前模块，导致nats.ws文件被引用，引发 部分手机 share页面打不开的bug
 */

import { cloneDeep } from "lodash";
import { queenApi } from "queenjs";
import { Controller } from "../core/controller";
import { useCtx } from "../ctx";
export class AppScreenMsgController extends Controller {
  screenModule: any;
  constructor() {
    super();
  }

  onReady() {
    // this.initScreen();
  }

  initScreen() {
    const { recvCtrl } = useCtx();

    recvCtrl.clearListeners();
    recvCtrl.addAssetsListener("发送模型", async (packUrl: string) => {
      const urlReg = /[a-zA-z]+:\/\/[^\s]*/;
      let packId = packUrl;
      if (urlReg.test(packUrl)) {
        const urlArr = packUrl.split("?");
        const params = urlArr[1].split("&");
        let obj: any = {};
        for (let i = 0; i < params.length; i++) {
          let param = params[i].split("=");
          obj[param[0]] = param[1];
        }
        packId = obj.id;
      }
      if (!packId) {
        return false;
      }
      this.downloadLocalPack(packId);
      return true;
    });
    recvCtrl.emitChange();
  }
  async downloadLocalPack(packId: string) {
    const { actions } = this.screenModule;
    const assetDtl = await actions.getAssetDetail(packId);
    if (assetDtl) {
      this.exportLocalWebPack(assetDtl);
    }
  }

  loadfile(dir: string, url: string) {
    if (!url) return;
    const { deviceCtrl } = useCtx();
    let names = url.split("/");
    let name = names[names.length - 1];
    const screenDir = deviceCtrl.appDataDir + "/screen";
    const filepath = screenDir + dir + name;
    return {
      file: dir + name,
      promise: new Promise((resolve) => {
        deviceCtrl.DownloadFile(url, filepath).then((ok) => {
          setTimeout(() => {
            resolve({ name: name, ok: ok });
          }, 0);
        });
      }),
    };
  }

  async exportLocalWebPack(asset: any) {
    queenApi.showLoading("资源下载中");
    const { deviceCtrl } = useCtx();

    let files: any = [];
    let pack = cloneDeep(asset);
    let source = pack.source;
    let wk = `/assets/packs/${pack._id}/`;
    let scope = this;

    function getFileName(url: string) {
      if (!url) return;

      let names = url.split("/");
      let name = names[names.length - 1];
      return name;
    }

    //模型处理
    let geom = source.geoms[0];
    let osgbinUrl = geom.osgjs.url;
    source.geoms = [geom];
    let f = this.loadfile(wk, geom.osgjs.url);
    files.push(f?.promise);
    geom.osgjs.url = f?.file;

    osgbinUrl = osgbinUrl.substring(0, osgbinUrl.length - 5) + "bin";
    f = this.loadfile(wk, osgbinUrl);
    files.push(f?.promise);
    f = this.loadfile(wk, geom.shadow.url);
    if (f) {
      files.push(f?.promise);
      geom.shadow.url = f.file;
    }
    delete geom.file;
    delete geom.glb;

    //材质处理
    for (let i = 0; i < source.mats.length; i++) {
      const m = source.mats[i];
      //base
      let f = scope.loadfile(wk, m.albedo.texture?.url);
      if (f) {
        files.push(f?.promise);
        source.mats[i].albedo.texture.url = f.file;
      }
      //法线
      if (m.normal?.texture) {
        f = scope.loadfile(wk, m.normal.texture?.url);
        if (f) {
          files.push(f?.promise);
          source.mats[i].normal.texture.url = f.file;
        }
      }
      //粗糙度
      if (m.roughness.texture) {
        f = scope.loadfile(wk, m.roughness.texture.url);
        if (f) {
          files.push(f?.promise);
          source.mats[i].roughness.texture.url = f.file;
        }
      }
      //金属度
      if (m.metalness.texture) {
        f = scope.loadfile(wk, m.metalness.texture.url);
        if (f) {
          files.push(f?.promise);
          source.mats[i].metalness.texture.url = f.file;
        }
      }
      //透明度
      if (m.opacity.texture) {
        f = scope.loadfile(wk, m.opacity.texture.url);
        if (f) {
          files.push(f?.promise);
          source.mats[i].opacity.texture.url = f.file;
        }
      }
    }

    //封面图
    let thumbnail = pack.thumbnail;
    const thumb = this.loadfile(wk, thumbnail.url);
    files.push(thumb?.promise);
    pack.thumbnail.url = thumb?.file;
    //环境球
    const wkenv3d = "/assets/env3d/";
    const env3dIds: any = [];
    source.scenes.forEach((item: any) => {
      if (item.envId) {
        const envItem = source.env3ds.find((e: any) => {
          const id = e.userData.assetId || e.id;
          return id == item.envId;
        });
        if (envItem) {
          env3dIds.push(envItem.id);
        }
      }
    });
    source.env3ds.forEach((item: any) => {
      const id = item.userData.assetId || item.id;
      if (!env3dIds.includes(id)) {
        return false;
      }
      const wk = wkenv3d + id + "/bg/";
      let f = this.loadfile(wk, item.background?.image?.url);
      if (f) {
        item.background.image.url = f.file;
        files.push(f.promise);
      }
      const twk = wkenv3d + id + "/t/";
      item.config.textures.forEach((t: any) => {
        t.images.forEach((im: any) => {
          const f = this.loadfile(twk, im.file);
          if (f) {
            im.file = f.file;
            files.push(f.promise);
          }
        });
      });
    });

    const wk3 = wkenv3d + "bg/";
    source.scenes.forEach((c: any) => {
      //@ts-ignore
      const url = c.background?.image?.url;
      if (url) {
        const f = this.loadfile(wk3, url);
        if (f) {
          //@ts-ignore
          c.background.image.url = f.file;
          files.push(f.promise);
        }
      }
    });

    const configFile = JSON.stringify(pack);
    Promise.all(files).then(async (ressult) => {
      queenApi.hideLoading();
      const failRes = ressult.filter((e) => {
        return e.ok == false;
      });
      if (failRes.length > 0) {
        queenApi.messageError(`${failRes[0].name}等文件下载失败！`);
        return;
      }
      const res = await deviceCtrl.WriteFileText(
        `${deviceCtrl.appDataDir}/screen/assets/packs/${pack._id}.json`,
        configFile
      );
      const currentCategory = localStorage.getItem("category") || "default";
      const assetsJson = await deviceCtrl.ReadFileText(
        `${deviceCtrl.appDataDir}/screen/assets_${currentCategory}.json`
      );
      if (assetsJson.text) {
        const assets = JSON.parse(assetsJson.text);
        const assetItem = {
          _id: pack._id,
          name: pack.name,
          thumbnail: pack.thumbnail.url,
          type: "3D",
          meshId: `/assets/packs/${pack._id}.json`,
        };
        assets.push(assetItem);
        await deviceCtrl.WriteFileText(
          `${deviceCtrl.appDataDir}/screen/assets_${currentCategory}.json`,
          JSON.stringify(assets)
        );
      }
      this.screenModule.actions.getAssetList();
    });
  }
}
