<template>
  <section class="upload-block-shell">
    <input
      ref="inputRef"
      class="upload-block-input"
      type="file"
      :accept="activeAccept"
      @change="handleFileChange"
    >

    <div class="upload-block-card" :class="{ 'is-uploading': isUploading }" @click="openFileDialog()">
      <div class="upload-block-cross" aria-hidden="true">
        <span></span>
        <span></span>
      </div>

      <div class="upload-block-footer" @click.stop>
        <span class="upload-block-label">{{ isUploading ? '处理中...' : '上传' }}</span>
        <label class="upload-block-select-wrap" for="upload-block-format-select">
          <select
            id="upload-block-format-select"
            v-model="activeFilter"
            class="upload-block-select"
            :disabled="isUploading"
            @change="handleFilterChange"
            @click.stop
          >
            <option value="">全部</option>
            <option
              v-for="option in props.menuOptions"
              :key="option.value"
              :value="option.value"
            >
              {{ option.label }}
            </option>
          </select>
          <svg class="upload-block-select-arrow" width="12" height="12" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
            <path d="M7 10l5 6 5-6z" />
          </svg>
        </label>
      </div>
    </div>
  </section>
</template>

<script setup>
import { computed, ref, watch } from 'vue'
import { getUploadBlockAcceptForType } from '../utils/uploadBlock.js'

const props = defineProps({
  allowedTypes: { type: Array, default: () => [] },
  accept: { type: String, default: '' },
  menuOptions: { type: Array, default: () => [] },
  onUploadRequest: { type: Function, default: null },
})

const inputRef = ref(null)
const isUploading = ref(false)
const activeFilter = ref('')
const activeAccept = computed(() => {
  if (activeFilter.value) {
    return getUploadBlockAcceptForType(activeFilter.value) || props.accept
  }
  return props.accept
})

const openFileDialog = (filter = '') => {
  if (isUploading.value) return
  activeFilter.value = filter
  inputRef.value?.click()
}

const handleFilterChange = (event) => {
  const nextValue = event?.target?.value || ''
  activeFilter.value = nextValue
  if (nextValue) {
    openFileDialog(nextValue)
  }
}

const handleFileChange = async (event) => {
  const input = event.target
  const file = input?.files?.[0]
  if (!file || !props.onUploadRequest) {
    if (input) input.value = ''
    return
  }

  isUploading.value = true

  try {
    await props.onUploadRequest(file)
  } finally {
    isUploading.value = false
    activeFilter.value = ''
    if (input) input.value = ''
  }
}

watch(
  () => props.accept,
  () => {
    activeFilter.value = ''
  }
)
</script>

<style scoped>
.upload-block-shell {
  display: flex;
  justify-content: flex-start;
  width: 100%;
  margin: 24px 0;
}

.upload-block-input {
  display: none;
}

.upload-block-card {
  position: relative;
  width: 10%;
  aspect-ratio: 1 / 1;
  min-width: 108px;
  border-radius: 22px;
  border: 2px solid var(--upload-card-border);
  background: var(--upload-card-bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  cursor: pointer;
  box-shadow: var(--upload-card-shadow);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}

.upload-block-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 20px 42px rgba(249, 115, 22, 0.28);
}

.upload-block-card.is-uploading {
  cursor: wait;
  opacity: 0.78;
}

.upload-block-footer {
  display: flex;
  align-items: center;
  gap: 6px;
}

.upload-block-label {
  color: var(--app-text);
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
}

.upload-block-select-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-width: 56px;
}

.upload-block-cross {
  position: relative;
  width: 54%;
  height: 54%;
}

.upload-block-cross span {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 4px;
  border-radius: 999px;
  background: var(--upload-card-border);
  transform: translate(-50%, -50%);
}

.upload-block-cross span:last-child {
  width: 4px;
  height: 100%;
}

.upload-block-select {
  appearance: none;
  width: 100%;
  padding: 0 18px 0 0;
  border: none;
  background: transparent;
  color: var(--app-text);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  outline: none;
}

.upload-block-select:disabled {
  cursor: wait;
}

.upload-block-select-arrow {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  color: var(--app-text);
  pointer-events: none;
}

:global(.upload-block-node-view) {
  display: block;
  width: 100%;
  min-width: 0;
}

:global(.upload-block-node-view.ProseMirror-selectednode) {
  outline: none !important;
}

:global(.upload-block-node-view.ProseMirror-selectednode .upload-block-card) {
  outline: none !important;
  box-shadow: var(--upload-card-shadow) !important;
}

:global(.upload-block-node-view.ProseMirror-selectednode)::after {
  display: none !important;
}

@media (max-width: 1280px) {
  .upload-block-card {
    width: 40%;
  }
}
</style>
