<template>
  <QuickNav />
  <!-- CONTENT -->
  <section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
    <!-- Heading -->
    <h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-8">
      Image
    </h1>
    <div v-if="imageBlob">
      <div v-if="uploading">
        <fa icon="spinner" class="fa-spin-pulse" />
      </div>
      <div v-else>
        Choose the purpose of this image:
        <br />
        <button @click="recordGift">Record a Gift</button>
        <br />
        <button @click="recordProfile">Save as Profile Image</button>
        <br />
        <button @click="cancel">Cancel</button>
      </div>

      <img
        :src="URL.createObjectURL(imageBlob)"
        alt="Shared Image"
        class="rounded"
      />
    </div>
    <div v-else>
      <p>No image found.</p>
    </div>
  </section>
</template>

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

import QuickNav from "@/components/QuickNav.vue";
import {
  DEFAULT_IMAGE_API_SERVER,
  IMAGE_TYPE_PROFILE,
  NotificationIface,
} from "@/constants/app";
import { db } from "@/db/index";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { getIdentity } from "@/libs/util";
import { accessToken } from "@/libs/crypto";
import axios from "axios";

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

  activeDid: string | undefined = undefined;
  imageBlob: Blob | undefined = undefined;
  imageFileName: string | undefined = undefined;
  uploading = false;

  URL = window.URL || window.webkitURL;

  // 'created' hook runs when the Vue instance is first created
  async mounted() {
    try {
      await db.open();
      const settings = await db.settings.get(MASTER_SETTINGS_KEY);
      this.activeDid = settings?.activeDid as string;

      const temp = await db.temp.get("shared-photo");
      if (temp) {
        this.imageBlob = temp.blob;

        // clear the temp image
        db.temp.delete("shared-photo");

        this.imageFileName = this.$route.query.fileName as string;
      }
    } catch (err: unknown) {
      console.error("Got an error loading an identifier:", err);
      this.$notify(
        {
          group: "alert",
          type: "danger",
          title: "Error",
          text: "Got an error loading this data.",
        },
        -1,
      );
    }
  }

  async recordGift() {
    await this.sendToImageServer("GiveAction").then((url) => {
      if (url) {
        this.$router.push({
          name: "gifted-details",
          query: { imageUrl: url },
        });
      }
    });
  }

  async recordProfile() {
    await this.sendToImageServer(IMAGE_TYPE_PROFILE).then((url) => {
      if (url) {
        db.settings.update(MASTER_SETTINGS_KEY, {
          profileImageUrl: url,
        });
        this.$router.push({ name: "account" });
      }
    });
  }

  async cancel() {
    this.imageBlob = undefined;
    this.imageFileName = undefined;
    this.$router.push({ name: "home" });
  }

  async sendToImageServer(imageType: string) {
    this.uploading = true;

    let result;
    try {
      // send the image to the server
      const identifier = await getIdentity(this.activeDid as string);
      const token = await accessToken(identifier);
      const headers = {
        Authorization: "Bearer " + token,
      };
      const formData = new FormData();
      formData.append(
        "image",
        this.imageBlob as Blob,
        this.imageFileName as string,
      );
      formData.append("claimType", imageType);

      const response = await axios.post(
        DEFAULT_IMAGE_API_SERVER + "/image",
        formData,
        { headers },
      );
      this.imageBlob = undefined;
      this.imageFileName = undefined;

      this.uploading = false;
      result = response.data.url as string;
    } catch (error) {
      console.error("Error uploading the image", error);
      this.$notify(
        {
          group: "alert",
          type: "danger",
          title: "Error",
          text: "There was an error saving the picture. Please try again.",
        },
        5000,
      );
      this.uploading = false;
    }
    return result;
  }
}
</script>
