<script setup>
import {computed, reactive, ref, watch} from "vue";
import {NButton, NDatePicker, NForm, NFormItem, NInput, NModal, NSelect} from "naive-ui";
import {useReportStore} from "../../../Stores/report.js";
import {useDebounceFn} from "@vueuse/core";

const props = defineProps({
    patientKind: {
        type: String,
        required: true,
    },
})

const show = defineModel('show', {type: Boolean, default: false})
const reportStore = useReportStore()
const formRef = ref(null)
const submitting = ref(false)
const mkbLoading = ref(false)
const mkbOptions = ref([])
const getDefaultAdmittedAt = () => reportStore.reportInfo?.dates?.endAt ?? Date.now()

const form = reactive({
    full_name: '',
    birth_date: null,
    admitted_at: getDefaultAdmittedAt(),
    diagnosis_code: '',
    diagnosis_name: '',
})

const rules = {
    full_name: {
        required: true,
        message: 'Укажите ФИО',
        trigger: ['blur', 'input'],
    },
    birth_date: {
        required: true,
        type: 'number',
        message: 'Укажите дату рождения',
        trigger: ['change', 'blur'],
        validator: (_rule, value) => {
            if (!value) return false
            return value <= Date.now()
        },
    },
}

const title = computed(() => props.patientKind === 'plan'
    ? 'Добавить планового пациента спецконтингента'
    : 'Добавить экстренного пациента спецконтингента')

const resetForm = () => {
    form.full_name = ''
    form.birth_date = null
    form.admitted_at = getDefaultAdmittedAt()
    form.diagnosis_code = ''
    form.diagnosis_name = ''
    mkbOptions.value = []
}

const normalizeSpaces = (value) => value.replace(/\s+/g, ' ').trim()
const pad = (value) => String(value).padStart(2, '0')
const formatLocalDate = (timestamp) => {
    const date = new Date(timestamp)
    return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`
}
const formatLocalDateTime = (timestamp) => {
    const date = new Date(timestamp)
    return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
}

const isSubmitDisabled = computed(() => submitting.value)

const handleClose = () => {
    resetForm()
    show.value = false
}

watch(() => show.value, (value) => {
    if (value) {
        form.admitted_at = getDefaultAdmittedAt()
    }
})

const loadMkbOptions = useDebounceFn(async (query) => {
    if (!query || query.trim().length < 2) {
        mkbOptions.value = []
        return
    }

    mkbLoading.value = true
    try {
        const items = await reportStore.searchMkb(query.trim())
        mkbOptions.value = (items ?? []).map((item) => ({
            label: item.label,
            value: item.code,
            name: item.name,
        }))
    } finally {
        mkbLoading.value = false
    }
}, 300)

const handleMkbSearch = async (query) => {
    await loadMkbOptions(query)
}

const handleMkbChange = (value, option) => {
    if (value === null || value === undefined || value === '') {
        form.diagnosis_code = ''
        form.diagnosis_name = ''
        return
    }

    const selected = (!Array.isArray(option) && option)
        ? option
        : mkbOptions.value.find((item) => item.value === value)

    form.diagnosis_code = selected?.value ?? value ?? ''
    form.diagnosis_name = selected?.name ?? ''
}

const submit = async () => {
    if (submitting.value) return

    try {
        await formRef.value?.validate()
    } catch {
        return
    }

    submitting.value = true

    try {
        await reportStore.createManualPatient({
            departmentId: reportStore.reportInfo.department.department_id,
            report_id: reportStore.reportInfo?.report?.report_id ?? null,
            startAt: reportStore.reportInfo?.dates?.startAt,
            endAt: reportStore.reportInfo?.dates?.endAt,
            user_id: reportStore.reportInfo?.report?.userId ?? null,
            full_name: normalizeSpaces(form.full_name),
            birth_date: formatLocalDate(form.birth_date),
            patient_kind: props.patientKind,
            admitted_at: form.admitted_at ? formatLocalDateTime(form.admitted_at) : null,
            diagnosis_code: form.diagnosis_code ? normalizeSpaces(form.diagnosis_code).toUpperCase() : null,
            diagnosis_name: form.diagnosis_name ? normalizeSpaces(form.diagnosis_name) : null,
        })

        resetForm()
        show.value = false
        window.$message.success('Пациент добавлен')
    } finally {
        submitting.value = false
    }
}
</script>

<template>
    <NModal v-model:show="show" preset="card" :title="title" class="max-w-xl" @after-leave="resetForm">
        <NForm ref="formRef" :model="form" :rules="rules" label-placement="top">
            <NFormItem label="ФИО" path="full_name">
                <NInput v-model:value="form.full_name" />
            </NFormItem>
            <NFormItem label="Дата рождения" path="birth_date">
                <NDatePicker v-model:value="form.birth_date" type="date" class="w-full" />
            </NFormItem>
            <NFormItem label="Дата и время поступления">
                <NDatePicker v-model:value="form.admitted_at" type="datetime" class="w-full" />
            </NFormItem>
            <NFormItem label="Диагноз (МКБ)">
                <NSelect
                    v-model:value="form.diagnosis_code"
                    class="w-full"
                    filterable
                    clearable
                    remote
                    :options="mkbOptions"
                    :loading="mkbLoading"
                    placeholder="Начните ввод кода или названия диагноза"
                    @search="handleMkbSearch"
                    @update:value="handleMkbChange"
                />
            </NFormItem>
        </NForm>

        <template #footer>
            <div class="flex justify-end gap-2">
                <NButton @click="handleClose">Отмена</NButton>
                <NButton type="primary" :loading="submitting" :disabled="isSubmitDisabled" @click="submit">
                    Сохранить
                </NButton>
            </div>
        </template>
    </NModal>
</template>
