<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" class="text-center mb-4">
        <fa icon="spinner" class="fa-spin-pulse" />
      </div>
      <div v-else>
        <div class="text-center mb-4">Choose how to use this image</div>
        <div class="grid grid-cols-1 sm:grid-cols-3 gap-4">
          <button
            @click="recordGift"
            class="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"
          >
            <fa icon="gift" class="fa-fw" />
            Record a Gift
          </button>
          <button
            @click="recordProfile"
            class="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"
          >
            <fa icon="circle-user" class="fa-fw" />
            Save as Profile Image
          </button>
          <button
            @click="cancel"
            class="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"
          >
            <fa icon="ban" class="fa-fw" />
            Cancel
          </button>
        </div>
        <PhotoDialog ref="photoDialog" />
      </div>

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

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

import PhotoDialog from "@/components/PhotoDialog.vue";
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 { accessToken } from "@/libs/crypto";
import { base64ToBlob, SHARED_PHOTO_BASE64_KEY } from "@/libs/util";

@Component({ components: { PhotoDialog, 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_BASE64_KEY);
      const imageB64 = temp?.blobB64 as string;
      if (temp) {
        this.imageBlob = base64ToBlob(imageB64);

        // clear the temp image
        db.temp.delete(SHARED_PHOTO_BASE64_KEY);

        this.imageFileName = (this.$route as Router).query[
          "fileName"
        ] as string;
      } else {
        console.error("No appropriate image found in temp storage.", temp);
      }
    } 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) {
        const route = {
          name: "gifted-details",
          // this might be wrong since "name" goes with params, but it works so test well when you change it
          query: {
            destinationPathAfter: "/home",
            hideBackButton: true,
            imageUrl: url,
            recipientDid: this.activeDid,
          },
        } as RouteLocationRaw;
        (this.$router as Router).push(route);
      }
    });
  }

  recordProfile() {
    (this.$refs.photoDialog as PhotoDialog).open(
      async (imgUrl) => {
        await db.settings.update(MASTER_SETTINGS_KEY, {
          profileImageUrl: imgUrl,
        });
        (this.$router as Router).push({ name: "account" });
      },
      IMAGE_TYPE_PROFILE,
      true,
      this.imageBlob,
      this.imageFileName,
    );
  }

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

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

    let result;
    try {
      // send the image to the server
      const token = await accessToken(this.activeDid);
      const headers = {
        Authorization: "Bearer " + token,
        // axios fills in Content-Type of multipart/form-data
      };
      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 },
      );
      if (response?.data?.url) {
        this.imageBlob = undefined;
        this.imageFileName = undefined;
        result = response.data.url as string;
      } else {
        console.error("Problem uploading the image", response.data);
        this.$notify(
          {
            group: "alert",
            type: "danger",
            title: "Error",
            text:
              "There was a problem saving the picture. " +
              (response?.data?.message || ""),
          },
          5000,
        );
      }

      this.uploading = false;
    } 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.",
        },
        5000,
      );
      this.uploading = false;
    }
    return result;
  }
}
</script>
