<template>
  <div>
    <div
      class="relative-position"
      :style="{
        width: sizePx,
        height: sizePx, 
        display: 'block'
      }"
      >
      <q-file
        ref="imgFileSelector"
        v-model="imageFile"
        :style="{ display: 'none' }"
        @update:model-value="handleUpload()"
        :filter="checkImgType"
        accept="image/*"
      />
      <q-icon
        v-if="modelValue === '' || modelValue === undefined || modelValue === null"
        name="mdi-camera-plus-outline"
        class="absolute-full fit text-grey-4"
        :style="{ fontSize: String(iconsize) + 'px'}"
        @click = "imgFileSelectorClick"
      />
      <q-img
        v-else
        fit="cover"
        :src="modelValue"
        :style="{
          height: sizePx,
          maxWidth: sizePx,
          borderRadius: avatar ? String(size/2) + 'px' : 'var(--top-raduis)',
        }"
        @click="showDialog = true"
      />
    </div>

    <q-dialog v-model="showDialog">
      <q-card class="w100 relative-position" style="height: auto;">
        <q-img :src="modelValue"/>
        <div 
          class="flex row items-center jutsify-center q-pb-sm" 
          style="bottom: 0; position: absolute; left: 50%; transform: translate(-50%, 0%);">
          <q-btn
            v-for="btn in menuBtns"
            :key="btn.name"
            :icon="btn.icon"
            @click="btn.f"
            class="q-mx-xs bg-white"
            round flat
            style="opacity: 0.8"
            color="primary"
          />
        </div>
        </q-card>
    </q-dialog>
  </div>
</template>

<script setup lang="ts">
  import { ref, Ref, computed } from 'vue' // eslint-disable-line
  import { QFile } from 'quasar'

  const modelValue = defineModel<string>()

  const props = defineProps<{
    size?: number
    iconsize?: number
    avatar?: boolean
  }>()

  const imageFile = ref(null) // file-from selector
  const imgFileSelector= ref() as Ref<QFile> // input file DOM
  const size = ref<number>(props.size ? props.size  : 100)
  const iconsize = ref<number>(props.iconsize ? props.iconsize  : 75)
  const showDialog = ref<boolean>(false)
  const menuBtns = [
    { name: 'change', icon: 'mdi-swap-horizontal', f: imgFileSelectorClick },
    { name: 'delete', icon: 'mdi-delete-outline', f: deleteImage },
    { name: 'close', icon: 'mdi-close', f: () => showDialog.value = false }
  ]

  const sizePx = computed(() => {
    return String(size.value) + 'px'
  })

  async function handleUpload () {
    if (imageFile.value) {
      const img = await imgToBase64(imageFile.value)
      modelValue.value = typeof img === 'string' ? img : ''
    }
  }

  function imgFileSelectorClick () {
    imgFileSelector.value.pickFiles()
  }

  function deleteImage () {
    showDialog.value = false
    imageFile.value = null
    modelValue.value = ''
  }

  function imgToBase64(file: File): Promise<string | ArrayBuffer | null> {
    const reader: FileReader = new FileReader()
    reader.readAsDataURL(file)

    return new Promise((resolve, reject) => {
      reader.onerror = () => {
        reader.abort()
        reject(new Error('Something went wrong'))
      }

      reader.onload = () => {
        resolve(reader.result)
      }
    })
  }

  function checkImgType(files: File[]): File[] {
    return files.filter((file: File) => file.type === 'image/x-png' || file.type === 'image/jpeg' || file.type === 'image/webp' )
  }
</script>

<style scope>
</style>
