<template>
  <!-- CONTENT -->
  <section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
    <TopMessage />

    <div class="mb-8">
      <!-- Sub View Heading -->
      <div id="SubViewHeading" class="flex gap-4 items-start mb-4">
        <h1 class="grow text-xl text-center font-semibold leading-tight">
          What Was Given
        </h1>

        <!-- Back -->
        <a
          class="order-first text-lg text-center leading-none p-1"
          @click="cancelBack()"
        >
          <font-awesome icon="chevron-left" class="block text-center w-[1em]" />
        </a>

        <!-- Help button -->
        <router-link
          :to="{ name: 'help' }"
          class="block ms-auto text-sm text-center text-white bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] p-1.5 rounded-full"
        >
          <font-awesome icon="question" class="block text-center w-[1em]" />
        </router-link>
      </div>

      <h2 class="text-lg font-normal leading-tight text-center overflow-hidden">
        <div class="truncate">
          From
          {{
            providedByProject
              ? providerProjectName
              : providedByGiver
                ? giverName
                : "someone not named"
          }}
        </div>
        <div class="truncate">
          to
          {{
            givenToProject
              ? fulfillsProjectName
              : givenToRecipient
                ? recipientName
                : "someone not named"
          }}
        </div>
      </h2>
    </div>

    <textarea
      v-model="description"
      class="block w-full rounded border border-slate-400 mb-2 px-3 py-2"
      placeholder="What was received"
    />
    <div class="flex mb-4">
      <AmountInput
        :value="parseFloat(amountInput) || 0"
        :min="0"
        input-id="inputGivenAmount"
        :on-update-value="handleAmountChange"
      />

      <select
        v-model="unitCode"
        class="flex-1 rounded border border-slate-400 ms-2 px-3 py-2"
      >
        <option
          v-for="(displayName, code) in unitOptions"
          :key="code"
          :value="code"
        >
          {{ displayName }}
        </option>
      </select>
    </div>

    <div class="flex justify-center mt-4" data-testId="imagery">
      <span v-if="imageUrl" class="flex items-end gap-3">
        <a :href="imageUrl" target="_blank">
          <img :src="imageUrl" class="h-36 rounded-lg" />
        </a>
        <font-awesome
          icon="trash-can"
          class="text-red-500 fa-fw cursor-pointer"
          @click="confirmDeleteImage"
        />
      </span>
      <span v-else>
        <font-awesome
          icon="camera"
          class="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-2 rounded-md"
          @click="openImageDialog"
        />
      </span>
    </div>
    <ImageMethodDialog ref="imageDialog" default-camera-mode="environment" />

    <div class="mt-4 sm:flex justify-between gap-2">
      <!-- First Column for Giver -->
      <div
        class="sm:flex-grow sm:w-1/2 border border-slate-400 p-2 rounded-md overflow-hidden"
      >
        <div class="flex items-center">
          <input
            v-if="giverDid && !providedByProject"
            v-model="providedByGiver"
            type="checkbox"
            class="flex-shrink-0 h-6 w-6 mr-2"
          />
          <font-awesome
            v-else
            icon="square"
            class="mr-2 bg-white text-white h-5 w-5 px-0.5 py-0.5 rounded-sm"
          />
          <label class="text-sm truncate">
            {{
              giverDid
                ? "This was provided by " + giverName + "."
                : "No named individual gave."
            }}
          </label>
          <font-awesome
            v-if="!giverDid || providedByProject"
            icon="info-circle"
            class="text-base cursor-pointer bg-white text-slate-500 ms-1"
            @click="notifyUserOfGiver()"
          />
        </div>

        <div class="flex items-center">
          <input
            v-if="providerProjectId && !providedByGiver"
            v-model="providedByProject"
            type="checkbox"
            class="flex-shrink-0 h-6 w-6 mr-2"
          />
          <font-awesome
            v-else
            icon="square"
            class="mr-2 bg-white text-white h-5 w-5 px-0.5 py-0.5 rounded-sm"
          />
          <label class="text-sm truncate">
            {{
              providerProjectId
                ? "This was provided by " + providerProjectName + "."
                : "This was not provided by a project."
            }}
          </label>
          <font-awesome
            v-if="!providerProjectId || providedByGiver"
            icon="info-circle"
            class="text-base cursor-pointer bg-white text-slate-500 ms-1"
            @click="notifyUserOfProvidingProject()"
          />
        </div>
      </div>

      <div class="sm:flex-shrink flex justify-center items-center my-1 sm:my-0">
        <font-awesome
          icon="arrow-right"
          class="fa-fw h-7 rotate-90 sm:rotate-0"
        />
      </div>

      <!-- Third Column for Recipient -->
      <div
        class="sm:flex-grow sm:w-1/2 border border-slate-400 p-2 rounded-md overflow-hidden"
      >
        <div class="flex items-center">
          <input
            v-if="recipientDid && !givenToProject"
            v-model="givenToRecipient"
            type="checkbox"
            class="flex-shrink-0 h-6 w-6 mr-2"
          />
          <font-awesome
            v-else
            icon="square"
            class="mr-2 bg-white text-white h-5 w-5 px-0.5 py-0.5 rounded-sm"
          />
          <label class="text-sm truncate">
            {{
              recipientDid
                ? "This was given to " + recipientName + "."
                : "No named individual benefitted."
            }}
          </label>
          <font-awesome
            v-if="!recipientDid || givenToProject"
            icon="info-circle"
            class="text-base cursor-pointer bg-white text-slate-500 ms-1"
            @click="notifyUserOfRecipient()"
          />
        </div>

        <div class="flex items-center">
          <input
            v-if="fulfillsProjectId && !givenToRecipient"
            v-model="givenToProject"
            type="checkbox"
            class="flex-shrink-0 h-6 w-6 mr-2"
          />
          <font-awesome
            v-else
            icon="square"
            class="mr-2 bg-white text-white h-5 w-5 px-0.5 py-0.5 rounded-sm"
          />
          <label class="text-sm truncate">
            {{
              fulfillsProjectId
                ? "This was given to " + fulfillsProjectName + ". "
                : "No project benefitted."
            }}
          </label>
          <font-awesome
            v-if="!fulfillsProjectId || givenToRecipient"
            icon="info-circle"
            class="text-base cursor-pointer bg-white text-slate-500 ms-1"
            @click="notifyUserFulfillsProject()"
          />
        </div>
      </div>
    </div>

    <div v-if="showGeneralAdvanced" class="mt-4 flex">
      <router-link
        :to="{
          name: 'claim-add-raw',
          query: {
            claim: constructGiveParam(),
          },
        }"
        class="text-blue-500"
      >
        Edit Raw Data
      </router-link>
    </div>

    <p class="text-center text-sm my-4">
      <b class="font-medium">Sign &amp; Send</b> to publish to the world
      <font-awesome
        icon="circle-info"
        class="fa-fw text-blue-500 text-base cursor-pointer"
        @click="explainData()"
      />
    </p>
    <div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
      <button
        class="block w-full text-center text-lg font-bold uppercase 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"
        @click="confirm"
      >
        Sign &amp; Send
      </button>
      <button
        class="block w-full text-center text-md uppercase 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-1.5 py-2 rounded-md"
        @click="cancel"
      >
        Cancel
      </button>
    </div>
  </section>
</template>

<script lang="ts">
import { Component, Vue } from "vue-facing-decorator";
import { RouteLocationNormalizedLoaded, Router } from "vue-router";

import ImageMethodDialog from "../components/ImageMethodDialog.vue";
import QuickNav from "../components/QuickNav.vue";
import TopMessage from "../components/TopMessage.vue";
import AmountInput from "../components/AmountInput.vue";
import { DEFAULT_IMAGE_API_SERVER, NotificationIface } from "../constants/app";
import { GenericCredWrapper, GiveActionClaim } from "../interfaces";
import {
  createAndSubmitGive,
  didInfo,
  editAndSubmitGive,
  getHeaders,
  getPlanFromCache,
  hydrateGive,
} from "../libs/endorserServer";
import * as libsUtil from "../libs/util";
import { retrieveAccountDids } from "../libs/util";
import { logger } from "../utils/logger";
import { Contact } from "@/db/tables/contacts";
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
import { createNotifyHelpers, TIMEOUTS } from "@/utils/notify";
import { showSeedPhraseReminder } from "@/utils/seedPhraseReminder";
import {
  NOTIFY_GIFTED_DETAILS_RETRIEVAL_ERROR,
  NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_CONFIRM,
  NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_ERROR,
  NOTIFY_GIFTED_DETAILS_NO_IDENTIFIER,
  NOTIFY_GIFT_ERROR_NEGATIVE_AMOUNT,
  NOTIFY_GIFTED_DETAILS_RECORDING_GIVE,
  NOTIFY_GIFTED_DETAILS_CREATE_GIVE_ERROR,
  NOTIFY_GIFTED_DETAILS_GIFT_RECORDED,
  NOTIFY_GIFT_ERROR_NO_DESCRIPTION,
} from "@/constants/notifications";

@Component({
  components: {
    ImageMethodDialog,
    QuickNav,
    TopMessage,
    AmountInput,
  },
  mixins: [PlatformServiceMixin],
})
export default class GiftedDetails extends Vue {
  $route!: RouteLocationNormalizedLoaded;
  $router!: Router;
  $notify!: (notification: NotificationIface, timeout?: number) => void;
  notify!: ReturnType<typeof createNotifyHelpers>;

  activeDid = "";
  apiServer = "";

  amountInput = "0";
  description = "";
  destinationPathAfter = "";
  fulfillsProjectId = "";
  fulfillsProjectName = "a project";
  givenToProject = false; // basically static, based on input; if we allow changing then let's fix things (see below)
  givenToRecipient = false; // basically static, based on input; if we allow changing then let's fix things (see below)
  giverDid = "";
  giverName = "";
  hideBackButton = false;
  imageUrl = "";
  message = "";
  offerId = "";
  prevCredToEdit?: GenericCredWrapper<GiveActionClaim>;
  providerProjectId = "";
  providerProjectName = "a project";
  providedByProject = false; // basically static, based on input; if we allow changing then let's fix things (see below)
  providedByGiver = false; // basically static, based on input; if we allow changing then let's fix things (see below)
  recipientDid = "";
  recipientName = "";
  showGeneralAdvanced = false;
  unitCode = "HUR";

  libsUtil = libsUtil;

  created() {
    this.notify = createNotifyHelpers(this.$notify);
  }

  async mounted() {
    try {
      this.prevCredToEdit = (this.$route.query["prevCredToEdit"] as string)
        ? (JSON.parse(
            this.$route.query["prevCredToEdit"] as string,
          ) as GenericCredWrapper<GiveActionClaim>)
        : undefined;
    } catch (error) {
      this.notify.error(
        NOTIFY_GIFTED_DETAILS_RETRIEVAL_ERROR.message,
        TIMEOUTS.LONG,
      );
    }

    const prevAmount = this.prevCredToEdit?.claim?.object?.amountOfThisGood;
    this.amountInput =
      (this.$route.query["amountInput"] as string) ||
      (prevAmount ? String(prevAmount) : "") ||
      this.amountInput;
    this.description =
      (this.$route.query["description"] as string) ||
      this.prevCredToEdit?.claim?.description ||
      this.description;
    this.destinationPathAfter =
      (this.$route.query["destinationPathAfter"] as string) || "";
    this.giverDid = ((this.$route.query["giverDid"] as string) ||
      (this.prevCredToEdit?.claim?.agent as unknown as { identifier: string })
        ?.identifier ||
      this.giverDid) as string;
    this.giverName = (this.$route.query["giverName"] as string) || "";
    this.hideBackButton =
      (this.$route.query["hideBackButton"] as string) === "true";
    this.message = (this.$route.query["message"] as string) || "";

    // find any offer ID
    const fulfills = this.prevCredToEdit?.claim?.fulfills;
    const fulfillsArray = Array.isArray(fulfills)
      ? fulfills
      : fulfills
        ? [fulfills]
        : [];
    const offer = fulfillsArray.find((rec) => rec["@type"] === "Offer");
    this.offerId = ((this.$route.query["offerId"] as string) ||
      offer?.identifier ||
      this.offerId) as string;

    // find any fulfills project ID
    const fulfillsProject = fulfillsArray.find(
      (rec) => rec["@type"] === "PlanAction",
    );
    // eslint-disable-next-line prettier/prettier
    this.fulfillsProjectId =
      ((this.$route.query["fulfillsProjectId"] as string) ||
      fulfillsProject?.identifier ||
      this.fulfillsProjectId) as string;

    // find any provider project ID
    const provider = this.prevCredToEdit?.claim?.provider;
    const providerArray = Array.isArray(provider)
      ? provider
      : provider
        ? [provider]
        : [];
    const providerProject = providerArray.find(
      (rec) => rec["@type"] === "PlanAction",
    );
    this.providerProjectId = ((this.$route.query[
      "providerProjectId"
    ] as string) ||
      providerProject?.identifier ||
      this.providerProjectId) as string;

    this.recipientDid = ((this.$route.query["recipientDid"] as string) ||
      this.prevCredToEdit?.claim?.recipient?.identifier) as string;
    this.recipientName = (this.$route.query["recipientName"] as string) || "";
    this.unitCode = ((this.$route.query["unitCode"] as string) ||
      this.prevCredToEdit?.claim?.object?.unitCode ||
      this.unitCode) as string;

    this.imageUrl = ((this.$route.query["imageUrl"] as string) ||
      this.prevCredToEdit?.claim?.image ||
      localStorage.getItem("imageUrl") ||
      this.imageUrl) as string;

    // this is an endpoint for sharing project info to highlight something given
    // https://developer.mozilla.org/en-US/docs/Web/Manifest/share_target
    if (this.$route.query["shareTitle"] as string) {
      this.description =
        ((this.$route.query["shareTitle"] as string) || "") +
        (this.description ? "\n" + this.description : "");
    }
    if (this.$route.query["shareText"] as string) {
      this.description =
        (this.description ? this.description + "\n" : "") +
        ((this.$route.query["shareText"] as string) || "");
    }
    if (this.$route.query["shareUrl"] as string) {
      this.imageUrl = this.$route.query["shareUrl"] as string;
    }

    const settings = await this.$accountSettings();
    this.apiServer = settings.apiServer || "";

    // Get activeDid from active_identity table (single source of truth)
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const activeIdentity = await (this as any).$getActiveIdentity();
    this.activeDid = activeIdentity.activeDid || "";

    if (
      (this.giverDid && !this.giverName) ||
      (this.recipientDid && !this.recipientName)
    ) {
      const dbContacts = await this.$dbQuery("SELECT * FROM contacts");
      const allContacts = this.$mapQueryResultToValues(
        dbContacts,
      ) as unknown as Contact[];
      const allMyDids = await retrieveAccountDids();
      if (this.giverDid && !this.giverName) {
        this.giverName = didInfo(
          this.giverDid,
          this.activeDid,
          allMyDids,
          allContacts,
        );
      }
      if (this.recipientDid && !this.recipientName) {
        this.recipientName = didInfo(
          this.recipientDid,
          this.activeDid,
          allMyDids,
          allContacts,
        );
      }
    }
    // these should be functions but something's wrong with the syntax in the <> conditional
    this.givenToProject = !!this.fulfillsProjectId;
    this.givenToRecipient = !this.givenToProject && !!this.recipientDid;

    // these should be functions but something's wrong with the syntax in the <> conditional
    this.providedByProject = !!this.providerProjectId;
    this.providedByGiver = !this.providedByProject && !!this.giverDid;

    this.showGeneralAdvanced = !!settings.showGeneralAdvanced;

    if (this.fulfillsProjectId) {
      const fulfillsProject = await getPlanFromCache(
        this.fulfillsProjectId,
        this.axios,
        this.apiServer,
        this.activeDid,
      );
      this.fulfillsProjectName = fulfillsProject?.name
        ? `the project "${fulfillsProject.name}"`
        : "a project";
    }
    if (this.providerProjectId) {
      const providerProject = await getPlanFromCache(
        this.providerProjectId,
        this.axios,
        this.apiServer,
        this.activeDid,
      );
      this.providerProjectName = providerProject?.name
        ? `the project "${providerProject.name}"`
        : "a project";
    }
  }

  changeUnitCode() {
    const units = Object.keys(this.libsUtil.UNIT_SHORT);
    const index = units.indexOf(this.unitCode);
    this.unitCode = units[(index + 1) % units.length];
  }

  increment() {
    this.amountInput = `${(parseFloat(this.amountInput) || 0) + 1}`;
  }

  decrement() {
    this.amountInput = `${Math.max(
      0,
      (parseFloat(this.amountInput) || 1) - 1,
    )}`;
  }

  handleAmountChange(value: number): void {
    this.amountInput = value.toString();
  }

  cancel() {
    this.deleteImage(); // not awaiting, so they'll go back immediately
    if (this.destinationPathAfter) {
      (this.$router as Router).push({ path: this.destinationPathAfter });
    } else {
      (this.$router as Router).back();
    }
  }

  cancelBack() {
    this.deleteImage(); // not awaiting, so they'll go back immediately
    (this.$router as Router).back();
  }

  openImageDialog() {
    (this.$refs.imageDialog as ImageMethodDialog).open((imgUrl) => {
      this.imageUrl = imgUrl;
    }, "GiveAction");
  }

  confirmDeleteImage() {
    this.notify.confirm(
      NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_CONFIRM.message,
      this.deleteImage,
      TIMEOUTS.LONG,
    );
  }

  async deleteImage() {
    if (!this.imageUrl) {
      return;
    }
    try {
      const headers = await getHeaders(this.activeDid);
      if (
        window.location.hostname === "localhost" &&
        !DEFAULT_IMAGE_API_SERVER.includes("localhost")
      ) {
        logger.log(
          "Using shared image API server, so only users on that server can play with images.",
        );
      }
      const response = await this.axios.delete(
        DEFAULT_IMAGE_API_SERVER +
          "/image/" +
          encodeURIComponent(this.imageUrl),
        { headers },
      );
      if (response.status === 204) {
        // don't bother with a notification
        // (either they'll simply continue or they're canceling and going back)
      } else {
        logger.error("Problem deleting image:", response);
        this.notify.error(
          NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_ERROR.message,
          TIMEOUTS.LONG,
        );
        return;
      }

      localStorage.removeItem("imageUrl");
      this.imageUrl = "";
    } catch (error) {
      logger.error("Error deleting image:", error);
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      if ((error as any)?.response?.status === 404) {
        logger.log("Weird: the image was already deleted.", error);

        localStorage.removeItem("imageUrl");
        this.imageUrl = "";

        // it already doesn't exist so we won't say anything to the user
      } else {
        this.notify.error(
          NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_ERROR.message,
          TIMEOUTS.LONG,
        );
      }
    }
  }

  async confirm() {
    if (!this.activeDid) {
      this.notify.error(
        NOTIFY_GIFTED_DETAILS_NO_IDENTIFIER.message,
        TIMEOUTS.SHORT,
      );
      return;
    }
    if (parseFloat(this.amountInput) < 0) {
      this.notify.error(
        NOTIFY_GIFT_ERROR_NEGATIVE_AMOUNT.message,
        TIMEOUTS.SHORT,
      );
      return;
    }
    if (!this.description && !parseFloat(this.amountInput)) {
      this.notify.error(
        NOTIFY_GIFT_ERROR_NO_DESCRIPTION.message.replace(
          "{unit}",
          this.libsUtil.UNIT_SHORT[this.unitCode] || this.unitCode,
        ),
        TIMEOUTS.SHORT,
      );
      return;
    }

    this.notify.toast(
      NOTIFY_GIFTED_DETAILS_RECORDING_GIVE.message,
      undefined,
      TIMEOUTS.BRIEF,
    );

    // this is asynchronous, but we don't need to wait for it to complete
    await this.recordGive();
  }

  notifyUserOfGiver() {
    // there's no individual giver or there's a provider project
    if (!this.giverDid) {
      this.notify.warning(
        "To assign a giver, you must choose a person in a previous step.",
        TIMEOUTS.SHORT,
      );
    } else {
      // must be because providedByProject is true
      this.notify.warning(
        "You cannot assign both a giver and a project.",
        TIMEOUTS.SHORT,
      );
    }
  }

  notifyUserOfRecipient() {
    // there's no individual recipient or there's a fulfills project
    if (!this.recipientDid) {
      this.notify.warning(
        "To assign a recipient, you must choose a person in a previous step.",
        TIMEOUTS.SHORT,
      );
    } else {
      // must be because givenToProject is true
      this.notify.warning(
        "You cannot assign both to a recipient and to a project.",
        TIMEOUTS.SHORT,
      );
    }
  }

  notifyUserOfProvidingProject() {
    // we're here because they clicked and either there is no provider project or there is a giver chosen
    if (!this.providerProjectId) {
      this.notify.warning(
        "To select a project as a provider, you must choose a project in a previous step.",
        TIMEOUTS.SHORT,
      );
    } else {
      // no providing project was chosen, so there must be an individual giver
      this.notify.warning(
        "You cannot select both a giving project and person.",
        TIMEOUTS.SHORT,
      );
    }
  }

  notifyUserFulfillsProject() {
    // we're here because they clicked and either there is no fulfills project or there is a recipient chosen
    if (!this.fulfillsProjectId) {
      this.notify.warning(
        "To assign a project as a recipient, you must choose a project in a previous step.",
        TIMEOUTS.SHORT,
      );
    } else {
      // no fulfills project was chosen, so there must be an individual recipient
      this.notify.warning(
        "You cannot select both a receiving project and person.",
        TIMEOUTS.SHORT,
      );
    }
  }

  /**
   *
   * @param giverDid may be null
   * @param description may be an empty string
   * @param amountInput may be 0
   * @param unitCode may be omitted, defaults to "HUR"
   */
  public async recordGive() {
    try {
      const giverDid = this.providedByGiver ? this.giverDid : undefined;
      const recipientDid = this.givenToRecipient
        ? this.recipientDid
        : undefined;
      const fulfillsProjectId = this.givenToProject
        ? this.fulfillsProjectId
        : undefined;
      let result;
      if (this.prevCredToEdit) {
        // don't create from a blank one in case some properties were set from a different interface
        result = await editAndSubmitGive(
          this.axios,
          this.apiServer,
          this.prevCredToEdit,
          this.activeDid,
          giverDid,
          recipientDid,
          this.description,
          parseFloat(this.amountInput),
          this.unitCode,
          fulfillsProjectId,
          this.offerId,
          false,
          this.imageUrl,
          this.providerProjectId,
        );
      } else {
        result = await createAndSubmitGive(
          this.axios,
          this.apiServer,
          this.activeDid,
          giverDid,
          recipientDid,
          this.description,
          parseFloat(this.amountInput),
          this.unitCode,
          fulfillsProjectId,
          this.offerId,
          false,
          this.imageUrl,
          this.providerProjectId,
        );
      }

      if (!result.success) {
        const errorMessage = result.error;
        logger.error("Error with give creation result:", result);
        this.notify.error(
          errorMessage || NOTIFY_GIFTED_DETAILS_CREATE_GIVE_ERROR.message,
          TIMEOUTS.LONG,
        );
      } else {
        this.notify.success(
          NOTIFY_GIFTED_DETAILS_GIFT_RECORDED.message,
          TIMEOUTS.SHORT,
        );

        // Show seed phrase backup reminder if needed
        try {
          const settings = await this.$accountSettings();
          showSeedPhraseReminder(!!settings.hasBackedUpSeed, this.$notify);
        } catch (error) {
          logger.error("Error checking seed backup status:", error);
        }

        localStorage.removeItem("imageUrl");
        if (this.destinationPathAfter) {
          (this.$router as Router).push({ path: this.destinationPathAfter });
        } else {
          (this.$router as Router).back();
        }
      }
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
    } catch (error: any) {
      logger.error("Error with give recordation caught:", error);
      const errorMessage =
        error.userMessage ||
        error.response?.data?.error?.message ||
        "There was an error recording the give.";
      this.notify.error(errorMessage, TIMEOUTS.LONG);
    }
  }

  constructGiveParam() {
    const giverDid = this.providedByGiver ? this.giverDid : undefined;
    const recipientDid = this.givenToRecipient ? this.recipientDid : undefined;
    const fulfillsProjectId = this.givenToProject
      ? this.fulfillsProjectId
      : undefined;
    const giveClaim = hydrateGive(
      this.prevCredToEdit?.claim as GiveActionClaim,
      giverDid,
      recipientDid,
      this.description,
      parseFloat(this.amountInput),
      this.unitCode,
      fulfillsProjectId,
      this.offerId,
      false,
      this.imageUrl,
      this.providerProjectId,
      this.prevCredToEdit?.id as string,
    );
    const claimStr = JSON.stringify(giveClaim);
    return claimStr;
  }

  // Helper functions for readability

  explainData() {
    this.notify.success(libsUtil.PRIVACY_MESSAGE, TIMEOUTS.LONG);
  }

  // Computed property to get unit options
  get unitOptions() {
    return this.libsUtil.UNIT_SHORT;
  }
}
</script>
