<template>
  <Page @loaded="pgLoad" @unloaded="pgUnload" actionBarHidden="true">
    <GridLayout rows="*, auto" columns="*">
      <ScrollView
        @scroll="svScroll($event)"
        rowSpan="2"
        scrollBarIndicatorVisible="false"
      >
        <StackLayout>
          <RGridLayout :rtl="RTL" rows="auto" columns="*, auto, 12">
            <RLabel class="pageTitle" :text="'timer' | L" />
            <Button col="1" class="ico" :text="icon.cog" @tap="navigateTo" />
          </RGridLayout>
          <Timer
            v-for="timer in activeTimers"
            :key="timer.id + key"
            :timer="timer"
            :formattedTime="formattedTime"
            :removeTimer="removeTimer"
            :togglePause="togglePause"
            :timerAlert="timerAlert"
            :showToast="showToast"
          />
          <StackLayout class="listSpace"> </StackLayout>
        </StackLayout>
      </ScrollView>
      <GridLayout v-if="!activeTimers.length" rows="*, auto">
        <StackLayout row="1" class="emptyState">
          <RLabel class="title" :text="'ccwt' | L" />
          <RLabel :text="'plsAdd' | L" />
        </StackLayout>
      </GridLayout>
      <RGridLayout
        :rtl="RTL"
        row="1"
        @loaded="abLoad"
        class="appbar"
        :hidden="showUndo"
        columns="auto, *, auto"
      >
        <Button class="ico rtl" :text="icon.back" @tap="navigateBack" />
        <Button class="ico fab" :text="icon.plus" @tap="addTimer" col="2" />
      </RGridLayout>
      <SnackBar
        :hidden="!showUndo || toast"
        :count="countdown"
        :msg="snackMsg"
        :undo="undoDel"
        :action="hideBar"
        :onload="sbLoad"
      />
      <Toast :onload="tbLoad" :toast="toast" :action="hideBar" />
    </GridLayout>
  </Page>
</template>

<script lang="ts">
import { localize } from "@nativescript/localize";
import {
  Observable,
  CoreTypes,
  Application,
  Utils,
  Device,
  Frame,
} from "@nativescript/core";
import {
  getNumber,
  setNumber,
  remove,
} from "@nativescript/core/application-settings";
import { mapState, mapActions } from "vuex";
import EnRecipes from "./EnRecipes.vue";
import Action from "./modals/Action.vue";
import CTSettings from "./settings/CTSettings.vue";
import TimePickerHMS from "./modals/TimePickerHMS.vue";
import TimerReminder from "./modals/TimerReminder.vue";
import Timer from "./sub/Timer.vue";
import Toast from "./sub/Toast.vue";
import SnackBar from "./sub/SnackBar.vue";
import * as utils from "~/shared/utils";
import { EvtBus } from "~/main";
let barTimer;
declare const com, android: any;
export default {
  components: { Timer, Toast, SnackBar },
  props: ["recipeID"],
  data() {
    return {
      scrollPos: 1,
      appbar: null,
      toastbar: null,
      snackbar: null,
      scrollView: null,
      countdown: 5,
      snackMsg: null,
      showUndo: 0,
      undo: 0,
      toast: null,
      key: 99,
    };
  },
  computed: {
    ...mapState([
      "icon",
      "recipes",
      "timerSound",
      "timerVibrate",
      "timerPresets",
      "activeTimers",
      "FGService",
      "RTL",
    ]),
    hasBackStack() {
      return Frame.topmost().backStack.length;
    },
  },
  methods: {
    ...mapActions([
      "addActiveTimer",
      "removeActiveTimer",
      "clearTimerInterval",
      "addTimerPreset",
      "updateActiveTimer",
      "setFGService",
    ]),
    pgLoad({ object }) {
      object.bindingContext = new Observable();
      if (this.activeTimers.filter((e: any) => e.done).length)
        this.openReminder();
      this.keepScreenOnCountUp();
      setNumber("isTimer", 1);
    },
    pgUnload() {
      utils.keepScreenOn(0);
    },
    abLoad({ object }) {
      this.appbar = object;
    },
    tbLoad({ object }) {
      this.toastbar = object;
    },
    sbLoad({ object }) {
      this.snackbar = object;
    },
    svScroll(args) {
      this.scrollView = args.object;
      let scrollUp;
      let y = args.scrollY;
      if (y) {
        scrollUp = y < this.scrollPos;
        this.scrollPos = Math.abs(y);
        let ab = this.appbar.translateY;
        if (!scrollUp && ab == 0) {
          this.appbar.animate({
            translate: { x: 0, y: 64 },
            duration: 200,
            curve: CoreTypes.AnimationCurve.ease,
          });
        } else if (scrollUp && ab == 64) {
          this.appbar.animate({
            translate: { x: 0, y: 0 },
            duration: 200,
            curve: CoreTypes.AnimationCurve.ease,
          });
        }
      }
    },

    // HELPERS
    getRecipeTitle(id) {
      let recipe = this.recipes.filter((e) => e.id === id)[0];
      return recipe ? recipe.title : `[ ${localize("resNF")} ]`;
    },
    formattedTime(time) {
      let hr = localize("hr");
      let min = localize("min");
      let sec = localize("sec");

      let t = time.split(":");

      let h = parseInt(t[0]);
      let m = parseInt(t[1]);
      let s = parseInt(t[2]);

      let hasHrs = h ? `${h} ${hr}` : "";
      let hasMins = m ? `${h ? " " : ""}${m} ${min}` : "";
      let hasSecs = s ? `${h || m ? " " : ""}${s} ${sec}` : "";

      return hasHrs + hasMins + hasSecs;
    },

    // NOTIFICATION HANDLERS
    timerInfo() {
      let activeCount = this.activeTimers.length;
      let pausedCount = this.activeTimers.filter((e) => e.isPaused).length;
      let ongoingCount = activeCount - pausedCount;
      this.foregroundService(activeCount);
      function show() {
        utils.TimerNotif.show({
          bID: "info",
          cID: "cti",
          cName: "Cooking Timer info",
          description: localize("oAP", ongoingCount + "", pausedCount),
          nID: 6,
          priority: -2,
          sound: null,
          title: localize("timer"),
        });
      }
      if (this.FGService)
        setTimeout(() => this.activeTimers.length && show(), 250);
      this.keepScreenOnCountUp();
      utils.wakeLock(ongoingCount);
    },
    timerAlert() {
      let title, description, bID;
      let firedTimers = this.activeTimers.filter((e) => e.done);
      let timer = firedTimers[0];
      if (firedTimers.length > 1) {
        title = localize("texp", firedTimers.length);
        description = localize("ttv");
        bID = "alerts";
      } else if (firedTimers.length == 1) {
        title =
          timer.label +
          (timer.recipeID ? " - " + this.getRecipeTitle(timer.recipeID) : "");
        description = this.formattedTime(timer.time);
        bID = "timer" + timer.id;
      } else {
        utils.TimerNotif.clear(7);
        return;
      }
      utils.TimerNotif.show({
        actions: 1,
        bID,
        cID: "cta",
        cName: "Cooking Timer alerts",
        description,
        multi: firedTimers.length > 1,
        nID: 7,
        priority: 1,
        sound: this.timerSound.uri,
        title,
        vibrate: this.timerVibrate,
      });
      if (firedTimers.length == 1) {
        Application.android.registerBroadcastReceiver(bID, (ctx, intent) => {
          EvtBus.$emit(bID, intent.getStringExtra("action"));
          Application.android.unregisterBroadcastReceiver(bID);
        });
      } else {
        Application.android.unregisterBroadcastReceiver(bID);
        Application.android.registerBroadcastReceiver(bID, (ctx, intent) => {
          if (intent.getStringExtra("action") == "dismissAll") {
            firedTimers.forEach((t) => this.removeTimer(t.id, 1));
            Application.android.unregisterBroadcastReceiver(bID);
          }
        });
      }
    },
    openReminder() {
      this.clearTimerInterval();
      this.$showModal(TimerReminder, {
        fullscreen: true,
        props: {
          formattedTime: this.formattedTime,
          removeTimer: this.removeTimer,
          togglePause: this.togglePause,
          timerAlert: this.timerAlert,
          showToast: this.showToast,
        },
      }).then(() => {
        this.clearTimerInterval();
        this.key = Math.floor(Math.random() * 900) + 100;
      });
    },
    foregroundService(n) {
      const ctx = Utils.ad.getApplicationContext();
      const intent = new android.content.Intent(
        ctx,
        com.tns.ForegroundService.class
      );
      if (n && !this.FGService) {
        parseInt(Device.sdkVersion) < 26
          ? ctx.startService(intent)
          : ctx.startForegroundService(intent);
        this.setFGService(1);
        setNumber("FGService", 1);
      } else if (!this.activeTimers.length) {
        ctx.stopService(intent);
        this.setFGService(0);
        setNumber("FGService", 0);
      }
    },

    // DATA HANDLERS
    addTimer() {
      this.$showModal(TimePickerHMS, {
        props: {
          title: "ntmr",
          label: `${localize("tmr", this.activeTimers.length + 1)}`,
          action: "strtBtn",
          showPreset: this.timerPresets.length,
        },
      }).then((res) => {
        if (res) {
          if (res == "presets") {
            let list = this.timerPresets.map(
              (e) => `${e.label} - ${this.formattedTime(e.time)}`
            );
            this.$showModal(Action, {
              props: {
                title: "prsts",
                list,
              },
            }).then((preset) => {
              if (preset) {
                let timer = JSON.parse(
                  JSON.stringify(this.timerPresets[list.indexOf(preset)])
                );
                timer.id = utils.getRandomID(1);
                timer.recipeID = this.recipeID;
                timer.timerInt = timer.isPaused = 0;
                timer.preset = timer.mode = 1;
                this.addActiveTimer({
                  timer,
                  i: this.activeTimers.length,
                });
                this.timerInfo();
              }
            });
          } else {
            let mode = res.time != "00:00:00" ? 1 : 0;
            this.addActiveTimer({
              timer: {
                id: utils.getRandomID(1),
                label: res.label,
                recipeID: this.recipeID,
                time: res.time,
                timerInt: 0,
                isPaused: 0,
                preset: 0,
                done: 0,
                mode,
              },
              i: this.activeTimers.length,
            });
            this.timerInfo();
          }
        }
      });
    },
    removeTimer(id, noUndo) {
      let i = this.activeTimers.findIndex((e) => e.id == id);
      let temp = this.activeTimers[i];
      clearInterval(temp.timerInt);
      temp.timerInt = 0;
      this.removeActiveTimer(i);
      let secs = [getNumber(`${temp.id}c`, 0), getNumber(`${temp.id}d`, 0)];
      function removeSettings() {
        remove(`${temp.id}c`);
        remove(`${temp.id}d`);
      }
      removeSettings();
      if (!noUndo) {
        this.showUndoBar("tmrRm")
          .then(() => {
            setNumber(`${temp.id}c`, secs[0]),
              setNumber(`${temp.id}d`, secs[1]),
              this.addActiveTimer({
                timer: temp,
                i,
              });
            this.timerInfo();
          })
          .catch(() => removeSettings());
      }
      this.timerAlert();
      this.timerInfo();
    },
    togglePause(timer, n) {
      timer.isPaused =
        typeof n === "number" ? n : (!timer.isPaused as boolean | 0);
      this.updateActiveTimer(timer);
      n ? 0 : this.timerInfo();
    },
    showToast(data) {
      this.animateBar(this.snackbar, 0);
      this.animateBar(this.appbar, 0).then(() => {
        this.showUndo = 0;
        this.toast = localize(data);
        this.animateBar(this.toastbar, 1);
        let a = 5;
        clearInterval(barTimer);
        barTimer = setInterval(() => a-- < 1 && this.hideBar(), 1000);
      });
    },
    showUndoBar(message) {
      return new Promise((resolve, reject) => {
        this.animateBar(this.toastbar, 0);
        this.animateBar(this.appbar, 0).then(() => {
          this.toast = null;
          this.showUndo = 1;
          this.snackMsg = message;
          this.countdown = 5;
          this.animateBar(this.snackbar, 1).then(() => {
            let a = 5;
            clearInterval(barTimer);
            barTimer = setInterval(() => {
              if (this.undo) {
                this.hideBar();
                resolve(1);
              }
              this.countdown = Math.round((a -= 0.1));
              if (this.countdown < 1) {
                this.hideBar();
                reject(1);
              }
            }, 100);
          });
        });
      });
    },
    hideBar() {
      clearInterval(barTimer);
      this.animateBar(this.toast ? this.toastbar : this.snackbar, 0).then(
        () => {
          this.showUndo = this.undo = 0;
          this.toast = null;
          this.animateBar(this.appbar, 1);
        }
      );
    },
    undoDel() {
      this.undo = 1;
    },

    //NAVIGATION HANDLERS
    navigateTo() {
      this.$navigateTo(CTSettings, {
        transition: {
          name: this.RTL ? "slideRight" : "slide",
          duration: 200,
          curve: "easeOut",
        },
      });
    },
    navigateBack() {
      setNumber("isTimer", 0);
      this.hasBackStack
        ? this.$navigateBack()
        : this.$navigateTo(EnRecipes, {
            clearHistory: true,
          });
    },

    // HELPERS
    keepScreenOnCountUp() {
      utils.keepScreenOn(
        this.activeTimers.filter((e: any) => !e.isPaused).length
      );
    },
  },
  created() {
    this.clearTimerInterval();
    this.recipeID && this.addTimer();
  },
  destroyed() {
    setNumber("isTimer", 0);
  },
};
</script>
