<template>
  <div class="file-uploader">
    <label class="file-uploader__dropzone-wrap">
      <div
        class="file-uploader__dropzone"
        :class="{ 'file-uploader__dropzone--active': isDragging }"
        @dragover.prevent
        @dragenter="isDragging = true"
        @dragleave="isDragging = false"
        @drop="handleDrop"
      >
        <SvgIcon name="upload" :size="32" class="file-uploader__upload-icon" />
        <span class="file-uploader__upload-text">{{ uploadText }}</span>
        <input
          type="file"
          class="file-uploader__input"
          :accept="accept"
          :multiple="multiple"
          @change="handleFileSelect"
        />
      </div>
    </label>

    <div v-if="modelValue.length > 0" class="file-uploader__list">
      <div v-for="(file, index) in modelValue" :key="file.id ?? index" class="file-uploader__item">
        <div class="file-uploader__item-info">
          <SvgIcon name="file" :size="24" class="file-uploader__item-icon" />
          <div class="file-uploader__item-meta">
            <p class="file-uploader__item-name">{{ file.name }}</p>
            <p class="file-uploader__item-size">{{ formatFileSize(file.size) }}</p>
          </div>
        </div>

        <div class="file-uploader__item-actions">
          <img
            v-if="file.url && isImage(file)"
            :src="file.url"
            class="file-uploader__item-thumb"
            alt="preview"
          />
          <a v-else-if="file.url" :href="file.url" target="_blank" class="file-uploader__item-link">
            دانلود
          </a>

          <CircleButton
            tooltip="حذف"
            bg-color="transparent"
            size="2rem"
            @click="removeFile(index, file)"
          >
            <template #icon>
              <SvgIcon name="close" color="red" :size="16" />
            </template>
          </CircleButton>
        </div>
      </div>
    </div>

    <div v-else class="file-uploader__empty">هیچ فایلی آپلود نشده است</div>
  </div>
</template>

<script setup>
import { computed, ref } from 'vue'
import SvgIcon from '@/components/icons/SvgIcon.vue'
import CircleButton from '@/components/CircleButton.vue'

const props = defineProps({
  modelValue: { type: Array, default: () => [] },
  accept: { type: String, default: '*' },
  multiple: { type: Boolean, default: true },
  maxFiles: { type: Number, default: 10 },
  maxSize: { type: Number, default: 0 },
})

const emit = defineEmits(['update:modelValue', 'select', 'remove', 'error'])

const isDragging = ref(false)

const uploadText = computed(() =>
  props.modelValue.length === 0 ? 'فایل جدید اضافه کنید' : 'فایل دیگری اضافه کنید'
)

const handleFileSelect = (event) => {
  const files = [...event.target.files]
  emitFiles(files)
  event.target.value = ''
}

const handleDrop = (event) => {
  event.preventDefault()
  isDragging.value = false
  const files = [...event.dataTransfer.files]
  emitFiles(files)
}

const emitFiles = (files) => {
  if (props.modelValue.length + files.length > props.maxFiles) {
    emit('error', `حداکثر تعداد فایل مجاز ${props.maxFiles} عدد است.`)
    return
  }
  if (props.maxSize > 0) {
    const tooBig = files.find((f) => f.size > props.maxSize)
    if (tooBig) {
      emit('error', `حجم فایل "${tooBig.name}" بیش از حد مجاز است.`)
      return
    }
  }
  emit('select', files)
}

const removeFile = (index, file) => {
  const next = [...props.modelValue]
  next.splice(index, 1)
  emit('update:modelValue', next)
  emit('remove', { index, file })
}

const isImage = (file) =>
  file.type === 'image' || /\.(jpe?g|png|gif|webp|svg)$/i.test(file.name || '')

const formatFileSize = (bytes) => {
  if (!bytes) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return `${Number.parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`
}
</script>

<style lang="scss" scoped>
.file-uploader {
  width: 100%;

  &__dropzone-wrap {
    display: block;
    width: 100%;
    cursor: pointer;
    margin-bottom: 0.75rem;
  }

  &__dropzone {
    border: 2px dashed #d1d5db;
    border-radius: 0.5rem;
    padding: 1rem;
    text-align: center;
    transition: border-color 0.2s;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;

    &:hover,
    &--active {
      border-color: var(--color-primary);
    }
  }

  &__upload-icon {
    color: #9ca3af;
  }

  &__upload-text {
    font-family: var(--font-family-fa);
    font-size: 0.875rem;
    font-weight: 500;
    color: #4b5563;
  }

  &__input {
    display: none;
  }

  &__list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 0.625rem;
  }

  &__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem;
    background-color: #eee;
    border-radius: 0.5rem;
    margin-bottom: 1rem;
    gap: 0.75rem;
  }

  &__item-info {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
  }

  &__item-icon {
    color: #6b7280;
    flex-shrink: 0;
  }

  &__item-meta {
    min-width: 0;
  }

  &__item-name {
    font-family: var(--font-family-fa);
    font-size: 0.875rem;
    font-weight: 500;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  &__item-size {
    font-family: var(--font-family-en);
    font-size: 0.75rem;
    color: #6b7280;
    margin: 0;
  }

  &__item-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }

  &__item-thumb {
    width: 4rem;
    height: 3rem;
    object-fit: cover;
    border-radius: 0.25rem;
  }

  &__item-link {
    font-family: var(--font-family-fa);
    font-size: 0.875rem;
    color: var(--color-primary);
    text-decoration: none;

    &:hover {
      opacity: 0.85;
    }
  }

  &__empty {
    text-align: center;
    padding: 1rem 0;
    font-family: var(--font-family-fa);
    color: #6b7280;
    font-size: 0.875rem;
  }
}
</style>
