<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Arquivo: src/features/documents/components/DocumentUploadDialog.vue
| Dialog de upload — drag & drop, tipo, categoria, tags, visibilidade.
|--------------------------------------------------------------------------
-->
<script setup>
import { ref, reactive, watch, computed } from 'vue'
import { useToast } from 'primevue/usetoast'
import DocumentTagsInput from './DocumentTagsInput.vue'

const props = defineProps({
    visible: { type: Boolean, default: false },
    patientId: { type: String, default: null },
    patientName: { type: String, default: '' },
    usedTags: { type: Array, default: () => [] },
    sessions: { type: Array, default: () => [] }
})

const emit = defineEmits(['update:visible', 'uploaded'])

const toast = useToast()

// ── State ───────────────────────────────────────────────────

const file = ref(null)
const filePreviewUrl = ref('')
const dragging = ref(false)
const saving = ref(false)
const formErr = ref('')

const form = reactive({
    tipo_documento: 'outro',
    categoria: '',
    descricao: '',
    tags: [],
    agenda_evento_id: null,
    visibilidade: 'privado',
    compartilhado_portal: false,
    compartilhado_supervisor: false
})

const TIPOS = [
    { value: 'laudo', label: 'Laudo' },
    { value: 'receita', label: 'Receita' },
    { value: 'exame', label: 'Exame' },
    { value: 'termo_assinado', label: 'Termo assinado' },
    { value: 'relatorio_externo', label: 'Relatório externo' },
    { value: 'identidade', label: 'Identidade' },
    { value: 'convenio', label: 'Convênio' },
    { value: 'declaracao', label: 'Declaração' },
    { value: 'atestado', label: 'Atestado' },
    { value: 'recibo', label: 'Recibo' },
    { value: 'outro', label: 'Outro' }
]

const VISIBILIDADES = [
    { value: 'privado', label: 'Privado (só eu)' },
    { value: 'compartilhado_supervisor', label: 'Compartilhado com supervisor' },
    { value: 'compartilhado_portal', label: 'Visível no portal do paciente' }
]

// ── Reset ao abrir ──────────────────────────────────────────

watch(() => props.visible, (v) => {
    if (v) {
        file.value = null
        filePreviewUrl.value = ''
        formErr.value = ''
        Object.assign(form, {
            tipo_documento: 'outro',
            categoria: '',
            descricao: '',
            tags: [],
            agenda_evento_id: null,
            visibilidade: 'privado',
            compartilhado_portal: false,
            compartilhado_supervisor: false
        })
    }
})

// ── Sync visibilidade ───────────────────────────────────────

watch(() => form.visibilidade, (v) => {
    form.compartilhado_portal = v === 'compartilhado_portal'
    form.compartilhado_supervisor = v === 'compartilhado_supervisor'
})

// ── File handling ───────────────────────────────────────────

const MAX_SIZE = 50 * 1024 * 1024 // 50MB

function onFileSelected(e) {
    const f = e.target?.files?.[0]
    if (f) setFile(f)
}

function onDrop(e) {
    dragging.value = false
    const f = e.dataTransfer?.files?.[0]
    if (f) setFile(f)
}

function setFile(f) {
    if (f.size > MAX_SIZE) {
        toast.add({ severity: 'warn', summary: 'Arquivo grande', detail: 'Máximo 50 MB.' })
        return
    }
    file.value = f
    filePreviewUrl.value = f.type.startsWith('image/') ? URL.createObjectURL(f) : ''
    formErr.value = ''
}

function removeFile() {
    file.value = null
    if (filePreviewUrl.value) URL.revokeObjectURL(filePreviewUrl.value)
    filePreviewUrl.value = ''
}

const fileSizeFormatted = computed(() => {
    if (!file.value) return ''
    const b = file.value.size
    if (b < 1024) return b + ' B'
    if (b < 1024 * 1024) return (b / 1024).toFixed(1) + ' KB'
    return (b / (1024 * 1024)).toFixed(1) + ' MB'
})

// ── Submit ──────────────────────────────────────────────────

async function submit() {
    if (!file.value) { formErr.value = 'Selecione um arquivo.'; return }
    if (!props.patientId) { formErr.value = 'Paciente não informado.'; return }

    saving.value = true
    formErr.value = ''

    try {
        emit('uploaded', { file: file.value, meta: { ...form } })
        close()
    } catch (e) {
        formErr.value = e?.message || 'Erro ao enviar arquivo.'
    } finally {
        saving.value = false
    }
}

function close() {
    emit('update:visible', false)
}
</script>

<template>
    <Dialog
        :visible="visible"
        @update:visible="$emit('update:visible', $event)"
        modal
        :draggable="false"
        :closable="!saving"
        :dismissableMask="!saving"
        class="w-[40rem]"
        :breakpoints="{ '768px': '94vw' }"
        :pt="{
            header:  { class: '!p-4 !rounded-t-xl border-b border-[var(--surface-border)]' },
            content: { class: '!p-4' },
            footer:  { class: '!p-3 !rounded-b-xl border-t border-[var(--surface-border)]' }
        }"
        pt:mask:class="backdrop-blur-xs"
    >
        <template #header>
            <div class="flex items-center gap-3">
                <span class="flex items-center justify-center w-8 h-8 rounded-lg bg-blue-500/10">
                    <i class="pi pi-upload text-blue-500" />
                </span>
                <div>
                    <div class="text-base font-semibold">Upload de documento</div>
                    <div class="text-xs text-[var(--text-color-secondary)]" v-if="patientName">{{ patientName }}</div>
                </div>
            </div>
        </template>

        <!-- Drop zone -->
        <div
            v-if="!file"
            class="flex flex-col items-center justify-center gap-3 p-8 rounded-lg border-2 border-dashed transition-colors cursor-pointer"
            :class="dragging ? 'border-primary bg-primary/5' : 'border-[var(--surface-border)] hover:border-[var(--surface-400)]'"
            @dragover.prevent="dragging = true"
            @dragleave="dragging = false"
            @drop.prevent="onDrop"
            @click="$refs.fileInput.click()"
        >
            <i class="pi pi-cloud-upload text-3xl text-[var(--text-color-secondary)]" />
            <div class="text-sm text-[var(--text-color-secondary)] text-center">
                <span class="font-medium text-primary">Clique para selecionar</span> ou arraste o arquivo aqui
            </div>
            <div class="text-xs text-[var(--text-color-secondary)] opacity-60">
                PDF, imagem, Word, Excel — até 50 MB
            </div>
            <input ref="fileInput" type="file" class="hidden" @change="onFileSelected" />
        </div>

        <!-- Arquivo selecionado -->
        <div v-else class="flex items-center gap-3 p-3 rounded-lg bg-[var(--surface-ground)] border border-[var(--surface-border)]">
            <img v-if="filePreviewUrl" :src="filePreviewUrl" class="w-12 h-12 rounded object-cover" />
            <i v-else class="pi pi-file text-2xl text-[var(--text-color-secondary)]" />
            <div class="flex-1 min-w-0">
                <div class="text-sm font-medium truncate">{{ file.name }}</div>
                <div class="text-xs text-[var(--text-color-secondary)]">{{ fileSizeFormatted }}</div>
            </div>
            <Button icon="pi pi-times" text rounded size="small" severity="danger" @click="removeFile" />
        </div>

        <!-- Campos -->
        <div class="flex flex-col gap-3.5 mt-4">
            <div class="grid grid-cols-1 sm:grid-cols-2 gap-3.5">
                <div class="flex flex-col gap-1">
                    <label class="text-xs font-medium text-[var(--text-color-secondary)]">Tipo do documento</label>
                    <Select
                        v-model="form.tipo_documento"
                        :options="TIPOS"
                        optionLabel="label"
                        optionValue="value"
                        class="w-full"
                    />
                </div>
                <div class="flex flex-col gap-1">
                    <label class="text-xs font-medium text-[var(--text-color-secondary)]">Visibilidade</label>
                    <Select
                        v-model="form.visibilidade"
                        :options="VISIBILIDADES"
                        optionLabel="label"
                        optionValue="value"
                        class="w-full"
                    />
                </div>
            </div>

            <div class="flex flex-col gap-1" v-if="sessions.length">
                <label class="text-xs font-medium text-[var(--text-color-secondary)]">Vincular a sessão (opcional)</label>
                <Select
                    v-model="form.agenda_evento_id"
                    :options="sessions"
                    optionLabel="label"
                    optionValue="value"
                    placeholder="Nenhuma sessão"
                    showClear
                    class="w-full"
                />
            </div>

            <div class="flex flex-col gap-1">
                <label class="text-xs font-medium text-[var(--text-color-secondary)]">Descrição (opcional)</label>
                <Textarea v-model="form.descricao" rows="2" autoResize class="w-full" />
            </div>

            <div class="flex flex-col gap-1">
                <label class="text-xs font-medium text-[var(--text-color-secondary)]">Tags</label>
                <DocumentTagsInput v-model="form.tags" :suggestions="usedTags" />
            </div>
        </div>

        <!-- Erro -->
        <div v-if="formErr" class="mt-3 text-sm text-red-500 flex items-center gap-1.5">
            <i class="pi pi-exclamation-circle text-xs" />
            {{ formErr }}
        </div>

        <template #footer>
            <div class="flex items-center justify-end gap-2">
                <Button label="Cancelar" text @click="close" :disabled="saving" />
                <Button label="Enviar" icon="pi pi-upload" :loading="saving" @click="submit" :disabled="!file" />
            </div>
        </template>
    </Dialog>
</template>
