<script setup>
import { NModal, NSelect, NSpace, NFlex, NButton, NForm, NFormItem, NInput, NDatePicker, NDivider, NSpin, NTag } from 'naive-ui'
import ArchiveHistoryMoveModal from '../ArchiveHistoryMoveModal/Index.vue'
import {computed, h, ref, watch} from "vue";
import {useMedicalHistoryFilter} from "../../../Composables/useMedicalHistoryFilter.js";
import {useNotification} from "../../../Composables/useNotification.js";
import {useDebounceFn, useTimestamp} from "@vueuse/core";
import {useArchiveCard} from "../../../Stores/ArchiveCard.js";

const open = defineModel('open')

const {errorApi} = useNotification()
const loading = ref(false)
const loadingFilterPatients = ref(false)
const timestampNow = useTimestamp()
const formRef = ref(null)
const archiveCardStore = useArchiveCard()
const isCardInArchive = computed(() => archiveCardStore.preOpenCard !== null)
const emits = defineEmits(['historyUpdated', 'closeWithoutSave', 'openArchiveCard'])
const archiveInfo = ref({
    id: null,
    num: null,
    post_in: timestampNow,
})
const archiveInfoRules = {
    id: [
        {
            required: true,
            validator(rule, value) {
                if (isCardInArchive.value) {
                    return false
                }

                if (!value) {
                    return false
                }
                else if (!Number(value)) {
                    return false
                }
                return true
            },
            renderMessage: () => {
                if (isCardInArchive.value) {
                    return h(
                        'div',
                        [
                            'Карта уже находится в архиве. ',
                            h(
                                NButton,
                                {
                                    text: true,
                                    onClick: (e) => {
                                        e.preventDefault()
                                        archiveCardStore.isOpenArchiveCard = true
                                        onCloseWithoutSave()
                                    }
                                },
                                'Перейти к карте'
                            )
                        ]
                    )
                }

                return 'Это поле необходимо заполнить'
            },
            trigger: ['change', 'blur']
        }
    ],
    num: [
        {
            required: true,
            message: 'Это поле необходимо заполнить',
            trigger: 'blur'
        }
    ],
    post_in: [
        {
            required: true,
            message: 'Это поле необходимо заполнить',
            trigger: 'blur',
            validator(rule, value) {
                return Number(value);
            },
        }
    ]
}

const onResetArchiveInfo = (only) => {
    if (only && Object.keys(only).length > 0) {
        archiveInfo.value = {
            ...archiveInfo.value,
            ...only
        }
    } else {
        archiveInfo.value = {
            id: null,
            num: null,
            post_in: timestampNow,
        }
    }
}

const onResetData = () => {
    onResetArchiveInfo()
    filteredPatients.value = []
    setTimeout(() => archiveCardStore.resetPreOpenCard(), 100)
}

const onCloseWithoutSave = () => {
    emits('closeWithoutSave')
    open.value = false
    onResetData()
}

const filteredPatients = ref([])

const debounceSearchCard = useDebounceFn(async (query) => {
    loadingFilterPatients.value = true
    await axios.post('/api/mis/patients/search', {
        query
    }).then(res => {
        filteredPatients.value = res.data
    }).finally(() => {
        loadingFilterPatients.value = false
    })
}, 1000)

const handleSearchCard = (query) => {
    debounceSearchCard(query)
}

const onSubmit = async (e) => {
    e.preventDefault()
    formRef.value?.validate(async (errors) => {
        if (!errors) {
            loading.value = true
            try {
                await axios.post(`/api/archive/create`, archiveInfo.value).then(res => {
                    open.value = false
                }).then(() => {
                    onResetData()
                })

            } catch (error) {
                errorApi(error)
                console.error(error)
            } finally {
                loading.value = false
            }
        }
        else {
            console.log(errors)
            errorApi(null, 'Проверьте заполненность формы')
        }
    })
}

const updateValueSearch = async (value) => {
    archiveCardStore.setPreOpenCard(null)
    await axios.post('/api/archive/check', {
        id: value
    }).then(res => {
        archiveCardStore.setPreOpenCard(res.data)
    }).catch(err => {
        if (err.code === 404) {
            archiveCardStore.resetPreOpenCard()
        }
    })
}

const onFilter = (pattern, option) => {
    if (!pattern) return true

    const normalizeText = (text) => {
        return text
            .toLowerCase()
            .replace(/[-\s]/g, '') // удаляем дефисы и пробелы
            .trim();
    }

    const normalizedPattern = normalizeText(pattern)
    const normalizedLabel = normalizeText(option.label || '')

    return normalizedLabel.includes(normalizedPattern)
}

watch(() => isCardInArchive.value, (val) => {
    if (val)
        onResetArchiveInfo({
            num: null,
            post_in: null
        })
})
</script>

<template>
    <NModal v-model:show="open"
            preset="card"
            class="max-w-xl relative"
            :mask-closable="false"
            closable
            title="Добавить карту в архив"
            @close="onCloseWithoutSave">
        <NFlex class="w-full" :wrap="false">
            <NForm ref="formRef" id="formAddToArchive" class="w-full" :model="archiveInfo" :rules="archiveInfoRules">
                <NFormItem label="Карта пациента" path="id">
                    <NSelect placeholder="№ карты фамилия имя отчество ИЛИ фамилия имя отчество"
                             size="large"
                             :remote
                             filterable
                             :loading="loadingFilterPatients"
                             :options="filteredPatients"
                             :filter="(pattern, option) => onFilter(pattern, option)"
                             v-model:value="archiveInfo.id"
                             @update:value="(val) => updateValueSearch(val)"
                             @search="handleSearchCard"
                    />
                </NFormItem>
                <NFormItem size="large" label="Дата поступления карты в архив" path="post_in">
                    <NDatePicker class="w-full"
                                 v-model:value="archiveInfo.post_in"
                                 :default-value="timestampNow"
                                 :disabled="archiveCardStore.isSetPreOpenCard"
                                 format="dd.MM.yyyy"
                    />
                </NFormItem>
                <NFormItem size="large" label="№ в архиве" path="num">
                    <NInput v-model:value="archiveInfo.num"
                            :disabled="archiveCardStore.isSetPreOpenCard"/>
                </NFormItem>
            </NForm>
        </NFlex>
        <template #action>
            <NFlex justify="end" align="center">
                <NSpace align="center" :size="0">
                    <NButton secondary
                             type="primary"
                             attr-type="submit"
                             form="formAddToArchive"
                             :disabled="archiveCardStore.isSetPreOpenCard"
                             @click="onSubmit">
                        Добавить карту
                    </NButton>
                </NSpace>
            </NFlex>
        </template>

        <div v-show="loading"
             class="absolute inset-0 z-10 backdrop-blur flex items-center justify-center rounded-[8px]">
            <NSpin :show="true" />
        </div>
    </NModal>
</template>

<style scoped>

</style>
