<script setup lang="ts">
import { Upload } from 'lucide-vue-next';
import { computed, ref } from 'vue';

const props = withDefaults(
    defineProps<{
        label: string;
        previewSrc: string;
        accept?: string;
        buttonText?: string;
    }>(),
    {
        accept: 'image/*',
        buttonText: 'Choose File',
    },
);

const emit = defineEmits<{
    (e: 'select', payload: { file: File; previewUrl: string }): void;
}>();

const inputRef = ref<HTMLInputElement | null>(null);
const selectedFileName = ref('');

const displayName = computed(() => {
    if (selectedFileName.value) {
        return selectedFileName.value;
    }

    return props.previewSrc ? 'Current image' : 'No file selected';
});

const openPicker = (): void => {
    inputRef.value?.click();
};

const onChange = (event: Event): void => {
    const target = event.target as HTMLInputElement;
    const file = target.files?.[0];

    if (!file) {
        return;
    }

    selectedFileName.value = file.name;
    emit('select', {
        file,
        previewUrl: URL.createObjectURL(file),
    });
};
</script>

<template>
    <div class="space-y-2">
        <label class="block ps-1 text-start text-[10px] font-bold tracking-widest text-slate-400 uppercase">{{ label }}</label>
        <div class="flex items-center gap-2">
            <button
                type="button"
                class="flex shrink-0 items-center gap-1.5 rounded-xl border border-slate-200 bg-slate-50 px-3 py-2 text-xs font-semibold text-slate-700 transition-all hover:bg-slate-100 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 dark:hover:bg-slate-700"
                @click="openPicker"
            >
                <Upload :size="14" />
                {{ buttonText }}
            </button>
            <div
                class="flex-1 truncate rounded-xl border border-slate-200 bg-slate-50 px-3 py-2 text-xs text-slate-600 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-300"
            >
                {{ displayName }}
            </div>
            <div
                class="flex aspect-square h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-lg border border-slate-200 bg-white dark:border-slate-700 dark:bg-slate-800"
            >
                <img v-if="previewSrc" :src="previewSrc" class="h-full w-full object-cover" :alt="label" />
                <span v-else class="text-[9px] text-slate-400">N/A</span>
            </div>
        </div>
        <input ref="inputRef" type="file" class="hidden" :accept="accept" @change="onChange" />
    </div>
</template>
