<script setup lang="ts">
import type {PropType} from 'vue';

const props = defineProps({
  value: {
    type: Object as PropType<File | null>,
    default: null,
  },
  text: {
    type: String,
    default: '选择图片进行图生图',
  },
  textOnSelect: {
    type: String,
  },
})
const emit = defineEmits(['update'])

const fileInput = ref<HTMLInputElement | null>(null)

const selected_file = ref<File | null>(null)
const image_dataurl = ref('')
const loading = ref(false)

watch(() => props.value, async (newVal) => {
  handleFileInput({target: {files: [newVal!]}})
})

const handleTrashClick = () => {
  fileInput.value!.value = '';
  selected_file.value = null
  image_dataurl.value = ''
  emit('update', null)
}

const handleFileInput = (event: { target: any; }) => {
  if (event.target.files) {
    const file = event.target.files[0]
    if (!file) return
    selected_file.value = file
    loading.value = true
    const reader = new FileReader()
    reader.onload = (e) => {
      image_dataurl.value = e.target?.result as string
      loading.value = false
    }
    reader.onerror = (e) => {
      loading.value = false
    }
    reader.readAsDataURL(selected_file.value!)
    emit('update', selected_file.value)
  }
}
</script>

<template>
  <div class="w-full bg-neutral-200/50 dark:bg-neutral-700/50 rounded-md flex justify-between items-center p-1.5 gap-2 relative
              hover:bg-neutral-200/80 hover:dark:bg-neutral-700/80 transition border dark:border-neutral-700 cursor-pointer"
       :class="{'cursor-pointer': !loading, 'cursor-not-allowed': loading}"
       @click="() => !loading && fileInput?.click()">
    <input ref="fileInput" type="file" class="hidden" @change="handleFileInput" accept="image/*"/>
    <Transition name="trash-btn" mode="out-in">
      <button type="button" @click.stop.prevent="handleTrashClick" v-if="!!selected_file"
              class="absolute -top-1 -right-1 bg-white dark:bg-black rounded-full p-1 shadow-lg border dark:border-neutral-700">
        <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
          <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                d="M4 7h16m-10 4v6m4-6v6M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2l1-12M9 7V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3"/>
        </svg>
      </button>
    </Transition>
    <div class="w-12 h-12 rounded-md overflow-hidden">
      <Transition name="preview-swap" mode="out-in">
        <div v-if="loading"
             class="w-full h-full flex justify-center items-center rounded-md border-2 border-dashed border-neutral-400 dark:border-neutral-600 text-neutral-400 dark:text-neutral-600">
          <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24">
            <path fill="currentColor" d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
                  opacity=".25"/>
            <path fill="currentColor"
                  d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z">
              <animateTransform attributeName="transform" dur="0.75s" repeatCount="indefinite" type="rotate"
                                values="0 12 12;360 12 12"/>
            </path>
          </svg>
        </div>
        <div v-else-if="!selected_file"
             class="w-full h-full flex justify-center items-center rounded-md border-2 border-dashed border-neutral-400 dark:border-neutral-600 text-neutral-400 dark:text-neutral-600">
          <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24">
            <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                  d="M12 5v14m-7-7h14"/>
          </svg>
        </div>
        <img v-else class="w-12 h-12 rounded-md object-cover" :src="image_dataurl" :key="selected_file.name"
             alt="Preview">
      </Transition>
    </div>
    <div class="flex-1 flex justify-center">
      <p class="text-neutral-400/80 dark:text-neutral-500 text-sm font-medium select-none text-center">
        {{ selected_file ? textOnSelect : text }}
        <span v-if="selected_file && textOnSelect" class="block text-[10px] text-center">
          {{ selected_file?.name || textOnSelect }}
        </span>
      </p>
    </div>
  </div>
</template>

<style scoped>
.trash-btn-enter-active,
.trash-btn-leave-active {
  @apply transition duration-200;
}

.trash-btn-enter-from,
.trash-btn-leave-to {
  @apply opacity-0 scale-75;
}

.preview-swap-enter-active,
.preview-swap-leave-active {
  @apply transition duration-200;
}

.preview-swap-enter-from,
.preview-swap-leave-to {
  @apply blur-sm;
}
</style>