<template>
  <section id="Content">
    <div v-if="claimData">
      <canvas ref="claimCanvas"></canvas>
      <div class="qr-code-container">
        <QRCodeVue
          ref="qrCodeRef"
          :value="qrCodeData"
          :size="200"
          level="H"
          render-as="svg"
          :margin="0"
          :color="{ dark: '#000000', light: '#ffffff' }"
        />
      </div>
    </div>
  </section>
</template>

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

import { NotificationIface } from "../constants/app";
import { db, retrieveSettingsForActiveAccount } from "../db/index";
import * as endorserServer from "../libs/endorserServer";
import { GenericCredWrapper, GenericVerifiableCredential } from "../interfaces";
import { logger } from "../utils/logger";

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

  activeDid = "";
  allMyDids: Array<string> = [];
  apiServer = "";
  claimId = "";
  claimData: GenericCredWrapper<GenericVerifiableCredential> | null = null;

  endorserServer = endorserServer;

  private qrCodeRef: InstanceType<typeof QRCodeVue> | null = null;
  private readonly CANVAS_WIDTH = 1100;
  private readonly CANVAS_HEIGHT = 850;

  async created() {
    const settings = await retrieveSettingsForActiveAccount();
    this.activeDid = settings.activeDid || "";
    this.apiServer = settings.apiServer || "";
    const pathParams = window.location.pathname.substring(
      "/claim-cert/".length,
    );
    this.claimId = pathParams;
    await this.fetchClaim();
  }

  async fetchClaim() {
    try {
      const response = await fetch(
        `${this.apiServer}/api/claim/${this.claimId}`,
      );
      if (response.ok) {
        this.claimData = await response.json();
        await nextTick(); // Wait for the DOM to update
        if (this.claimData) {
          this.drawCanvas(this.claimData);
        }
      } else {
        throw new Error(`Error fetching claim: ${response.statusText}`);
      }
    } catch (error) {
      logger.error("Failed to load claim:", error);
      this.$notify({
        group: "alert",
        type: "danger",
        title: "Error",
        text: "There was a problem loading the claim.",
      });
    }
  }

  async drawCanvas(claimData: GenericCredWrapper<GenericVerifiableCredential>) {
    await db.open();
    const allContacts = await db.contacts.toArray();

    const canvas = this.$refs.claimCanvas as HTMLCanvasElement;
    if (canvas) {
      const ctx = canvas.getContext("2d");
      if (ctx) {
        // Load the background image
        const backgroundImage = new Image();
        backgroundImage.src = "/img/background/cert-frame-2.jpg";
        backgroundImage.onload = async () => {
          // Draw the background image
          ctx.drawImage(
            backgroundImage,
            0,
            0,
            this.CANVAS_WIDTH,
            this.CANVAS_HEIGHT,
          );

          // Set font and styles
          ctx.fillStyle = "black";

          // Draw claim type
          ctx.font = "bold 20px Arial";
          const claimTypeText =
            this.endorserServer.capitalizeAndInsertSpacesBeforeCaps(
              claimData.claimType || "",
            );
          const claimTypeWidth = ctx.measureText(claimTypeText).width;
          ctx.fillText(
            claimTypeText,
            (this.CANVAS_WIDTH - claimTypeWidth) / 2, // Center horizontally
            this.CANVAS_HEIGHT * 0.33,
          );

          if (claimData.claim.agent) {
            const presentedText = "Presented to ";
            ctx.font = "14px Arial";
            const presentedWidth = ctx.measureText(presentedText).width;
            ctx.fillText(
              presentedText,
              (this.CANVAS_WIDTH - presentedWidth) / 2, // Center horizontally
              this.CANVAS_HEIGHT * 0.37,
            );
            const agentText = endorserServer.didInfoForCertificate(
              claimData.claim.agent,
              allContacts,
            );
            ctx.font = "bold 20px Arial";
            const agentWidth = ctx.measureText(agentText).width;
            ctx.fillText(
              agentText,
              (this.CANVAS_WIDTH - agentWidth) / 2, // Center horizontally
              this.CANVAS_HEIGHT * 0.4,
            );
          }

          const descriptionText =
            claimData.claim.name || claimData.claim.description;
          if (descriptionText) {
            const descriptionLine =
              descriptionText.length > 50
                ? descriptionText.substring(0, 75) + "..."
                : descriptionText;
            ctx.font = "14px Arial";
            const descriptionWidth = ctx.measureText(descriptionLine).width;
            ctx.fillText(
              descriptionLine,
              (this.CANVAS_WIDTH - descriptionWidth) / 2,
              this.CANVAS_HEIGHT * 0.45,
            );
          }

          // Draw claim issuer & recipient
          if (claimData.issuer) {
            ctx.font = "14px Arial";
            const issuerText =
              "Issued by " +
              endorserServer.didInfoForCertificate(
                claimData.issuer,
                allContacts,
              );
            ctx.fillText(
              issuerText,
              this.CANVAS_WIDTH * 0.3,
              this.CANVAS_HEIGHT * 0.6,
            );
          }

          // Draw claim ID
          ctx.font = "14px Arial";
          ctx.fillText(
            this.claimId,
            this.CANVAS_WIDTH * 0.3,
            this.CANVAS_HEIGHT * 0.7,
          );
          ctx.fillText(
            "via EndorserSearch.com",
            this.CANVAS_WIDTH * 0.3,
            this.CANVAS_HEIGHT * 0.73,
          );

          // Generate and draw QR code
          await this.generateQRCode();
        };
      }
    }
  }

  private async generateQRCode() {
    if (!this.qrCodeRef) return;

    const canvas = await this.qrCodeRef.toCanvas();
    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    // Draw the QR code on the report canvas
    ctx.drawImage(canvas, this.CANVAS_WIDTH * 0.6, this.CANVAS_HEIGHT * 0.55);
  }
}
</script>

<style scoped>
canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
}

.qr-code-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
