<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="goBack()"
      >
        <font-awesome icon="chevron-left" class="fa-fw"></font-awesome>
      </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 v-model="attended" type="checkbox" class="h-6 w-6" />
        <span class="pb-2 pl-2 pr-2">Attended</span>
      </div>
      <div class="m-2 flex">
        <input v-model="gaveTime" type="checkbox" class="h-6 w-6" />
        <span class="pb-2 pl-2 pr-2">Spent Time</span>
        <span v-if="gaveTime">
          <input
            v-model="hoursStr"
            type="text"
            placeholder="How much time"
            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="canSubmit" class="flex justify-center mt-4">
      <button :class="activeButtonClass" @click="record()">Sign & Send</button>
    </div>
    <div v-else class="flex justify-center mt-4">
      <button :class="disabledButtonClass">Select Your Actions</button>
    </div>
  </section>
</template>

<script lang="ts">
import axios from "axios";
import { DateTime } from "luxon";
import { Router } from "vue-router";
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 {
  NOTIFY_BVC_PROCESSING,
  NOTIFY_BVC_TIME_ERROR,
  NOTIFY_BVC_ATTENDANCE_ERROR,
  NOTIFY_BVC_SUBMISSION_ERROR,
  createBvcSuccessMessage,
} from "../constants/notifications";
import { createNotifyHelpers, TIMEOUTS } from "../utils/notify";
import {
  BVC_MEETUPS_PROJECT_CLAIM_ID,
  bvcMeetingJoinClaim,
  createAndSubmitClaim,
  createAndSubmitGive,
} from "../libs/endorserServer";
import * as libsUtil from "../libs/util";
import { logger } from "../utils/logger";
import { PlatformServiceMixin } from "../utils/PlatformServiceMixin";

/**
 * @file QuickActionBvcBeginView.vue
 * @description BVC (Bountiful Volunteerism Community) meeting attendance tracker
 * for Saturday meetings. Allows users to record attendance and time contributions
 * for weekly BVC meetings in Bountiful, using America/Denver timezone.
 * @author Matthew Raymer
 */

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

  // Notification helper system
  private notify = createNotifyHelpers(this.$notify);

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

  /**
   * Lifecycle hook to calculate the current or previous Saturday meeting date
   * Uses America/Denver timezone for Bountiful location
   */
  async mounted() {
    logger.debug(
      "[QuickActionBvcBeginView] Mounted - calculating meeting date",
    );

    // use the time zone for Bountiful
    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,
      }) || "";

    logger.debug(
      "[QuickActionBvcBeginView] Meeting date calculated:",
      this.todayOrPreviousStartDate,
    );
  }

  /**
   * Records attendance and/or time contribution to BVC meeting
   * Creates claims for both attendance and time if applicable
   */
  async record() {
    logger.debug(
      "[QuickActionBvcBeginView] Recording BVC meeting participation",
    );

    // Get account settings using PlatformServiceMixin
    const settings = await this.$accountSettings();
    const activeDid = settings.activeDid || "";
    const apiServer = settings.apiServer || "";

    if (!activeDid || !apiServer) {
      logger.error("[QuickActionBvcBeginView] Missing required settings:", {
        activeDid: !!activeDid,
        apiServer: !!apiServer,
      });
      return;
    }

    try {
      const hoursNum = libsUtil.numberOrZero(this.hoursStr);

      logger.debug("[QuickActionBvcBeginView] Processing submission:", {
        attended: this.attended,
        gaveTime: this.gaveTime,
        hours: hoursNum,
      });

      // Use notification helper with proper timeout
      this.notify.toast(
        NOTIFY_BVC_PROCESSING.title,
        NOTIFY_BVC_PROCESSING.message,
        TIMEOUTS.BRIEF,
      );

      // first send the claim for time given
      let timeSuccess = false;
      if (this.gaveTime && hoursNum > 0) {
        logger.debug("[QuickActionBvcBeginView] Submitting time gift:", {
          hours: hoursNum,
        });

        const timeResult = await createAndSubmitGive(
          axios,
          apiServer,
          activeDid,
          activeDid,
          undefined,
          undefined,
          hoursNum,
          "HUR",
          BVC_MEETUPS_PROJECT_CLAIM_ID,
        );
        if (timeResult.success) {
          timeSuccess = true;
          logger.debug(
            "[QuickActionBvcBeginView] Time gift submission successful",
          );
        } else {
          logger.error(
            "[QuickActionBvcBeginView] Error sending time:",
            timeResult,
          );
          this.notify.error(
            timeResult?.error || NOTIFY_BVC_TIME_ERROR.message,
            TIMEOUTS.LONG,
          );
        }
      }

      // now send the claim for attendance
      let attendedSuccess = false;
      if (this.attended) {
        logger.debug("[QuickActionBvcBeginView] Submitting attendance claim");

        const attendResult = await createAndSubmitClaim(
          bvcMeetingJoinClaim(activeDid, this.todayOrPreviousStartDate),
          activeDid,
          apiServer,
          axios,
        );
        if (attendResult.success) {
          attendedSuccess = true;
          logger.debug(
            "[QuickActionBvcBeginView] Attendance claim submission successful",
          );
        } else {
          logger.error(
            "[QuickActionBvcBeginView] Error sending attendance:",
            attendResult,
          );
          this.notify.error(
            attendResult?.error || NOTIFY_BVC_ATTENDANCE_ERROR.message,
            TIMEOUTS.LONG,
          );
        }
      }

      if (timeSuccess || attendedSuccess) {
        const successMessage = createBvcSuccessMessage(
          timeSuccess,
          attendedSuccess,
        );

        logger.debug(
          "[QuickActionBvcBeginView] Submission completed successfully:",
          { timeSuccess, attendedSuccess },
        );

        this.notify.success(successMessage, TIMEOUTS.STANDARD);
        this.$router.push({ path: "/quick-action-bvc" });
      }

      // eslint-disable-next-line @typescript-eslint/no-explicit-any
    } catch (error: any) {
      logger.error("[QuickActionBvcBeginView] Error sending claims:", error);
      this.notify.error(
        error.userMessage || NOTIFY_BVC_SUBMISSION_ERROR.message,
        TIMEOUTS.LONG,
      );
    }
  }

  /**
   * Navigates back to the previous page
   */
  goBack() {
    this.$router.back();
  }

  /**
   * Computed property for active button styling
   */
  get activeButtonClass() {
    return "block text-center text-md font-bold bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md w-56";
  }

  /**
   * Computed property for disabled button styling
   */
  get disabledButtonClass() {
    return "block text-center text-md font-bold bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md w-56";
  }

  /**
   * Computed property to determine if the submit button should be enabled
   * Returns true if user has attended or provided valid time contribution
   */
  get canSubmit() {
    return (
      this.attended || (this.gaveTime && this.hoursStr && this.hoursStr !== "0")
    );
  }
}
</script>
