<script setup>
import PatientTypeSection from "./PatientSection.vue";
import PatientDataTable from "./PatientDataTable.vue";
import {NButton, NFlex, NInput, NTabPane, NTabs, NSpace, NDivider} from "naive-ui";
import PatientTypeSectionItem from "./PatientSectionItem.vue";
import {computed, inject, ref} from "vue";
import {usePatientColumns} from "../../../Composables/usePatientColumns.js";
import OperationInfoModal from "./OperationInfoModal.vue";
import ObservableModal from "./Modals/ObservableModal.vue";
import {useAppDialog} from "../../../Composables/useAppDialog.js";
import {TbSearch} from "vue-icons-plus/tb";
import {router, usePage} from "@inertiajs/vue3";

const props = defineProps({
    patients: {
        type: Object,
        default: () => ({data: []})
    },
    nursePatients: {
        type: Object,
        default: () => ({data: []})
    }
})
const emits = defineEmits([
    'createObservable',
    'removeObservable',
])

const operationsInModal = ref(null)
const showOperationsModal = ref(false)
const activePatient = ref(null)
const showObservableModal = ref(false)
const searchArg = ref(null)
const searching = ref(false)
const { reportForm, updateReportForm } = inject('reportForm')

const page = usePage()
const canEditObservable = computed(() => {
    const perms = page.props.user?.permissions ?? []
    return perms.includes('report.create') || perms.includes('report.edit') || perms.includes('report.edit.past')
})

// Нормализация даты до минут для сравнения (убирает расхождения в секундах)
const normDate = (d) => {
    if (!d) return null
    try { return new Date(d).toISOString().slice(0, 16) } catch { return null }
}

const nurseByOriginalId = computed(() => {
    const map = new Map()
    for (const p of props.nursePatients?.data ?? []) {
        if (p.original_id != null) map.set(p.original_id, p)
    }
    return map
})

const FIELD_LABELS = {
    recipient_date: 'дата госпитализации',
    extract_date: 'дата выписки',
    death_date: 'дата смерти',
    ingoing_date: 'дата поступления в отделение',
    out_date: 'дата выбытия из отделения',
    department: 'перевод в другое отделение',
}

const getNurseChanges = (misPat) => {
    // Текущий период: MedicalHistory использует 'id', прошлый: ReportDutyPatient — 'original_id'
    const patientKey = misPat.original_id ?? misPat.id
    const nurseP = nurseByOriginalId.value.get(patientKey)
    if (!nurseP) return []

    const changes = []

    if (normDate(nurseP.recipient_date) !== normDate(misPat.recipient_date))
        changes.push('recipient_date')
    if (normDate(nurseP.extract_date) !== normDate(misPat.extract_date))
        changes.push('extract_date')
    if (normDate(nurseP.death_date) !== normDate(misPat.death_date))
        changes.push('death_date')

    // Текущий период грузит latestMigration (объект), прошлый — migrations (массив)
    const nurseMig = nurseP.migrations?.[0]
    const misMig = misPat.migrations?.[0] ?? misPat.latest_migration
    if (nurseMig && misMig) {
        if (normDate(nurseMig.ingoing_date) !== normDate(misMig.ingoing_date))
            changes.push('ingoing_date')
        if (normDate(nurseMig.out_date) !== normDate(misMig.out_date))
            changes.push('out_date')
        if (nurseMig.department_id !== misMig.department_id)
            changes.push('department')
    }

    return changes
}

const withNurse = (p) => {
    const nurse_changes = getNurseChanges(p)
    if (!nurse_changes.length) return p
    return {
        ...p,
        nurse_changes,
        nurse_changes_labels: nurse_changes.map(k => FIELD_LABELS[k] ?? k),
    }
}

const patientsByGroup = computed(() => {
    const groups = {
        urgent: [],
        planned: [],
        deceased: [],
        in_department: [],
        recipient: [],
        discharged: [],
        transferred: [],
        reanimations: [],
        observables: []
    }

    const patients = props.patients?.data ?? []

    for (const raw of patients) {
        const p = withNurse(raw)
        const flags = p.period_flags ?? {}
        const isCurrentAtEnd = flags.current_at_end ?? ['in_department', 'recipient'].includes(p.patient_status)

        // Группировка по срочности за период: пациент должен состоять на конец периода.
        if (isCurrentAtEnd && (flags.urgent ?? p.patient_urgency === 'urgent')) groups.urgent.push(p)
        else if (isCurrentAtEnd && (flags.planned ?? p.patient_urgency === 'planned')) groups.planned.push(p)

        // Группировка по реанимации
        if (p.in_reanimation === true) groups.reanimations.push(p)
        // Группировка по наблюдению
        if (p.in_observable === true) groups.observables.push(p)

        // Событийная группировка за период. Один пациент может быть в нескольких группах.
        if (flags.recipient ?? p.patient_status === 'recipient') groups.recipient.push(p)
        if (flags.current_at_end ?? p.patient_status === 'in_department') groups.in_department.push(p)
        if (flags.discharged ?? p.patient_status === 'discharged') groups.discharged.push(p)
        if (flags.deceased ?? p.patient_status === 'deceased') groups.deceased.push(p)
        if (flags.transferred ?? p.patient_status === 'transferred') groups.transferred.push(p)
    }

    return groups
})

const {
    planOrEmergencyColumns, observableColumns, reanimationColumns, dischargedColumns,
    deceasedColumns, transferredColumns,
} = usePatientColumns({
    onAddObservable: (row) => {
        activePatient.value = row
        showObservableModal.value = true
    },
    onShowOperationModal: ({patient, operations}) => {
        activePatient.value = patient
        operationsInModal.value = operations
        showOperationsModal.value = true
    },
    onAddObservableComment: (row) => {
        activePatient.value = row
        showObservableModal.value = true
    },
    onRemoveObservable: async (row) => {
        await useAppDialog({
            title: 'Снятие с контроля',
            content: 'Это действие необратимо. Продолжить?',
            onConfirm: async () => {
                const queryString = window.location.search;
                const params = new URLSearchParams(queryString);
                const url = new URL(`${window.location.origin}/api/duty/observable/close`)
                url.searchParams.append('startAt', params.get('startAt'))
                url.searchParams.append('endAt', params.get('endAt'))

                try {
                    await axios.post(url.toString(), { ...row })
                } catch (e) {
                    if (e.response?.status !== 404) throw e
                    // 404 — запись не найдена, удаляем локально
                }
                emits('removeObservable', row)
            }
        })
    }
}, { canEditObservable })

const findPatient = () => {
    if (searching.value) return

    // Просто перезагружаем текущую страницу с новым search параметром
    router.reload({
        data: {
            search: searchArg.value || null, // Отправляем как POST или GET параметр
        },
        preserveState: true,
        preserveScroll: true,
        only: ['patients', 'search'], // Обновляем только нужные пропсы
        onStart: () => {
            searching.value = true
        },
        onFinish: () => {
            searching.value = false
        }
    })
}

const resetSearch = () => {
    searchArg.value = null

    router.reload({
        data: { search: null }, // Отправляем null
        preserveState: true,
        preserveScroll: true,
        only: ['patients', 'search', 'meta'],
        onStart: () => {
            searching.value = true
        },
        onFinish: () => {
            searching.value = false
        }
    });
}

const onObservablePatient = (model) => {
    const observableKey = 'observables'
    const observablesInReport = reportForm.value[observableKey]
    const preparedModel = {
        ...model,
        in_observable: true
    }
    const form = { [observableKey]: [...observablesInReport, preparedModel] }
    updateReportForm(form)
    emits('createObservable', preparedModel)
}
</script>

<template>
    <NSpace vertical :size="16">
        <NFlex :wrap="false">
            <NInput v-model:value="searchArg"
                    placeholder="Поиск пациента по ФИО"
                    @keydown.enter="findPatient"
                    clearable
                    @clear="resetSearch"
            />
            <NButton secondary @click="findPatient">
                <template #icon>
                    <TbSearch />
                </template>
                Найти
            </NButton>
        </NFlex>
        <PatientTypeSection>
            <PatientTypeSectionItem label="Планово" :counter="patientsByGroup.planned.length">
                <PatientDataTable :data="patientsByGroup.planned" :columns="planOrEmergencyColumns" :loading="searching" />
            </PatientTypeSectionItem>
            <PatientTypeSectionItem label="Экстренно" :counter="patientsByGroup.urgent.length">
                <PatientDataTable :data="patientsByGroup.urgent" :columns="planOrEmergencyColumns" :loading="searching" />
            </PatientTypeSectionItem>
            <PatientTypeSectionItem label="Находятся на контроле" :counter="patientsByGroup.observables.length">
                <PatientDataTable :data="patientsByGroup.observables" :columns="observableColumns" :loading="searching" />
            </PatientTypeSectionItem>
            <PatientTypeSectionItem label="Находятся в реанимации" :counter="patientsByGroup.reanimations.length">
                <PatientDataTable :data="patientsByGroup.reanimations" :columns="reanimationColumns" :loading="searching" />
            </PatientTypeSectionItem>
            <PatientTypeSectionItem label="Выбывшие" :counter="patientsByGroup.discharged.length + patientsByGroup.deceased.length">
                <NTabs type="segment" animated>
                    <NTabPane name="1" :tab="`Выписанные (${patientsByGroup.discharged.length})`">
                        <PatientDataTable :data="patientsByGroup.discharged" :columns="dischargedColumns" :loading="searching" />
                    </NTabPane>
                    <NTabPane name="2" :tab="`Умершие (${patientsByGroup.deceased.length})`">
                        <PatientDataTable :data="patientsByGroup.deceased" :columns="deceasedColumns" :loading="searching" />
                    </NTabPane>
                    <NTabPane name="3" :tab="`Переведенные (${patientsByGroup.transferred.length})`">
                        <PatientDataTable :data="patientsByGroup.transferred" :columns="transferredColumns" :loading="searching" />
                    </NTabPane>
                </NTabs>
            </PatientTypeSectionItem>
        </PatientTypeSection>
    </NSpace>

    <OperationInfoModal :patient="activePatient" :operations="operationsInModal" v-model:show="showOperationsModal" />
    <ObservableModal :patient="activePatient" v-model:show="showObservableModal" @on-submit="(model) => onObservablePatient(model)" />
</template>

<style scoped>

</style>
