<template>
  <section id="Content">
    <div v-if="claimData">
      <canvas ref="claimCanvas"></canvas>
    </div>
  </section>
</template>

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

import { APP_SERVER, NotificationIface, USE_DEXIE_DB } from "../constants/app";
import { db, retrieveSettingsForActiveAccount } from "../db/index";
import * as databaseUtil from "../db/databaseUtil";
import * as endorserServer from "../libs/endorserServer";
import { logger } from "../utils/logger";
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
import { Contact } from "@/db/tables/contacts";
@Component
export default class ClaimReportCertificateView extends Vue {
  $notify!: (notification: NotificationIface, timeout?: number) => void;

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

  endorserServer = endorserServer;

  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: endorserServer.GenericCredWrapper<endorserServer.GenericVerifiableCredential>,
  ) {
    const platformService = PlatformServiceFactory.getInstance();
    const dbAllContacts = await platformService.dbQuery(
      "SELECT * FROM contacts",
    );
    let allContacts = databaseUtil.mapQueryResultToValues(
      dbAllContacts,
    ) as unknown as Contact[];
    if (USE_DEXIE_DB) {
      await db.open();
      allContacts = await db.contacts.toArray();
    }

    const canvas = this.$refs.claimCanvas as HTMLCanvasElement;
    if (canvas) {
      const CANVAS_WIDTH = 1100;
      const CANVAS_HEIGHT = 850;

      // size to approximate portrait of 8.5"x11"
      canvas.width = CANVAS_WIDTH;
      canvas.height = CANVAS_HEIGHT;
      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, CANVAS_WIDTH, 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,
            (CANVAS_WIDTH - claimTypeWidth) / 2, // Center horizontally
            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,
              (CANVAS_WIDTH - presentedWidth) / 2, // Center horizontally
              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,
              (CANVAS_WIDTH - agentWidth) / 2, // Center horizontally
              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,
              (CANVAS_WIDTH - descriptionWidth) / 2,
              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, CANVAS_WIDTH * 0.3, CANVAS_HEIGHT * 0.6);
          }

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

          // Generate and draw QR code
          const qrCodeCanvas = document.createElement("canvas");
          await QRCode.toCanvas(
            qrCodeCanvas,
            APP_SERVER + "/claim/" + this.claimId,
            {
              width: 150,
              color: { light: "#0000" /* Transparent background */ },
            },
          );
          ctx.drawImage(qrCodeCanvas, CANVAS_WIDTH * 0.6, CANVAS_HEIGHT * 0.55);
        };
      }
    }
  }
}
</script>

<style scoped>
canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
</style>
