<template>
  <!-- QUICK NAV -->
  <nav id="QuickNav" class="fixed bottom-0 left-0 right-0 bg-slate-200 z-50">
    <ul class="flex text-2xl p-2 gap-2">
      <!-- Home Feed -->
      <li class="basis-1/5 rounded-md text-slate-500">
        <router-link :to="{ name: 'home' }" class="block text-center py-3 px-1"
          ><fa icon="house-chimney" class="fa-fw"></fa
        ></router-link>
      </li>
      <!-- Search -->
      <li class="basis-1/5 rounded-md text-slate-500">
        <router-link
          :to="{ name: 'discover' }"
          class="block text-center py-3 px-1"
          ><fa icon="magnifying-glass" class="fa-fw"></fa
        ></router-link>
      </li>
      <!-- Projects -->
      <li class="basis-1/5 rounded-md bg-slate-400 text-white">
        <router-link
          :to="{ name: 'projects' }"
          class="block text-center py-3 px-1"
          ><fa icon="folder-open" class="fa-fw"></fa
        ></router-link>
      </li>
      <!-- Contacts -->
      <li class="basis-1/5 rounded-md text-slate-500">
        <router-link
          :to="{ name: 'contacts' }"
          class="block text-center py-3 px-1"
          ><fa icon="hand" class="fa-fw"></fa
        ></router-link>
      </li>
      <!-- Profile -->
      <li class="basis-1/5 rounded-md text-slate-500">
        <router-link
          :to="{ name: 'account' }"
          class="block text-center py-3 px-1"
          ><fa icon="circle-user" class="fa-fw"></fa
        ></router-link>
      </li>
    </ul>
  </nav>

  <!-- CONTENT -->
  <section id="Content" class="p-6 pb-24">
    <!-- 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"></fa>
        </button>
        <!-- Context Menu -->
        <a
          href=""
          class="text-lg text-center px-2 py-1 absolute -right-2 -top-1"
          ><fa icon="ellipsis-vertical" class="fa-fw"></fa
        ></a>

        View Plan
      </h1>
    </div>

    <div>
      {{ errorMessage }}
    </div>

    <!-- Project Details -->
    <div class="bg-slate-100 rounded-md overflow-hidden px-4 py-3 mb-4">
      <div>
        <h2 class="text-xl font-semibold">{{ name }}</h2>
        <div class="flex justify-between gap-4 text-sm mb-3">
          <span><fa icon="user" class="fa-fw text-slate-400"></fa> Rotary</span>
          <span
            ><fa icon="calendar" class="fa-fw text-slate-400"></fa
            >{{ timeSince }}
          </span>
        </div>

        <div class="text-sm text-slate-500">
          <div v-if="!expanded">
            {{ truncatedDesc }}
            <a v-if="description.length >= truncateLength" @click="expandText"
              >Read More</a
            >
          </div>
          <div v-else>
            {{ description }}
            <a
              @click="collapseText"
              class="uppercase text-xs font-semibold text-slate-700"
              >Read Less</a
            >
          </div>
        </div>
      </div>
      <button
        type="button"
        class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md"
        @click="onEditClick()"
      >
        Edit
      </button>
    </div>

    <button
      @click="openDialog({ name: 'you', did: activeDid })"
      class="block text-center text-lg font-bold uppercase bg-blue-600 text-white px-2 py-3 rounded-md mb-8"
    >
      I gave...
    </button>

    <div>
      <p>... or choose a contact who gave:</p>
      <!-- similar contact selection code is in multiple places -->
      <div class="px-4">
        <button
          v-for="contact in allContacts"
          :key="contact.did"
          @click="openDialog(contact)"
          class="text-blue-500"
        >
          &nbsp;{{ contact.name }},
        </button>
        <span v-if="allContacts.length > 0">&nbsp;or&nbsp;</span>
        <button @click="openDialog()" class="text-blue-500">
          someone not specified
        </button>
      </div>
    </div>

    <GiftedDialog
      ref="customDialog"
      @dialog-result="handleDialogResult"
      message="Received from"
    >
    </GiftedDialog>

    <!-- Commit -->
    <!--
    <router-link
      :to="{ name: 'new-edit-commitment' }"
      class="block text-center text-lg font-bold uppercase bg-blue-600 text-white px-2 py-3 rounded-md mb-8"
      >Make Commitment</router-link
    >
    -->

    <!-- Commitments -->
    <!--
    <div class="bg-slate-100 px-4 py-3 rounded-md">
      <h3 class="text-sm uppercase font-semibold mb-3">Commitments</h3>

      <ul class="text-sm border-t border-slate-300">
        <li class="flex justify-between gap-4 py-1.5 border-b border-slate-300">
          <span>[Username]</span>
          <span
            >5 hours <fa icon="spinner" class="fa-fw text-slate-400"></fa
          ></span>
        </li>

        <li class="flex justify-between gap-4 py-1.5 border-b border-slate-300">
          <span>[Username]</span>
          <span
            >US$ 20.00 <fa icon="circle-check" class="fa-fw text-lime-500"></fa
          ></span>
        </li>

        <li class="flex justify-between gap-4 py-1.5 border-b border-slate-300">
          <span>[Username]</span>
          <span
            >0.1 BTC <fa icon="spinner" class="fa-fw text-slate-400"></fa
          ></span>
        </li>
      </ul>
    </div>
    -->
  </section>
</template>

<script lang="ts">
import { AxiosError } from "axios";
import * as moment from "moment";
import * as R from "ramda";
import { Options, Vue } from "vue-class-component";

import GiftedDialog from "@/components/GiftedDialog.vue";
import { accountsDB, db } from "@/db";
import { Contact } from "@/db/tables/contacts";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { createAndSubmitGive } from "@/libs/endorserServer";
import { accessToken } from "@/libs/crypto";
import { IIdentifier } from "@veramo/core";

@Options({
  components: { GiftedDialog },
})
export default class ProjectViewView extends Vue {
  activeDid = "";
  allContacts: Array<Contact> = [];
  apiServer = "";
  expanded = false;
  name = "";
  description = "";
  truncatedDesc = "";
  truncateLength = 40;
  timeSince = "";
  projectId = localStorage.getItem("projectId") || ""; // handle ID
  errorMessage = "";

  onEditClick() {
    localStorage.setItem("projectId", this.projectId as string);
    const route = {
      name: "new-edit-project",
    };
    this.$router.push(route);
  }

  expandText() {
    this.expanded = true;
  }

  collapseText() {
    this.expanded = false;
  }

  async LoadProject(identity: IIdentifier) {
    const url =
      this.apiServer +
      "/api/claim/byHandle/" +
      encodeURIComponent(this.projectId);
    const token = await accessToken(identity);
    const headers = {
      "Content-Type": "application/json",
      Authorization: "Bearer " + token,
    };

    try {
      const resp = await this.axios.get(url, { headers });
      if (resp.status === 200) {
        const startTime = resp.data.startTime;
        if (startTime != null) {
          const eventDate = new Date(startTime);
          const now = moment.now();
          this.timeSince = moment.utc(now).to(eventDate);
        }
        this.name = resp.data.claim?.name || "(no name)";
        this.description = resp.data.claim?.description || "(no description)";
        this.truncatedDesc = this.description.slice(0, this.truncateLength);
      } else if (resp.status === 404) {
        // actually, axios throws an error so we never get here
        this.errorMessage = "That project does not exist.";
      }
    } catch (error: unknown) {
      const serverError = error as AxiosError;
      if (serverError.response?.status === 404) {
        this.errorMessage = "That project does not exist.";
      } else {
        this.errorMessage =
          "Something went wrong retrieving that project." +
          " See logs for more info.";
        console.error("Error retrieving project:", error);
      }
    }
  }

  // 'created' hook runs when the Vue instance is first created
  async created() {
    await db.open();
    const settings = await db.settings.get(MASTER_SETTINGS_KEY);
    this.activeDid = settings?.activeDid || "";
    this.apiServer = settings?.apiServer || "";
    this.allContacts = await db.contacts.toArray();

    await accountsDB.open();
    const num_accounts = await accountsDB.accounts.count();
    if (num_accounts === 0) {
      console.error("Problem!  Should have a profile!");
    } else {
      const accounts = await accountsDB.accounts.toArray();
      const account = R.find((acc) => acc.did === this.activeDid, accounts);
      const identity = JSON.parse(account?.identity || "null");
      if (!identity) {
        throw new Error("No identity found.");
      }
      this.LoadProject(identity);
    }
  }

  openDialog(contact) {
    this.$refs.customDialog.open(contact);
  }
  handleDialogResult(result) {
    if (result.action === "confirm") {
      return new Promise((resolve) => {
        this.recordGive(result.contact?.did, result.description, result.hours);
        resolve();
      });
    } else {
      // action was not "confirm" so do nothing
    }
  }

  /**
   *
   * @param giverDid may be null
   * @param description may be an empty string
   * @param hours may be 0
   */
  async recordGive(giverDid, description, hours) {
    if (this.activeDid == null) {
      this.alertTitle = "Error";
      this.alertMessage =
        "You must select an identity before you can record a give.";
      return;
    }
    const accounts = await accountsDB.accounts.toArray();
    const account = R.find((acc) => acc.did === this.activeDid, accounts);
    const identity = JSON.parse(account?.identity || "null");
    if (!identity) {
      throw new Error("No identity found.");
    }
    createAndSubmitGive(
      this.axios,
      this.apiServer,
      identity,
      giverDid,
      this.activeDid,
      description,
      hours,
      this.projectId
    )
      .then((result) => {
        if (result.status != 201 || result.data?.error) {
          console.log("Error with give result:", result);
          this.alertTitle = "Error";
          this.alertMessage =
            result.data?.message || "There was an error recording the give.";
        } else {
          this.alertTitle = "Success";
          this.alertMessage = "That gift was recorded.";
          //this.updateAllFeed(); // full update is overkill but we should show something
        }
      })
      .catch((e) => {
        console.log("Error with give caught:", e);
        this.alertTitle = "Error";
        this.alertMessage =
          e.userMessage || "There was an error recording the give.";
      });
  }

  // This same popup code is in many files.
  alertMessage = "";
  alertTitle = "";
  public onClickClose() {
    this.alertTitle = "";
    this.alertMessage = "";
  }
  public computedAlertClassNames() {
    return {
      hidden: !this.alertMessage,
      "dismissable-alert": true,
      "bg-slate-100": true,
      "p-5": true,
      rounded: true,
      "drop-shadow-lg": true,
      fixed: true,
      "top-3": true,
      "inset-x-3": true,
      "transition-transform": true,
      "ease-in": true,
      "duration-300": true,
    };
  }
}
</script>
