<template>
  <QuickNav />
  <TopMessage />

  <!-- CONTENT -->
  <section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
    <!-- Back -->
    <div class="text-lg text-center font-light relative px-7">
      <h1
        class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
        @click="$router.back()"
      >
        <fa icon="chevron-left" class="fa-fw"></fa>
      </h1>
    </div>

    <!-- Heading -->
    <h1 id="ViewHeading" class="text-4xl text-center font-light px-4 mb-4">
      Beginning of BVC Saturday Meeting
    </h1>

    <div>
      <h2 class="text-2xl m-2">You're Here</h2>
      <div class="m-2 flex">
        <input type="checkbox" v-model="attended" class="h-6 w-6" />
        <span class="pb-2 pl-2 pr-2">Attended</span>
      </div>
      <div class="m-2 flex">
        <input type="checkbox" v-model="gaveTime" class="h-6 w-6" />
        <span class="pb-2 pl-2 pr-2">Spent Time</span>
        <span v-if="gaveTime">
          <input
            type="text"
            placeholder="How much time"
            v-model="hoursStr"
            size="1"
            class="border border-slate-400 h-6 px-2"
          />
          hour(s)
        </span>
        <!-- This is to match input height to avoid shifting when hiding & showing. -->
        <span v-else class="h-6" />
      </div>
    </div>

    <div
      v-if="attended || (gaveTime && hoursStr && hoursStr != '0')"
      class="flex justify-center mt-4"
    >
      <button
        @click="record()"
        class="block text-center text-md font-bold bg-blue-500 text-white px-2 py-3 rounded-md w-56"
      >
        Sign & Send
      </button>
    </div>
    <div v-else class="flex justify-center mt-4">
      <button
        class="block text-center text-md font-bold bg-slate-500 text-white px-2 py-3 rounded-md w-56"
      >
        Select Your Actions
      </button>
    </div>
  </section>
</template>

<script lang="ts">
import axios from "axios";
import { DateTime } from "luxon";
import { Component, Vue } from "vue-facing-decorator";

import QuickNav from "@/components/QuickNav.vue";
import TopMessage from "@/components/TopMessage.vue";
import { NotificationIface } from "@/constants/app";
import { db } from "@/db/index";
import {
  BVC_MEETUPS_PROJECT_CLAIM_ID,
  bvcMeetingJoinClaim,
  createAndSubmitClaim,
  createAndSubmitGive,
} from "@/libs/endorserServer";
import * as libsUtil from "@/libs/util";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";

@Component({
  components: {
    QuickNav,
    TopMessage,
  },
})
export default class QuickActionBvcBeginView extends Vue {
  $notify!: (notification: NotificationIface, timeout?: number) => void;

  attended = true;
  gaveTime = true;
  hoursStr = "1";
  todayOrPreviousStartDate = "";

  async mounted() {
    let currentOrPreviousSat = DateTime.now().setZone("America/Denver");
    if (currentOrPreviousSat.weekday < 6) {
      // it's not Saturday or Sunday,
      // so move back one week before setting to the Saturday
      currentOrPreviousSat = currentOrPreviousSat.minus({ week: 1 });
    }
    const eventStartDateObj = currentOrPreviousSat
      .set({ weekday: 6 })
      .set({ hour: 9 })
      .startOf("hour");

    // Hack, but full ISO pushes the length to 340 which crashes verifyJWT!
    this.todayOrPreviousStartDate =
      eventStartDateObj.toISO({
        suppressMilliseconds: true,
      }) || "";
  }

  async record() {
    await db.open();
    const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
    const activeDid = settings?.activeDid || "";
    const apiServer = settings?.apiServer || "";

    try {
      const hoursNum = libsUtil.numberOrZero(this.hoursStr);
      const identity = await libsUtil.getIdentity(activeDid);

      let timeSuccess = false;
      if (this.gaveTime && hoursNum > 0) {
        const timeResult = await createAndSubmitGive(
          axios,
          apiServer,
          identity,
          activeDid,
          undefined,
          undefined,
          hoursNum,
          "HUR",
          BVC_MEETUPS_PROJECT_CLAIM_ID,
        );
        if (timeResult.type === "success") {
          timeSuccess = true;
        } else {
          console.error("Error sending give:", timeResult);
          this.$notify(
            {
              group: "alert",
              type: "danger",
              title: "Error",
              text:
                timeResult?.error?.userMessage ||
                "There was an error sending the time.",
            },
            -1,
          );
        }
      }

      let attendedSuccess = false;
      if (this.attended) {
        const attendResult = await createAndSubmitClaim(
          bvcMeetingJoinClaim(activeDid, this.todayOrPreviousStartDate),
          identity,
          apiServer,
          axios,
        );
        if (attendResult.type === "success") {
          attendedSuccess = true;
        } else {
          console.error("Error sending give:", attendResult);
          this.$notify(
            {
              group: "alert",
              type: "danger",
              title: "Error",
              text:
                attendResult?.error?.userMessage ||
                "There was an error sending the attendance.",
            },
            -1,
          );
        }
      }

      if (timeSuccess || attendedSuccess) {
        const actions =
          timeSuccess && attendedSuccess
            ? "attendance and time have been"
            : timeSuccess
              ? "time has been"
              : "attendance has been";
        this.$notify(
          {
            group: "alert",
            type: "success",
            title: "Success",
            text: `Your ${actions} recorded.`,
          },
          -1,
        );
      }

      // eslint-disable-next-line @typescript-eslint/no-explicit-any
    } catch (error: any) {
      console.error("Error sending claims.", error);
      this.$notify(
        {
          group: "alert",
          type: "danger",
          title: "Error",
          text: error.userMessage || "There was an error sending those claims.",
        },
        -1,
      );
    }
  }
}
</script>
