<script setup lang="ts">
import { computed, ref } from 'vue'
import { useToast } from '@/composables/useToast'

/** 拖拽或点击上传的文本文件选择区；文件内容仅在浏览器本地读取。
 *  compact：单行紧凑形态，用于表单内与其他字段并排。 */
const props = defineProps<{ accept?: string; label?: string; hint?: string; compact?: boolean }>()
const emit = defineEmits<{ load: [text: string, name: string] }>()

const message = useToast()
const inputEl = ref<HTMLInputElement>()
const fileName = ref('')
const dragging = ref(false)

const acceptExts = computed(
  () =>
    props.accept
      ?.split(',')
      .map((s) => s.trim().toLowerCase())
      .filter((s) => s.startsWith('.')) ?? [],
)

function extOk(name: string): boolean {
  if (!acceptExts.value.length) return true
  const lower = name.toLowerCase()
  return acceptExts.value.some((ext) => lower.endsWith(ext))
}

async function take(file: File | undefined) {
  if (!file) return
  if (!extOk(file.name)) {
    message.error(`仅支持 ${acceptExts.value.join(' / ')} 文件`)
    return
  }
  if (file.size > 1024 * 1024) {
    message.error('文件超过 1 MB，请确认选择的是文本文件')
    return
  }
  fileName.value = file.name
  emit('load', await file.text(), file.name)
}

function onChange(e: Event) {
  const input = e.target as HTMLInputElement
  void take(input.files?.[0])
  input.value = ''
}

function onDrop(e: DragEvent) {
  dragging.value = false
  void take(e.dataTransfer?.files?.[0])
}
</script>

<template>
  <div
    v-if="compact"
    class="flex h-[34px] cursor-pointer items-center justify-center gap-2 rounded-md border border-dashed px-3 transition-colors"
    :class="dragging ? 'border-accent bg-accent/5' : 'border-line hover:border-accent'"
    :title="fileName ? '已读取，点击或拖拽可重新选择' : hint"
    @click="inputEl?.click()"
    @dragover.prevent="dragging = true"
    @dragleave="dragging = false"
    @drop.prevent="onDrop"
  >
    <svg
      class="h-3.5 w-3.5 flex-none text-ink-3"
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      stroke-width="1.5"
    >
      <path d="M12 16V4m0 0 4 4m-4-4-4 4" stroke-linecap="round" stroke-linejoin="round" />
      <path d="M4 15v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3" stroke-linecap="round" />
    </svg>
    <span
      class="truncate text-[13px]"
      :class="fileName ? 'mono font-medium text-ink' : 'text-ink-2'"
    >
      {{ fileName || label || '上传文件' }}
    </span>
    <input ref="inputEl" type="file" class="hidden" :accept="accept" @change="onChange" />
  </div>

  <div
    v-else
    class="cursor-pointer rounded-lg border border-dashed px-5 py-5 text-center transition-colors"
    :class="dragging ? 'border-accent bg-accent/5' : 'border-line hover:border-accent'"
    @click="inputEl?.click()"
    @dragover.prevent="dragging = true"
    @dragleave="dragging = false"
    @drop.prevent="onDrop"
  >
    <div
      class="mx-auto flex h-9 w-9 items-center justify-center rounded-md border border-line bg-card text-ink-2"
    >
      <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
        <path d="M12 16V4m0 0 4 4m-4-4-4 4" stroke-linecap="round" stroke-linejoin="round" />
        <path d="M4 15v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3" stroke-linecap="round" />
      </svg>
    </div>
    <div v-if="fileName" class="mt-2.5">
      <div class="mono truncate text-[13px] font-medium text-ink">{{ fileName }}</div>
      <div class="mt-1 text-xs text-ink-3">已读取，点击或拖拽可重新选择</div>
    </div>
    <div v-else class="mt-2.5">
      <div class="text-[13px] font-medium text-ink-2">{{ label ?? '拖拽或点击上传文件' }}</div>
      <div v-if="hint" class="mt-1 text-xs text-ink-3">{{ hint }}</div>
    </div>
    <input ref="inputEl" type="file" class="hidden" :accept="accept" @change="onChange" />
  </div>
</template>
