<script lang="ts" setup>
import { computed, onMounted, ref, watch } from 'vue';
import { useQuasar } from 'quasar';
import SignaturePad from 'signature_pad';
import Cropper from 'cropperjs';

defineExpose({ clearCanvas, clearUpload });

const $q = useQuasar();
const isDarkActive = computed(() => $q.dark.isActive);

const canvasRef = ref<HTMLCanvasElement>();
const signaturePad = ref();
const currentColor = ref('blue');

const imageRef = ref<HTMLImageElement>();
const cropper = ref();

const tab = ref('draw');
const uploadFile = ref<File | undefined>(undefined);
const profileUrl = ref<string | null>('');
const inputFile = (() => {
  const element = document.createElement('input');
  element.type = 'file';
  element.accept = 'image/*';

  const reader = new FileReader();
  reader.addEventListener('load', () => {
    if (typeof reader.result === 'string') profileUrl.value = reader.result;
  });

  element.addEventListener('change', () => {
    uploadFile.value = element.files?.[0];
    if (uploadFile.value) {
      reader.readAsDataURL(uploadFile.value);
    }
  });

  return element;
})();

async function initializeSignaturePad(canva?: HTMLCanvasElement) {
  if (canva) {
    signaturePad.value = new SignaturePad(canva, {
      backgroundColor: isDarkActive.value
        ? 'rgb(21,25,29)'
        : 'rgb(248,249,250)',
      penColor: 'blue',
    });
  } else {
    console.warn('Canvas reference not found. SignaturePad not initialized.');
  }
}

async function initializeCropper(image?: HTMLImageElement) {
  console.log(image);
  if (image) {
    cropper.value = new Cropper(image, {
      aspectRatio: 16 / 9,
      crop(event) {
        console.log(event.detail.x);
        console.log(event.detail.y);
        console.log(event.detail.width);
        console.log(event.detail.height);
        console.log(event.detail.rotate);
        console.log(event.detail.scaleX);
        console.log(event.detail.scaleY);
      },
    });
  } else {
    console.warn('Canvas reference not found. Cropper not initialized.');
  }
}

function changeColor(color: string) {
  signaturePad.value.penColor = color;
  currentColor.value = color;
}

function clearCanvas() {
  signaturePad.value.clear();
}

function clearUpload() {
  profileUrl.value = '';
}

watch(
  () => tab.value,
  async () => {
    await initializeSignaturePad(canvasRef.value);
    await initializeCropper(imageRef.value);
  },
);

onMounted(async () => {
  await initializeSignaturePad(canvasRef.value);
  await initializeCropper(imageRef.value);
});
</script>
<template>
  <div class="surface-1 bordered rounded full-width">
    <q-tabs
      v-model="tab"
      dense
      align="left"
      class="text-grey"
      active-color="primary"
      indicator-color="primary"
    >
      <div class="row justify-between full-width items-center">
        <div class="row">
          <q-tab
            name="draw"
            label="Draw"
            style="border-top-left-radius: var(--radius-2)"
          />
          <q-tab name="upload" label="Upload" />
        </div>

        <div class="q-pr-md">
          <q-btn
            dense
            flat
            v-if="tab === 'upload'"
            :label="$t('newUpload')"
            color="info"
            @click="inputFile.click()"
          />
        </div>
      </div>
    </q-tabs>
    <q-separator />

    <div v-show="tab === 'draw'" class="q-pa-md">
      <div class="column relative-position">
        <div class="absolute-top-right q-ma-md q-gutter-x-md row items-center">
          <span
            class="dot"
            :class="{ active: currentColor === 'black' }"
            style="background-color: black"
            @click="changeColor('black')"
          >
            <q-icon
              v-if="currentColor === 'black'"
              name="mdi-check"
              color="white"
              size="sm"
            />
          </span>
          <span
            :class="{ active: currentColor === 'red' }"
            class="dot"
            style="background-color: red"
            @click="changeColor('red')"
          >
            <q-icon
              v-if="currentColor === 'red'"
              name="mdi-check"
              color="white"
              size="sm"
            />
          </span>
          <span
            :class="{ active: currentColor === 'blue' }"
            class="dot"
            style="background-color: blue"
            @click="changeColor('blue')"
          >
            <q-icon
              v-if="currentColor === 'blue'"
              name="mdi-check"
              color="white"
              size="sm"
            />
          </span>
        </div>

        <canvas
          class="signature-canvas"
          ref="canvasRef"
          id="signature-pad"
          width="700"
          height="310"
        ></canvas>
      </div>
    </div>

    <div v-show="tab === 'upload'" class="q-pa-md">
      <div
        class="bordered upload-border rounded column items-center justify-center"
        style="height: 312px"
      >
        <q-img
          v-show="profileUrl"
          ref="imageRef"
          :src="profileUrl ?? ''"
          style="object-fit: cover; width: 100%; height: 100%"
        />
        <div v-if="!profileUrl">
          <q-icon
            name="mdi-cloud-upload"
            size="10rem"
            style="color: hsla(var(--text-mute) / 0.2)"
          />
          <div>
            <q-btn
              unelevated
              color="info"
              :label="$t('uploadFile')"
              icon="mdi-plus"
              @click="inputFile.click()"
            />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<style scoped lang="scss">
.signature-canvas {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-2);
}

.dot {
  height: 25px;
  width: 25px;
  border-radius: 50%;
  display: inline-flex;
  justify-content: center;
  align-items: center;

  &.active {
    height: 35px;
    width: 35px;
  }
}

.color-palette {
  position: absolute;
  display: inline-block;
}

.upload-border {
  border-style: dashed;
  border-color: hsl(var(--info-bg));
}
</style>
