<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 } from "../constants/app";
import * as endorserServer from "../libs/endorserServer";
import {
  GenericCredWrapper,
  GenericVerifiableCredential,
} from "../interfaces/common";
import { logger } from "../utils/logger";
import { Contact } from "@/db/tables/contacts";
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
import { createNotifyHelpers, TIMEOUTS } from "@/utils/notify";
import { NOTIFY_ERROR_LOADING_CLAIM } from "@/constants/notifications";
@Component({
  mixins: [PlatformServiceMixin],
})
export default class ClaimReportCertificateView extends Vue {
  $notify!: (notification: NotificationIface, timeout?: number) => void;

  // Notification helper
  notify!: ReturnType<typeof createNotifyHelpers>;

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

  endorserServer = endorserServer;

  // Computed properties for canvas optimization
  get CANVAS_WIDTH() {
    return 1100;
  }

  get CANVAS_HEIGHT() {
    return 850;
  }

  async created() {
    // Initialize notification helper
    this.notify = createNotifyHelpers(this.$notify);

    const settings = await this.$accountSettings();

    // Get activeDid from active_identity table (single source of truth)
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const activeIdentity = await (this as any).$getActiveIdentity();
    this.activeDid = activeIdentity.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.error(NOTIFY_ERROR_LOADING_CLAIM.message, TIMEOUTS.LONG);
    }
  }

  async drawCanvas(claimData: GenericCredWrapper<GenericVerifiableCredential>) {
    if (!claimData || !claimData.claim) {
      return;
    }

    // Load contacts if not already loaded
    if (this.allContacts.length === 0) {
      this.allContacts = await this.$getAllContacts();
    }

    const canvas = this.$refs.claimCanvas as HTMLCanvasElement;
    if (canvas) {
      // size to approximate portrait of 8.5"x11"
      canvas.width = this.CANVAS_WIDTH;
      canvas.height = this.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,
            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(
              typeof claimData.claim.agent === "string"
                ? claimData.claim.agent
                : claimData.claim.agent?.identifier,
              this.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,
                this.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
          const qrCodeCanvas = document.createElement("canvas");
          await QRCode.toCanvas(
            qrCodeCanvas,
            APP_SERVER + "/claim/" + this.claimId,
            {
              width: 150,
              color: { light: "#0000" /* Transparent background */ },
            },
          );
          ctx.drawImage(
            qrCodeCanvas,
            this.CANVAS_WIDTH * 0.6,
            this.CANVAS_HEIGHT * 0.55,
          );
        };
      }
    }
  }
}
</script>

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