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

    <!-- Details -->
    <div class="bg-slate-100 rounded-md overflow-hidden px-4 py-3 mb-4">
      <div class="block flex gap-4 overflow-hidden">
        <div class="overflow-hidden">
          <div class="flex justify-between">
            <h2 class="text-md font-bold">
              {{ capitalizeAndInsertSpacesBeforeCaps(veriClaim.claimType) }}
              <button
                v-if="
                  ['GiveAction', 'Offer', 'PlanAction'].includes(
                    veriClaim.claimType as string,
                  ) && veriClaim.issuer === activeDid
                  // a PlanAction agent also could edit one of those,
                  // but rather than add more Plan-specific logic to detect the agent
                  // we'll let them click the Project link and edit from there
                "
                @click="onClickEditClaim"
                title="Edit"
                data-testId="editClaimButton"
              >
                <fa icon="pen" class="text-sm text-blue-500 ml-2 mb-1" />
              </button>
            </h2>
            <!--
            <div>
              <router-link
                :to="'/claim-cert/' + encodeURIComponent(veriClaim.id)"
                class="text-blue-500 mt-2"
              >
                <fa icon="square" class="text-white bg-yellow-500 p-1" />
              </router-link>
            </div>
            -->
          </div>
          <div class="text-sm">
            <div data-testId="description">
              <fa icon="message" class="fa-fw text-slate-400" />
              {{
                veriClaim.claim?.itemOffered?.description ||
                veriClaim.claim?.description
              }}
            </div>
            <div>
              <fa icon="user" class="fa-fw text-slate-400" />
              {{ didInfo(veriClaim.issuer) }}
            </div>
            <div>
              <fa icon="calendar" class="fa-fw text-slate-400" />
              {{ veriClaim.issuedAt?.replace(/T/, " ").replace(/Z/, " UTC") }}
            </div>
            <div v-if="veriClaim.claim.image" class="flex justify-center">
              <a :href="veriClaim.claim.image" target="_blank">
                <img :src="veriClaim.claim.image" class="h-24 rounded-xl" />
              </a>
            </div>

            <div v-if="veriClaim.claimType === 'PlanAction'" class="mt-4">
              <router-link
                :to="'/project/' + encodeURIComponent(veriClaim.handleId)"
                class="text-blue-500 mt-2"
              >
                Go to Project page
              </router-link>
            </div>

            <!-- Fullfills Links -->

            <!-- fullfills links for a give -->
            <div v-if="detailsForGive?.fulfillsPlanHandleId" class="mt-4">
              <router-link
                :to="
                  '/project/' +
                  encodeURIComponent(detailsForGive?.fulfillsPlanHandleId)
                "
                class="text-blue-500 mt-2"
              >
                Fulfills a bigger plan...
              </router-link>
            </div>
            <!-- if there's another, it's probably fulfilling an offer, too -->
            <div
              v-if="
                detailsForGive?.fulfillsType &&
                detailsForGive?.fulfillsType !== 'PlanAction' &&
                detailsForGive?.fulfillsHandleId
              "
            >
              <!-- router-link to /claim/ only changes URL path -->
              <a
                @click="
                  showDifferentClaimPage(detailsForGive?.fulfillsHandleId)
                "
                class="text-blue-500 mt-4 cursor-pointer"
              >
                Fulfills
                {{
                  capitalizeAndInsertSpacesBeforeCaps(
                    detailsForGive.fulfillsType,
                  )
                }}...
              </a>
            </div>

            <!-- fullfills links for an offer -->
            <div v-if="detailsForOffer?.fulfillsPlanHandleId">
              <router-link
                :to="
                  '/project/' +
                  encodeURIComponent(detailsForOffer?.fulfillsPlanHandleId)
                "
                class="text-blue-500 mt-4"
              >
                Offered to a bigger plan...
              </router-link>
            </div>

            <!-- Providers -->
            <div v-if="providersForGive?.length > 0" class="mt-4">
              <span>Other assistance provided by:</span>
              <ul class="ml-4">
                <li
                  v-for="provider of providersForGive"
                  :key="provider.identifier"
                  class="list-disc ml-4"
                >
                  <div class="flex gap-4">
                    <div class="grow overflow-hidden">
                      <a
                        @click="
                          provider.identifier.startsWith('did:')
                            ? this.$router.push(
                                '/did/' +
                                  encodeURIComponent(provider.identifier),
                              )
                            : showDifferentClaimPage(provider.identifier)
                        "
                        class="text-blue-500 mt-4 cursor-pointer"
                      >
                        an activity...
                      </a>
                    </div>
                  </div>
                </li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="mt-2">
      <fa icon="comment" class="text-slate-400" />
      {{ issuerName }} posted that.
    </div>
    <!--
    <div>
      <router-link :to="'/claim-cert/' + encodeURIComponent(veriClaim.id)">
        <fa icon="file-contract" class="text-slate-400" />
        <span class="ml-2 text-blue-500">Printable Certificate</span>
      </router-link>
    </div>
    -->

    <div class="mt-8">
      <button
        v-if="libsUtil.canFulfillOffer(veriClaim)"
        @click="openFulfillGiftDialog()"
        class="col-span-1 block w-fit text-center text-md 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-1.5 py-2 rounded-md"
      >
        Affirm Delivery
        <fa icon="hand-holding-heart" class="ml-2 text-white cursor-pointer" />
      </button>
    </div>
    <GiftedDialog ref="customGiveDialog" />

    <div v-if="libsUtil.isGiveAction(veriClaim)">
      <div class="flex columns-3">
        <button
          class="col-span-1 bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white mt-2 px-4 py-2 rounded-md"
          v-if="
            libsUtil.isGiveRecordTheUserCanConfirm(
              isRegistered,
              veriClaim,
              activeDid,
              confirmerIdList,
            )
          "
          @click="confirmConfirmClaim()"
        >
          Confirm
          <fa icon="circle-check" class="ml-2 text-white cursor-pointer" />
        </button>
        <h2 v-else class="font-bold uppercase text-xl mt-2">Confirmations</h2>

        <span class="mt-0.5 px-4 py-2">
          <router-link
            v-if="libsUtil.isGiveAction(veriClaim)"
            :to="'/confirm-gift/' + encodeURIComponent(veriClaim.id)"
            class="col-span-1 text-blue-500"
            data-testId="confirmGiftLink"
          >
            Details...
          </router-link>
        </span>
      </div>

      <div class="mt-2">
        <span v-if="totalConfirmers() === 0">Nobody has confirmed this.</span>
        <span v-else-if="totalConfirmers() === 1">
          One person has confirmed this.
        </span>
        <span v-else>
          {{ totalConfirmers() }} people have confirmed this.
        </span>
      </div>

      <div v-if="totalConfirmers() > 0">
        <div
          v-if="
            confirmerIdList.length === 0 && confsVisibleToIdList.length === 0
          "
        >
          Nobody that you know confirmed this claim, nor do they have any
          confirmers in their network.
        </div>

        <div
          v-if="confirmerIdList.length === 0 && confsVisibleToIdList.length > 0"
        >
          <!-- Only show if this person has links to confirmers (below). -->
          Nobody that you know has issued or confirmed this claim.
        </div>
        <div v-if="confirmerIdList.length > 0">
          The following people have confirmed this claim.
          <ul class="ml-4">
            <li
              v-for="confirmerId in confirmerIdList"
              :key="confirmerId"
              class="list-disc ml-4"
            >
              <div class="flex gap-4">
                <div class="grow overflow-hidden">
                  <div class="text-sm">
                    {{ didInfo(confirmerId) }}
                    <span v-if="!serverUtil.isEmptyOrHiddenDid(confirmerId)">
                      <button
                        @click="
                          copyToClipboard(
                            'The DID of ' + confirmerId,
                            confirmerId,
                          )
                        "
                      >
                        <fa icon="copy" class="text-slate-400 fa-fw" />
                      </button>
                    </span>
                  </div>
                </div>
              </div>
            </li>
          </ul>
        </div>

        <!--
         Never need to show this message:
         "Nobody that you know can see someone who has confirmed this claim."

         If there is nobody in the confirmerIdList then we'll show the combined "nobody" message.
         If there is somebody in the confirmerIdList then that's all they need to show.
         -->

        <!-- Now show anyone linked to confirmers. -->
        <div v-if="confsVisibleToIdList.length > 0">
          The following people can connect you with people who have issued or
          confirmed this claim.
          <ul class="ml-4">
            <li
              v-for="confsVisibleTo in confsVisibleToIdList"
              :key="confsVisibleTo"
              class="list-disc ml-4"
            >
              <div class="flex gap-4">
                <div class="grow overflow-hidden">
                  <div class="text-sm">
                    {{ didInfo(confsVisibleTo) }}
                    <span v-if="!serverUtil.isEmptyOrHiddenDid(confsVisibleTo)">
                      <button
                        @click="
                          copyToClipboard(
                            'The DID of ' + confsVisibleTo,
                            confsVisibleTo,
                          )
                        "
                      >
                        <fa icon="copy" class="text-slate-400 fa-fw" />
                      </button>
                    </span>
                  </div>
                </div>
              </div>
            </li>
          </ul>
        </div>
      </div>

      <!-- explain if user cannot confirm -->
      <!-- Note that these conditions are mirrored in userCanConfirm(). -->
      <div v-if="confirmerIdList.includes(activeDid)">
        You have confirmed this claim.
      </div>
      <div v-else-if="veriClaim.issuer == activeDid">
        You cannot confirm this because you issued this claim, so you already
        count as confirming it.
      </div>
      <div v-else-if="serverUtil.containsHiddenDid(veriClaim.claim)">
        You cannot confirm this because it contains hidden identifiers.
      </div>
    </div>

    <!-- Note that a similar section is found in ConfirmGiftView.vue -->
    <div>
      <h2 class="font-bold uppercase text-xl mt-8 mb-2">Details</h2>
      <div
        v-if="
          serverUtil.containsHiddenDid(veriClaim) &&
          R.isEmpty(veriClaimDidsVisible)
        "
        class="mb-2"
      >
        Some of the details are not visible to you; they show as "HIDDEN". They
        are not visible to any of your direct contacts, either.
        <span v-if="canShare">
          If you'd like to ask any of your contacts to take a look and see if
          their contacts can see more details,
          <a @click="onClickShareClaim()" class="text-blue-500"
            >click to send them this info</a
          >
          and see if they are willing to make an introduction. They are surely
          connected to someone; if you don't know who to ask, you might try the
          person who registered you.
        </span>
        <span v-else>
          If you'd like to ask any of your contacts to take a look and see if
          their contacts can see more details,
          <a
            @click="copyToClipboard('A link to this page', windowLocation)"
            class="text-blue-500"
            >share this page with them</a
          >
          and see if they are willing to make an introduction.
        </span>
      </div>

      <div v-if="!R.isEmpty(veriClaimDidsVisible)">
        Some of the details are not visible to you but they are visible to some
        of your contacts.
        <span v-if="canShare">
          If you'd like an introduction,
          <a @click="onClickShareClaim()" class="text-blue-500"
            >click to share the information with them and ask if they'll tell
            you more about the participants.</a
          >
        </span>
        <span v-else>
          If you'd like an introduction,
          <a
            @click="copyToClipboard('A link to this page', windowLocation)"
            class="text-blue-500"
            >share this page with them and ask if they'll tell you more about
            about the participants.</a
          >
        </span>

        <div
          v-for="(visibleDidPath, index) of Object.keys(veriClaimDidsVisible)"
          :key="index"
          class="list-disc p-4"
        >
          <div class="text-sm">
            <fa icon="minus" class="fa-fw" />
            The {{ visibleDidPath }} is visible to:
          </div>
          <div class="ml-12 p-1">
            <ul>
              <li
                v-for="(visDid, idx2) of veriClaimDidsVisible[visibleDidPath]"
                :key="idx2"
                class="list-disc"
              >
                <div class="text-sm mt-2">
                  <span>
                    {{ didInfo(visDid) }}
                    <span v-if="!serverUtil.isEmptyOrHiddenDid(visDid)">
                      <button
                        @click="copyToClipboard('The DID of ' + visDid, visDid)"
                      >
                        <fa icon="copy" class="text-slate-400 fa-fw" />
                      </button>
                    </span>
                    <span v-if="veriClaim.publicUrls?.[visDid]"
                      >, found at&nbsp;<a
                        :href="veriClaim.publicUrls?.[visDid]"
                        class="text-blue-500"
                      >
                        <fa icon="globe" class="fa-fw text-slate-400" />
                        {{
                          veriClaim.publicUrls[visDid].substring(
                            veriClaim.publicUrls[visDid].indexOf("//") + 2,
                          )
                        }}
                      </a>
                    </span>
                  </span>
                </div>
              </li>
            </ul>
          </div>
        </div>
      </div>
      <span v-if="isEditedGlobalId" class="mt-2">
        This record is an edited version. The latest version is here.
      </span>
      <br />
      <button @click="showVeriClaimDump = !showVeriClaimDump" class="ml-2">
        Details
        <fa v-if="showVeriClaimDump" icon="chevron-up" class="text-blue-400" />
        <fa v-else icon="chevron-down" class="text-blue-400" />
      </button>
      <!-- Keep the dump contents directly between > and < to avoid weird spacing. -->
      <pre
        v-if="showVeriClaimDump"
        class="text-sm overflow-x-scroll bg-slate-100 px-4 py-3 rounded-md"
        >{{ veriClaimDump }}</pre
      >
    </div>

    <h2 class="text-xl mt-8 mb-2">Full Claim</h2>
    <p class="mb-4">
      The full claim includes the claim as it was originally issued, including
      the signature (ie. the proof of issuance by that person).
    </p>
    <div v-if="!fullClaim">
      <p v-if="fullClaimMessage" class="mb-4">
        {{ fullClaimMessage }}
      </p>
      <button
        v-else
        class="block w-full text-center text-md 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-1.5 py-2 rounded-md mb-2"
        @click="showFullClaim(veriClaim.id as string)"
      >
        Load Full Claim Details
      </button>
    </div>
    <div v-else>
      <pre
        class="text-sm overflow-x-scroll bg-slate-100 px-4 py-3 rounded-md"
        >{{ fullClaimDump }}</pre
      >
    </div>

    <a
      :href="apiServer + '/api/claim/' + veriClaim.id"
      target="_blank"
      class="block w-full text-center text-md 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-1.5 py-2 rounded-md mb-2"
    >
      View on the Public Server
    </a>
  </section>
</template>

<script lang="ts">
import { AxiosError } from "axios";
import * as yaml from "js-yaml";
import * as R from "ramda";
import { Component, Vue } from "vue-facing-decorator";
import { Router } from "vue-router";
import { useClipboard } from "@vueuse/core";

import GiftedDialog from "@/components/GiftedDialog.vue";
import QuickNav from "@/components/QuickNav.vue";
import { NotificationIface } from "@/constants/app";
import {
  db,
  logConsoleAndDb,
  retrieveSettingsForActiveAccount,
} from "@/db/index";
import { Contact } from "@/db/tables/contacts";
import * as serverUtil from "@/libs/endorserServer";
import {
  GenericCredWrapper,
  OfferVerifiableCredential,
} from "@/libs/endorserServer";
import * as libsUtil from "@/libs/util";

interface ProviderInfo {
  identifier: string; // could be a DID or a handleId
  linkConfirmed: boolean;
}

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

  activeDid = "";
  allMyDids: Array<string> = [];
  allContacts: Array<Contact> = [];
  apiServer = "";

  canShare = false;
  confirmerIdList: string[] = []; // list of DIDs that have confirmed this claim excluding the issuer
  confsVisibleErrorMessage = "";
  confsVisibleToIdList: string[] = []; // list of DIDs that can see any confirmer
  detailsForGive = null;
  detailsForOffer = null;
  fullClaim = null;
  fullClaimDump = "";
  fullClaimMessage = "";
  isEditedGlobalId = false;
  isRegistered = false;
  issuerName = "";
  numConfsNotVisible = 0; // number of hidden DIDs in the confirmerIdList, minus the issuer if they aren't visible
  providersForGive: ProviderInfo[] = [];
  showIdCopy = false;
  showVeriClaimDump = false;
  veriClaim = serverUtil.BLANK_GENERIC_SERVER_RECORD;
  veriClaimDump = "";
  veriClaimDidsVisible = {};
  windowLocation = window.location.href;

  R = R;
  yaml = yaml;
  libsUtil = libsUtil;
  serverUtil = serverUtil;

  resetThisValues() {
    this.confirmerIdList = [];
    this.confsVisibleErrorMessage = "";
    this.confsVisibleToIdList = [];
    this.detailsForGive = null;
    this.detailsForOffer = null;
    this.fullClaim = null;
    this.fullClaimDump = "";
    this.fullClaimMessage = "";
    this.isEditedGlobalId = false;
    this.numConfsNotVisible = 0;
    this.providersForGive = [];
    this.veriClaim = serverUtil.BLANK_GENERIC_SERVER_RECORD;
    this.veriClaimDump = "";
    this.veriClaimDidsVisible = {};
  }

  async created() {
    const settings = await retrieveSettingsForActiveAccount();
    this.activeDid = settings.activeDid || "";
    this.apiServer = settings.apiServer || "";
    this.allContacts = await db.contacts.toArray();
    this.isRegistered = settings.isRegistered || false;

    try {
      this.allMyDids = await libsUtil.retrieveAccountDids();
    } catch (error) {
      // continue because we want to see claims, even anonymously
      logConsoleAndDb(
        "Error retrieving all account DIDs on home page:" + error,
        true,
      );
      this.$notify(
        {
          group: "alert",
          type: "danger",
          title: "Error Loading Profile",
          text: "See the Help page for problems with your personal data.",
        },
        -1,
      );
    }

    const pathParam = window.location.pathname.substring("/claim/".length);
    let claimId;
    if (pathParam) {
      claimId = decodeURIComponent(pathParam);
      await this.loadClaim(claimId, this.activeDid);
    } else {
      this.$notify(
        {
          group: "alert",
          type: "danger",
          title: "Error",
          text: "No claim ID was provided.",
        },
        -1,
      );
    }

    // When Chrome compatibility is fixed https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API#api.navigator.canshare
    // then use this truer check: navigator.canShare && navigator.canShare()
    this.canShare = !!navigator.share;
  }

  // insert a space before any capital letters except the initial letter
  // (and capitalize initial letter, just in case)
  capitalizeAndInsertSpacesBeforeCaps(text: string) {
    return !text
      ? ""
      : text[0].toUpperCase() + text.substr(1).replace(/([A-Z])/g, " $1");
  }

  totalConfirmers() {
    return (
      this.numConfsNotVisible +
      this.confirmerIdList.length +
      this.confsVisibleToIdList.length
    );
  }

  // Isn't there a better way to make this available to the template?
  didInfo(did: string) {
    return serverUtil.didInfo(
      did,
      this.activeDid,
      this.allMyDids,
      this.allContacts,
    );
  }

  async loadClaim(claimId: string, userDid: string) {
    const urlPath = libsUtil.isGlobalUri(claimId)
      ? "/api/claim/byHandle/"
      : "/api/claim/";
    const url = this.apiServer + urlPath + encodeURIComponent(claimId);
    const headers = await serverUtil.getHeaders(userDid);

    try {
      const resp = await this.axios.get(url, { headers });
      if (resp.status === 200) {
        this.veriClaim = resp.data;
        this.issuerName = this.didInfo(this.veriClaim.issuer);
        this.veriClaimDump = yaml.dump(this.veriClaim);
        this.veriClaimDidsVisible = libsUtil.findAllVisibleToDids(
          this.veriClaim,
          true,
        );
      } else {
        // actually, axios typically throws an error so we never get here
        console.error("Error getting claim:", resp);
        this.$notify(
          {
            group: "alert",
            type: "danger",
            title: "Error",
            text: "There was a problem retrieving that claim.",
          },
          -1,
        );
        return;
      }

      this.isEditedGlobalId = !this.veriClaim.handleId.endsWith(claimId);

      // retrieve more details on Give, Offer, or Plan
      if (this.veriClaim.claimType === "GiveAction") {
        const giveUrl =
          this.apiServer +
          "/api/v2/report/gives?handleId=" +
          encodeURIComponent(this.veriClaim.handleId as string);
        const giveHeaders = await serverUtil.getHeaders(userDid);
        const giveResp = await this.axios.get(giveUrl, {
          headers: giveHeaders,
        });
        if (giveResp.status === 200 && giveResp.data.data?.length > 0) {
          this.detailsForGive = giveResp.data.data[0];
        } else {
          console.error("Error getting detailed give info:", giveResp);
        }

        // look for providers
        const providerUrl =
          this.apiServer +
          "/api/v2/report/providersToGive?handleId=" +
          encodeURIComponent(this.veriClaim.handleId as string);
        const providerHeaders = await serverUtil.getHeaders(userDid);
        const providerResp = await this.axios.get(providerUrl, {
          headers: providerHeaders,
        });
        // should be at least an empty array
        if (
          providerResp.status === 200 &&
          Array.isArray(providerResp.data.data)
        ) {
          this.providersForGive = providerResp.data.data;
        } else {
          console.error("Error getting give providers:", giveResp);
          this.$notify(
            {
              group: "alert",
              type: "warning",
              title: "Error",
              text: "Got error retrieving linked provider data.",
            },
            -1,
          );
        }
      } else if (this.veriClaim.claimType === "Offer") {
        const offerUrl =
          this.apiServer +
          "/api/v2/report/offers?handleId=" +
          encodeURIComponent(this.veriClaim.handleId as string);
        const offerHeaders = await serverUtil.getHeaders(userDid);
        const offerResp = await this.axios.get(offerUrl, {
          headers: offerHeaders,
        });
        if (offerResp.status === 200) {
          this.detailsForOffer = offerResp.data.data[0];
        } else {
          console.error("Error getting detailed offer info:", offerResp);
          this.$notify(
            {
              group: "alert",
              type: "warning",
              title: "Error",
              text: "Got error retrieving linked offer data.",
            },
            -1,
          );
        }
      }

      // retrieve the list of confirmers
      const confirmerInfo = await libsUtil.retrieveConfirmerIdList(
        this.apiServer,
        claimId,
        this.veriClaim.issuer,
        userDid,
      );
      if (confirmerInfo) {
        this.confirmerIdList = confirmerInfo.confirmerIdList;
        this.confsVisibleToIdList = confirmerInfo.confsVisibleToIdList;
        this.numConfsNotVisible = confirmerInfo.numConfsNotVisible;
      } else {
        this.confsVisibleErrorMessage =
          "Had problems retrieving confirmations.";
      }
    } catch (error: unknown) {
      const serverError = error as AxiosError;
      console.error("Error retrieving claim:", serverError);
      this.$notify(
        {
          group: "alert",
          type: "danger",
          title: "Error",
          text: "Something went wrong retrieving claim data.",
        },
        3000,
      );
    }
  }

  async showFullClaim(claimId: string) {
    const url =
      this.apiServer + "/api/claim/full/" + encodeURIComponent(claimId);
    const headers = await serverUtil.getHeaders(this.activeDid);

    try {
      const resp = await this.axios.get(url, { headers });
      if (resp.status === 200) {
        this.fullClaim = resp.data;
        this.fullClaimDump = yaml.dump(this.fullClaim);
      } else {
        // actually, axios typically throws an error so we never get here
        console.error("Error getting full claim:", resp);
        this.$notify(
          {
            group: "alert",
            type: "danger",
            title: "Error",
            text: "There was a problem getting that claim.",
          },
          -1,
        );
      }
    } catch (error: unknown) {
      console.error("Error retrieving full claim:", error);
      const serverError = error as AxiosError;
      if (serverError.response?.status === 403) {
        let issuerPhrase = "";
        const issuerContact = serverUtil.contactForDid(
          this.veriClaim.issuer,
          this.allContacts,
        );
        if (issuerContact?.name) {
          issuerPhrase +=
            "Ask " +
            issuerContact.name +
            " to show you the full claim details.";
        }
        if (
          this.confirmerIdList.length > 0 ||
          this.confsVisibleToIdList.length > 0
        ) {
          if (issuerContact?.name) {
            issuerPhrase +=
              "You could also ask someone in the Confirmations section to make an introduction.";
          } else {
            issuerPhrase +=
              "Ask someone in the Confirmations section to make an introduction.";
          }
        }
        this.fullClaimMessage =
          "You are not authorized to view the full contents of this claim." +
          issuerPhrase +
          " You might ask someone in your network -- like the person who registered you --" +
          " if they can find out more and make an introduction: " +
          " send them this page and see if they can make a connection for you.";
      } else {
        this.$notify(
          {
            group: "alert",
            type: "danger",
            title: "Error",
            text: "Something went wrong retrieving that claim.",
          },
          -1,
        );
      }
    }
  }

  confirmConfirmClaim() {
    this.$notify(
      {
        group: "modal",
        type: "confirm",
        title: "Confirm",
        text: "Do you personally confirm that this is true?",
        onYes: async () => {
          await this.confirmClaim();
        },
      },
      -1,
    );
  }

  // similar code is found in ProjectViewView
  async confirmClaim() {
    // similar logic is found in endorser-mobile
    const goodClaim = serverUtil.removeSchemaContext(
      serverUtil.removeVisibleToDids(
        serverUtil.addLastClaimOrHandleAsIdIfMissing(
          this.veriClaim.claim,
          this.veriClaim.id,
          this.veriClaim.handleId,
        ),
      ),
    );
    const confirmationClaim: serverUtil.GenericVerifiableCredential = {
      "@context": "https://schema.org",
      "@type": "AgreeAction",
      object: goodClaim,
    };
    const result = await serverUtil.createAndSubmitClaim(
      confirmationClaim,
      this.activeDid,
      this.apiServer,
      this.axios,
    );
    if (result.type === "success") {
      this.$notify(
        {
          group: "alert",
          type: "success",
          title: "Success",
          text: "Confirmation submitted.",
        },
        5000,
      );
    } else {
      console.error("Got error submitting the confirmation:", result);
      this.$notify(
        {
          group: "alert",
          type: "danger",
          title: "Error",
          text: "There was a problem submitting the confirmation.",
        },
        -1,
      );
    }
  }

  showDifferentClaimPage(claimId: string) {
    const route = {
      path: "/claim/" + encodeURIComponent(claimId),
    };
    (this.$router as Router).push(route).then(async () => {
      this.resetThisValues();
      await this.loadClaim(claimId, this.activeDid);
    });
  }

  openFulfillGiftDialog() {
    const giver: libsUtil.GiverReceiverInputInfo = {
      did: libsUtil.offerGiverDid(
        this.veriClaim as GenericCredWrapper<OfferVerifiableCredential>,
      ),
    };
    (this.$refs.customGiveDialog as GiftedDialog).open(
      giver,
      undefined,
      this.veriClaim.handleId,
      "Offer fulfilled by " + (giver?.name || "someone not named"),
    );
  }

  copyToClipboard(name: string, text: string) {
    useClipboard()
      .copy(text)
      .then(() => {
        this.$notify(
          {
            group: "alert",
            type: "toast",
            title: "Copied",
            text: (name || "That") + " was copied to the clipboard.",
          },
          2000,
        );
      });
  }

  onClickShareClaim() {
    window.navigator.share({
      title: "Help Connect Me",
      text: "I'm trying to find the full details of this claim. Can you help me?",
      url: this.windowLocation,
    });
  }

  onClickEditClaim() {
    if (this.veriClaim.claimType === "GiveAction") {
      const route = {
        name: "gifted-details",
        query: {
          prevCredToEdit: JSON.stringify(this.veriClaim),
          destinationPathAfter:
            "/claim/" + encodeURIComponent(this.veriClaim.handleId),
        },
      };
      (this.$router as Router).push(route);
    } else if (this.veriClaim.claimType === "Offer") {
      const route = {
        name: "offer-details",
        query: {
          prevCredToEdit: JSON.stringify(this.veriClaim),
          destinationPathAfter:
            "/claim/" + encodeURIComponent(this.veriClaim.handleId),
        },
      };
      (this.$router as Router).push(route);
    } else if (this.veriClaim.claimType === "PlanAction") {
      const route = {
        name: "new-edit-project",
        query: { projectId: this.veriClaim.handleId },
      };
      (this.$router as Router).push(route);
    } else {
      console.error(
        "Unrecognized claim type for edit:",
        this.veriClaim.claimType,
      );
      this.$notify(
        {
          group: "alert",
          type: "danger",
          title: "Error",
          text: "This is an unrecognized claim type.",
        },
        3000,
      );
    }
  }
}
</script>
