<template>
  <div v-if="pageState === State.Load" class="full-screen flex">
    <AppLoading :size="80"/>
    <p>加载中...</p>
  </div>
  <WineControlPage v-else-if="pageState === State.Show" class="full-screen" ref="ListPage" @to_adv="play_adv"/>
  <AdvertisePage v-else-if="pageState === State.Play" class="full-screen" :ads="ads" @to_wine="show_wine"/>
  <WineChangePage v-else-if="pageState === State.Change" class="full-screen" :who="who" @to_wine="show_wine"/>
  <DeviceFixPage v-else-if="pageState === State.Fix" class="full-screen" :who="who" @to_wine="show_wine"/>
  <div v-else class="full-screen flex">illegal operation</div>

  <div class="fixed-info" @click="_onSetDebug(true)">{{ info.seq }} [{{ info.ver }}]</div>
  <AlertPopup class="full-screen" v-if="alert.show" ref="alert" @mounted="AlertReady" @close="HideAlert"/>
  <div class="debug" v-if="debug.show">
    <div class="debug-clear" @click="debug.texts = [];">清 空</div>
    <pre class="debug-text">{{ debug.texts.join('\n') }}</pre>
  </div>
</template>

<script>
import AdvertisePage from "@/pages/AdvertisePage";
import WineControlPage from "@/pages/WineControlPage";
import AppLoading from "@/components/AppLoading";
import WineChangePage from "@/pages/WineChangePage";
import DeviceFixPage from "@/pages/DeviceFixPage";
import AlertPopup from "@/components/AlertPopup";

const GapTime = 200;
export default {
  directives: {
    click: {
      mounted(el, binding) {
        let timer = null, count = 0, timeout = 150;
        const clearTimer = () => {
          clearTimeout(timer);
          timer = null;
        }
        const handler = function () {
          if (timer === null) {
            count = 0;
            timer = setTimeout(clearTimer, 1000);
          }
          count++;
          if (count === 5) {
            setTimeout(() => {
              if (count === 5) {
                count = 0;
                binding.value.t5();
              }
            }, timeout);
          } else if (count === 7) {
            setTimeout(() => {
              if (count === 7) {
                count = 0;
                binding.value.t7();
              }
            }, timeout);
          }
        }
        el.__my_click = handler;
        el.addEventListener("click", handler);
      },
      unmounted(el) {
        el.removeEventListener("click", el.__my_click);
        delete el.__my_click;
      }
    }
  },
  components: {
    AlertPopup,
    DeviceFixPage,
    WineChangePage,
    AppLoading,
    AdvertisePage,
    WineControlPage
  },
  name: "App",
  data() {
    let state = {Load: "Loading", Show: "Showing", Play: "Playing", Change: "Changing", Fix: "Fixing"};
    return {
      info: {seq: "NULL-Device-Seq", ver: "V0.0"},
      alert: {
        show: false, time: -1, title: "", color: "", subtitle: "", icon: "",
        button: {need: false, text: "", callback: null, countdown: -1}
      },
      debug: {show: false, texts: []},
      State: state,
      pageState: state.Load,
      who: "",
      ads: [],
      wines: []
    }
  },
  methods: {
    _start(device, version) {
      this.info.seq = device;
      this.info.ver = version;

      this.$utils.EventBus["ShowAlert"] = this.ShowAlert;
      this.$utils.EventBus["ShowError"] = this.ShowError;
      this.$utils.EventBus["HideAlert"] = this.HideAlert;
      this.$utils.EventBus["debug"] = this.addDebug;

      this.$utils.ConnectSocket(device);
      this.$utils.SockEventMap["__Error_Event__"] = this.ShowError;
      this.$utils.SockEventMap["setDebug"] = this._onSetDebug;
      this.$utils.SockEventMap["ppvUpdate"] = this._onPpvUpdate;
      this.$utils.SockEventMap["wineResult"] = this._onWineResult;
      this.$utils.SockEventMap["advResult"] = this._onAdvResult;
      this.$utils.SockEventMap["runParamResult"] = this._onRunParamResult;
      this.$utils.SockEventMap["initFinish"] = this._onInitFinish;
      this.$utils.SockEventMap["openGate"] = this._onOpenGateCommand;
    },
    _onSetDebug(debug) {
      this.$utils.DebugMode = this.debug.show = debug;
      this.$utils.Android(debug ? "show" : "hide");
      this.addDebug(`set debug: ${debug}`);
    },
    _onPpvUpdate(data) {
      this.addDebug(`update ppv${data.index + 1} => ${data.value}`);
      this.$utils.Wines[data.index].ppv = data.value;
    },
    _onWineResult(wines) {
      for (let i = 0; i < wines.length; ++i) {
        wines[i].cell = i;
        wines[i].density = wines[i].density / 1000;
        wines[i].price_in_yuan = wines[i].price / 100;  // 分 -> 元
        wines[i].remain_in_weight = this.$utils.Volume2Weight(wines[i].remain, wines[i].density);  // ml -> 两
      }
      this.$utils.Wines = wines;
    },
    _onAdvResult(ads) {
      this.ads = ads;
    },
    _onRunParamResult(params) {
      params.forEach(e => this.$utils.ParamMap[e.key] = e.value);
    },
    _onInitFinish() {
      this.pageState = this.State.Show;
    },
    _onOpenGateCommand(data) {
      this.addDebug(`open gate: ${JSON.stringify(data)}`);
      if (this.pageState === data.kind) return;
      this.HideAlert(true);
      if (this.pageState !== this.State.Show) this.pageState = this.State.Show;
      setTimeout(() => {
        this.$refs.ListPage.Over();
        this.who = data.who;
        this.pageState = data.kind;
      }, GapTime);
    },
    show_wine() {
      this.pageState = this.State.Show;
      this.$utils.Android("setVolume", this.$utils.ParamMap.VolumeNormal);
    },
    play_adv() {
      this.pageState = this.State.Play;
      this.$utils.Android("setVolume", this.$utils.ParamMap.VolumeAdv);
    },
    addDebug(msg) {
      this.debug.texts.unshift(msg);
    },
    AlertReady() {
      this.$refs.alert.Update(this.alert.options);
    },
    ShowError(msg) {
      this.alert.show = false;
      this.alert = {
        show: true, callback: null, options: {
          time: 2, title: "发 生 错 误", color: "red",
          subtitle: msg, icon: `${process.env.BASE_URL}icon/error.svg`,
          button: {need: false, text: "", countdown: -1}
        }
      };
    },
    ShowAlert(options) {
      this.alert.show = false;
      setTimeout(() => this.alert = {options: options, callback: options.callback, show: true}, GapTime);
    },
    HideAlert(restrain = false) {
      this.alert.show = false;
      !restrain && this.alert.callback && this.alert.callback();
    }
  },
  mounted() {
    if (window.android === undefined) this.$utils.VmAndroid();

    this.$utils.Register("__Error_Happened__", this.ShowError);
    this.$utils.Register("pon", () => {
    });
    this.$utils.Register("startApp", this._start);
    this.$utils.Android("onWebMounted");
    setInterval(() => this.$utils.Android("pin"), 10 * 60 * 1000);
  }
}
</script>

<style scoped>
.fixed-info {
  position: fixed;
  top: 10px;
  right: 10px;
  color: lightgray;
  cursor: pointer;
  z-index: 100100;
}

.full-screen {
  width: 100%;
  height: 100%;
}

.flex {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.debug {
  width: 40%;
  height: 50%;
  position: fixed;
  left: 5px;
  bottom: 5px;
  z-index: 20020;
  box-sizing: border-box;
  background-color: ghostwhite;
  border-radius: 2px;
  border: 1px solid lightgray;
  padding: 2px 4px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.debug-clear {
  width: 100%;
  border-bottom: 1px solid black;
  cursor: pointer;
  line-height: 24px;
  text-align: center;
  font-weight: bold;
}

.debug-clear:active {
  font-weight: normal;
}

.debug-text {
  width: 100%;
  height: calc(100% - 22px);
  overflow-y: scroll;
}

.debug-text::-webkit-scrollbar {
  display: none;
}
</style>
