<template>
  <div class="ad" ref="rootEl" v-show="!picking" @contextmenu.prevent="onContextMenuRoot" @mouseleave="onMouseLeaveRoot" @mouseenter="onMouseEnterCocosLogo">
    <div class="title">
      <div class="btns" v-show="showBtns">
        <div v-for="(item, index) in listArray" :key="index" class="list" @click="item.click($event, item)" :title="item.txt" v-show="item.visible">
          <i class="iconfont icon" :class="item.icon" @contextmenu.prevent.stop="item.contextmenu"></i>
        </div>
      </div>
      <i class="iconfont icon_cocos cocos" @mousedown="onMouseDown" @click="onCocosLogoClick"></i>
    </div>
    <!-- <Memory></Memory> -->
    <CCDialog></CCDialog>
    <CCMenu></CCMenu>
  </div>
</template>
<script lang="ts">
import ccui from "@xuyanfeng/cc-ui";
import { IUiMenuItem } from "@xuyanfeng/cc-ui/types/cc-menu/const";
import { storeToRefs } from "pinia";
import { defineComponent, onMounted, ref, toRaw } from "vue";
import { GA_EventName } from "../../ga/type";
import { DocumentEvent } from "../const";
import { inspectTarget } from "../inject/inspect-list";
import Ad from "./ad.vue";
import Banner from "./banner.vue";
import Memory from "./memory.vue";
import { appStore } from "./store";
import { ga } from "./util";
declare const cc: any;
const { CCDialog, CCMenu } = ccui.components;
interface ListItem {
  icon: string;
  txt: string;
  visible: boolean;
  /**
   * 点击回调
   */
  click: (event: MouseEvent, item: ListItem) => void;
  contextmenu: (event: MouseEvent) => void;
}
export default defineComponent({
  name: "ad",
  components: { CCDialog, Banner, Memory, CCMenu },
  setup() {
    const store = appStore();
    store.init();
    const { config } = storeToRefs(appStore());
    const listArray = ref<ListItem[]>([
      {
        icon: "icon_shop_cart ani_shop_cart",
        txt: "Recommended Plugins",
        contextmenu: () => {},
        visible: true,
        click: () => {
          ccui.dialog.showDialog({
            title: "Recommended Plugins",
            comp: Ad,
            width: 310,
            height: 500,
            closeCB: () => {
              ga(GA_EventName.CloseAd);
            },
          });
        },
      },
      {
        icon: "icon_do_play",
        click: (event: MouseEvent, item: ListItem) => {
          ga(GA_EventName.GamePlayer);
          if (typeof cc !== "undefined") {
            cc.game.resume();
          }
        },
        visible: true,
        txt: "game play",
        contextmenu: () => {},
      },
      {
        icon: "icon_do_pause",
        visible: true,
        txt: "game pause",
        click: () => {
          ga(GA_EventName.GamePause);
          if (typeof cc !== "undefined") {
            cc.game.pause();
          }
        },
        contextmenu: () => {},
      },
      {
        icon: "icon_do_step",
        visible: true,
        txt: "game step",
        click: () => {
          ga(GA_EventName.GameStep);
          if (typeof cc !== "undefined") {
            cc.game.step();
          }
        },
        contextmenu: () => {},
      },
      {
        icon: "icon_target",
        txt: "Inspect Game",
        visible: true,
        click: () => {
          ga(GA_EventName.GameInspector);
          if (config.value.autoHide) {
            showBtns.value = false;
          }
          picking.value = true;
          if (typeof cc === "undefined") {
            testInspector();
          } else {
            const event = new CustomEvent(DocumentEvent.GameInspectorBegan);
            document.dispatchEvent(event);
          }
        },
        contextmenu: (event: MouseEvent) => {
          const arr = [
            { name: "Inspect Label", type: typeof cc !== "undefined" ? cc.Label : "cc.Label" }, //
            { name: "Inspect Sprite", type: typeof cc !== "undefined" ? cc.Sprite : "cc.Sprite" },
            { name: "Inspect Button", type: typeof cc !== "undefined" ? cc.Button : "cc.Button" },
            { name: "Inspect RichText", type: typeof cc !== "undefined" ? cc.RichText : "cc.RichText" },
          ];
          const compMenu: IUiMenuItem[] = arr.map((item) => {
            return {
              name: item.name,
              enabled: inspectTarget.enabled,
              selected: inspectTarget.isContainInspectType(item.type),
              callback: (menu: IUiMenuItem) => {
                ga(GA_EventName.MouseMenu, menu.name);
                if (menu.selected) {
                  inspectTarget.removeInspectType(item.type);
                } else {
                  inspectTarget.addInspectType(item.type);
                }
              },
            };
          });
          ccui.menu.showMenuByMouseEvent(event, [
            {
              name: "Clear",
              callback: (menu: IUiMenuItem) => {
                const event = new CustomEvent(DocumentEvent.InspectorClear);
                document.dispatchEvent(event);
                ga(GA_EventName.MouseMenu, menu.name);
              },
            },
            {
              name: "Pick Top",
              selected: config.value.pickTop,
              callback: (menu: IUiMenuItem) => {
                config.value.pickTop = !config.value.pickTop;
                appStore().save();
                ga(GA_EventName.MouseMenu, menu.name);
              },
            },
            { type: ccui.menu.MenuType.Separator },
            {
              name: "Filter Enabled",
              selected: inspectTarget.enabled,
              callback: (menu: IUiMenuItem) => {
                ga(GA_EventName.MouseMenu, menu.name);
                inspectTarget.enabled = !inspectTarget.enabled;
              },
            },
            ...compMenu,
          ]);
        },
      },
    ]);
    document.addEventListener(DocumentEvent.GameInspectorEnd, () => {
      picking.value = false;
    });
    function testInspector() {
      const cursor = document.body.style.cursor;
      document.body.style.cursor = "zoom-in";
      function test(event: MouseEvent) {
        document.removeEventListener("mousedown", test, true);
        document.body.style.cursor = cursor;
        picking.value = false;
      }
      document.addEventListener("mousedown", test, true);
    }
    function recoverAssistantTop() {
      const top = toRaw(config.value.pos);
      updateAssistantTop(top);
    }

    function updateAssistantTop(top: number) {
      const root = toRaw(rootEl.value) as HTMLDivElement;
      if (!root) {
        return;
      }
      if (top < 0) {
        top = 0;
      }
      const maxTop = document.body.clientHeight - root.clientHeight;
      if (top > maxTop) {
        top = maxTop;
      }
      root.style.top = `${top}px`;
      config.value.pos = top;
      appStore().save();
    }
    onMounted(async () => {
      recoverAssistantTop();
      window.addEventListener("resize", () => {
        const root = toRaw(rootEl.value) as HTMLDivElement;
        if (!root) {
          return;
        }
        updateAssistantTop(root.offsetTop);
      });
      return;
    });

    const picking = ref(false);
    const rootEl = ref<HTMLDivElement>(null);
    const showBtns = ref(true);
    if (config.value.autoHide) {
      showBtns.value = false;
    }
    let autoHideTimer = null;
    let isDraging = false;
    return {
      showBtns,
      listArray,
      rootEl,
      picking,
      onMouseEnterCocosLogo() {
        clearTimeout(autoHideTimer);
        showBtns.value = true;
      },
      onCocosLogoClick() {
        showBtns.value = !showBtns.value;
      },
      onContextMenuRoot(event: MouseEvent) {
        const arr: IUiMenuItem[] = [
          {
            name: "auto hide",
            selected: config.value.autoHide,
            callback: (item) => {
              config.value.autoHide = !config.value.autoHide;
              appStore().save();
              ga(GA_EventName.MouseMenu, item.name);
              if (!config.value.autoHide) {
                clearTimeout(autoHideTimer);
                showBtns.value = true;
              }
            },
          },
        ];
        ccui.menu.showMenuByMouseEvent(event, arr);
      },
      onMouseLeaveRoot(event: MouseEvent) {
        if (isDraging) {
          return;
        }
        if (!config.value.autoHide) {
          return;
        }
        autoHideTimer = setTimeout(() => {
          showBtns.value = false;
        }, 500);
      },
      onMouseDown(event: MouseEvent) {
        const root = toRaw(rootEl.value) as HTMLDivElement;
        if (!root) {
          return;
        }
        const startY = event.pageY;
        const startTop = root.offsetTop;
        function onMouseMove(e: MouseEvent) {
          isDraging = true;
          const dy = e.pageY - startY;
          const top = startTop + dy;
          updateAssistantTop(top);
        }

        function onMouseUp(e: MouseEvent) {
          isDraging = false;
          document.removeEventListener("mousemove", onMouseMove, true);
          document.removeEventListener("mouseup", onMouseUp, true);
        }
        document.addEventListener("mousemove", onMouseMove, true);
        document.addEventListener("mouseup", onMouseUp, true);
      },
    };
  },
});
</script>

<style scoped lang="less">
@x: 1px;
@r: 8deg;
@keyframes color-change {
  0% {
    color: #f00;
    transform: rotate(0) translateX(0px);
  }
  20% {
    transform: rotate(-@r) translateX(-@x);
  }
  40% {
    transform: rotate(@r) translateX(@x);
  }
  50% {
    color: #0f0;
  }
  60% {
    transform: rotate(-@r) translateX(-@x);
  }
  80% {
    transform: rotate(@r) translateX(@x);
  }
  100% {
    color: #f00;
    transform: rotate(0) translateX(0px);
  }
}
.ad {
  position: fixed;
  box-shadow: 0px 0px 6px 1px rgb(255, 255, 255);
  //z-index: 99999;
  top: 0px;
  right: 0px;
  display: flex;
  flex-direction: column;
  background-color: white;
  border-top-left-radius: 5px;
  border-bottom-left-radius: 5px;
  // overflow: hidden;
  .title {
    display: flex;
    flex-direction: row;
    align-items: center;
    font-size: 14px;
    user-select: none;
    background-color: rgb(0, 0, 0);
    border: 1px solid black;
    color: white;
    padding: 2px 4px;
    border-top-left-radius: 5px;
    border-bottom-left-radius: 5px;

    .btns {
      color: white;
      display: flex;
      flex-direction: row;
      .list {
        display: flex;
        flex-direction: row;
        align-items: center;
        color: white;
        user-select: none;
        &:hover {
          color: rgb(101, 163, 249);
        }
        &:active {
          color: rgb(255, 187, 0);
        }
        .icon {
          font-size: 20px;
        }
        .ani_shop_cart {
          animation: color-change 2s infinite;
        }
      }
    }
    .cocos {
      cursor: move;
      font-size: 20px;
      color: rgb(85, 192, 224);
    }
  }
}
</style>