<script setup>
import {
    NIcon,
    NText,
    NDataTable,
    NButton,
    NBadge,
    NTabs,
    NTabPane,
    NPopover,
    NEllipsis,
    NTooltip,
    NFlex,
    NInput,
    NPagination,
    NSpin,
} from "naive-ui";
import {useReportStore} from "../../../Stores/report.js";
import {computed, h, ref, watch} from "vue";
import {storeToRefs} from "pinia";
import {TbEye, TbExternalLink, TbPencil, TbTrash, TbLock, TbEdit} from "vue-icons-plus/tb";
import MoveModalComment from "./MoveModalComment.vue";
import OperationInfoModal from "./OperationInfoModal.vue";
import ManualPatientOutcomeModal from "./ManualPatientOutcomeModal.vue";
import ManualPatientLinkModal from "./ManualPatientLinkModal.vue";
import ManualPatientEditModal from "./ManualPatientEditModal.vue";
import ManualPatientOperationsModal from "./ManualPatientOperationsModal.vue";
import ReanimationIndicatorModal from "./ReanimationIndicatorModal.vue";
import {useDebounceFn} from "@vueuse/core";

const props = defineProps({
    id: {
        type: String,
        default: null
    },
    mode: {
        type: String,
        default: 'fillable' // 'fillable', 'readonly'
    },
    keys: {
        type: Array,
        default: ['num', 'fullname', 'age', 'birth_date', 'admitted_at']
    },
    status: {
        type: String,
        default: null // 'plan'
    },
    isRemovable: {
        type: Boolean,
        default: false
    },
    isDraggable: {
        type: Boolean,
        default: false
    },
    isDraggableDrop: {
        type: Boolean,
        default: false
    },
    accentIds: {
        type: Array,
        default: []
    },
    enabled: {
        type: Boolean,
        default: true,
    },
})

const isFillableMode = computed(() => props.mode.toLowerCase() === 'fillable')
const isReadonlyMode = computed(() => props.mode.toLowerCase() === 'readonly')
const baseStatus = computed(() => props.status.replace(/^(mis|special)-/, ''))
const isSpecialStatus = computed(() => props.status.startsWith('special-'))

const tableRef = ref()

const emit = defineEmits(['item-dragged', 'item-dropped'])

const reportStore = useReportStore()
const {patientsData, statusStates} = storeToRefs(reportStore)
const showMoveModal = ref(false)
const showOperationInfoModal = ref(false)
const showManualOutcomeModal = ref(false)
const showManualLinkModal = ref(false)
const showManualEditModal = ref(false)
const showManualOperationsModal = ref(false)
const showReanimationIndicatorModal = ref(false)
const currentHistory = ref(null)
const latestDropItem = ref(null)
const activePatient = ref(null)

const hasDisabledEdit = computed(() => {
    return !Boolean(reportStore.reportInfo?.report?.isActiveSendButton)
})
const isHeadOrAdmin = computed(() => Boolean(reportStore.reportInfo?.report?.isHeadOrAdmin))
const canEditSpecial = computed(() => (
    isSpecialStatus.value
    && (!hasDisabledEdit.value || isHeadOrAdmin.value)
    && baseStatus.value !== 'observation'
))
const canEditReanimationIndicator = computed(() => (
    baseStatus.value === 'reanimation'
    && !isSpecialStatus.value
    && (!hasDisabledEdit.value || isHeadOrAdmin.value)
))
const statusState = computed(() => statusStates.value[props.status] ?? {
    page: 1,
    perPage: 20,
    total: 0,
    search: '',
    loading: false,
    loaded: false,
})
const searchValue = ref('')
const isObservationStatus = computed(() => baseStatus.value === 'observation')
const showPagination = computed(() => !isObservationStatus.value)

// Добавляем drag колонку если режим fillable
const columns = computed(() => {
    const resolvedBaseColumns = reportStore.getColumnsByKey(props.keys)
        .filter(Boolean)
        .map((column) => ({
            ...column,
            align: 'left',
            titleAlign: 'left',
        }))

    const newColumns = []

    const dragColumn = {
        title: '',
        key: 'goToMis',
        width: 40,
        align: 'left',
        titleAlign: 'left',
        render: (row) => {
            const actions = []

            if (canEditSpecial.value && row?.department_patient_id) {
                actions.push(
                    h(
                        NTooltip,
                        {},
                        {
                            trigger: () => h(
                                'div',
                                {
                                    style: {
                                        cursor: 'pointer',
                                        textAlign: 'center',
                                        userSelect: 'none',
                                        color: '#6b7280',
                                        display: 'inline-flex',
                                    },
                                    onClick: () => {
                                        activePatient.value = row
                                        showManualEditModal.value = true
                                    },
                                },
                                [h(NIcon, { depth: 3, size: 16 }, h(TbPencil))]
                            ),
                            default: () => 'Редактировать',
                        }
                    )
                )
            }

            if (row.medical_history_id) {
                actions.push(
                    h(
                        NTooltip,
                        {},
                        {
                            trigger: () => h(
                                'div',
                                {
                                    style: {
                                        cursor: 'pointer',
                                        textAlign: 'center',
                                        userSelect: 'none',
                                        display: 'inline-flex',
                                    },
                                    onClick: () => {
                                        window.open(`https://stationar.amurzdrav.ru/prod/statist/edit/card/${row.medical_history_id}`, '_blank')
                                    }
                                },
                                [h(NIcon, { depth: 2 }, h(TbExternalLink))]
                            ),
                            default: () => 'Перейти в карту'
                        }
                    )
                )
            }

            if (!actions.length) {
                return null
            }

            if (actions.length === 1) {
                return actions[0]
            }

            return h(
                'div',
                {
                    style: {
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'center',
                        gap: '6px',
                    },
                },
                actions
            )
        }
    }

    const removeColumn = {
        title: '',
        key: 'remove',
        align: 'left',
        titleAlign: 'left',
        render: (row) => h(
            NButton,
            {
                text: true,
                disabled: hasDisabledEdit.value,
                    onClick: () => {
                        axios.post('/api/report/observation/remove', {
                            id: row.id
                        }).then(async () => {
                            reportStore.removeObservationPatientLocally(row.id)
                        })
                    }
                },
            [
                h(NIcon, {size: '16'}, h(TbTrash))
            ]
        )
    }

    const expandColumn = {
        title: '',
        width: '30',
        align: 'left',
        titleAlign: 'left',
        render: (rowData) => {
            return h(
                NIcon,
                {
                    onClick: () => {
                        latestDropItem.value = rowData
                        showMoveModal.value = true
                    }
                },
                {
                    default: h(TbEye)
                }
            )
        }
    }

    const fillableColumn = {
        title: '',
        key: 'fillable',
        width: '20',
        align: 'left',
        titleAlign: 'left',
        render: (row) => h(
            NBadge,
            {
                dot: true,
                color: (row.comment && row.comment.trim()) ? '#7fe7c4' : '#e88080'
            }
        )
    }

    if (baseStatus.value === 'observation') {
        newColumns.push(expandColumn)
        newColumns.push(fillableColumn)
    }

    newColumns.push(dragColumn)
    newColumns.push(...resolvedBaseColumns)
    newColumns.push({
        title: 'Диагноз',
        key: 'ds',
        align: 'left',
        titleAlign: 'left',
        render: (row) => {
            if (row.mkb.ds !== null && row.mkb.name !== null) {
                return h(NPopover, {
                    placement: 'top',
                    arrow: false
                }, {
                    trigger: h(
                        'div',
                        {
                            class: 'cursor-help w-full',
                            style: 'padding: 8px;'
                        },
                        row.mkb.ds
                    ),
                    default: row.mkb.name
                })
            } else {
                return row.mkb.ds
            }
        },
        cellProps: (rowData, rowIndex) => {
            const styles = ['--n-td-padding: 0;']
            return {
                'style': styles
            }
        }
    })
    if (props.isRemovable) newColumns.push(removeColumn)

    if (baseStatus.value === 'emergency' || baseStatus.value === 'plan') {
        const operationColumn = {
            title: 'Операции',
            key: 'operations',
            align: 'left',
            titleAlign: 'left',
            render: (row) => canEditSpecial.value && row?.department_patient_id
                ? h(
                    'div',
                    {
                        class: 'underline decoration-dashed cursor-pointer',
                        style: 'padding: 8px;',
                        onClick: () => {
                            activePatient.value = row
                            showManualOperationsModal.value = true
                        },
                    },
                    row.operations?.length
                        ? h(NEllipsis, {tooltip: false}, row.operations.map(itm => `${itm.code}; `).join(''))
                        : 'Добавить'
                )
                : isSpecialStatus.value
                    ? (row.operations?.length
                        ? h('div', {style: 'padding: 8px;'}, h(NEllipsis, {tooltip: false}, row.operations.map(itm => `${itm.code}; `).join('')))
                        : h('div', {style: 'padding: 8px;'}, '-'))
                : row.operations?.length ?
                h(
                    NPopover,
                    {
                        placement: 'top',
                        arrow: false
                    },
                    {
                        trigger: () => h(
                            'div',
                            {
                                class: 'underline decoration-dashed cursor-pointer',
                                style: 'padding: 8px;',
                                onClick: () => {
                                    currentHistory.value = row.medical_history_id
                                    showOperationInfoModal.value = true
                                },
                            },
                            h(NEllipsis, {tooltip: false}, row.operations.map(itm => `${itm.code}; `).join(''))
                        ),
                        default: () => row.operations.map(itm =>`${itm.name}; `).join(''),
                    }
                ) : h('div', {style: 'padding: 8px;',}, '-'),
            cellProps: (rowData, rowIndex) => {
                const styles = ['--n-td-padding: 0;']
                return {
                    'style': styles
                }
            }
        }
        newColumns.push(operationColumn)
    }

    if (baseStatus.value === 'outcome') {
        const typeColumn = {
            title: 'Причина',
            key: 'outcome_type',
            align: 'left',
            titleAlign: 'left',
            ellipsis: {
                tooltip: true
            }
        }
        newColumns.push(typeColumn)
    }

        if (baseStatus.value === 'reanimation') {
        const indicatorColumn = {
            title: 'Состояние',
            key: 'reanimation_indicator',
            width: 120,
            minWidth: 100,
            maxWidth: 140,
            align: 'left',
            titleAlign: 'left',
            render: (row) => {
                const labelMap = {
                    stable: 'Стабильный',
                    moderate: 'Средней тяжести',
                    severe: 'Тяжелый',
                    critical: 'Критический',
                }
                const value = row.reanimation_indicator ? (labelMap[row.reanimation_indicator] ?? row.reanimation_indicator) : '-'

                if (canEditReanimationIndicator.value) {
                    return h(
                        'div',
                        {
                            class: 'inline-flex items-center gap-1',
                        },
                        [
                            h(
                                'div',
                                {
                                    class: 'underline decoration-dashed cursor-pointer',
                                    onClick: () => {
                                        activePatient.value = row
                                        showReanimationIndicatorModal.value = true
                                    },
                                },
                                value
                            ),
                            h(
                                NTooltip,
                                {},
                                {
                                    trigger: () => h(
                                        'div',
                                        {
                                            class: 'cursor-pointer inline-flex text-slate-500',
                                            onClick: () => {
                                                activePatient.value = row
                                                showReanimationIndicatorModal.value = true
                                            },
                                        },
                                        [h(NIcon, { size: 14 }, h(TbEdit))]
                                    ),
                                    default: () => 'Изменить состояние',
                                }
                            ),
                        ]
                    )
                }

                return h(
                    NTooltip,
                    {},
                    {
                        trigger: () => h(
                            'div',
                            {
                                class: 'inline-flex items-center gap-1 text-slate-500',
                            },
                            [
                                h('span', value),
                                h(NIcon, { size: 14 }, h(TbLock)),
                            ]
                        ),
                        default: () => 'Редактирование недоступно',
                    }
                )
            },
        }
        newColumns.push(indicatorColumn)
    }

    return newColumns
})

const isCursorOverTable = (e) => {
    const rect = tableRef.value.$el.getBoundingClientRect()
    return (
        e.clientX >= rect.left &&
        e.clientX <= rect.right &&
        e.clientY >= rect.top &&
        e.clientY <= rect.bottom
    )
}

const handleDragStart = (e, row) => {
    if (hasDisabledEdit.value) return

    // Устанавливаем данные о перетаскиваемом элементе
    e.dataTransfer.setData('application/json', JSON.stringify({
        row: row,
        fromStatus: props.status
    }))
    e.dataTransfer.effectAllowed = 'copy'

    const rowElement = e.target

    // Устанавливаем флаг перетаскивания в store
    reportStore.isDragActive = true

    // Эмитим событие для родителя
    emit('item-dragged', { row, fromStatus: props.status })

    // Добавляем класс для визуальной обратной связи
    e.target.classList.add('dragging')
}

const handleDragEnd = (e) => {
    if (hasDisabledEdit.value) return

    // Устанавливаем флаг перетаскивания в store
    reportStore.isDragActive = false

    if (e.target) {
        e.target.classList.remove('dragging')
    }
}

const handleDragOver = (e) => {
    if (hasDisabledEdit.value) return

    // console.log(e)

    e.preventDefault()
}

const handleDrop = (e) => {
    e.preventDefault()
    if (hasDisabledEdit.value) return
    if (props.isDraggableDrop === false) return

    // Проверяем, действительно ли курсор над таблицей
    if (!isCursorOverTable(e)) {
        return
    }

    try {
        const dragData = JSON.parse(e.dataTransfer.getData('application/json'))

        // Эмитим событие для родителя
        emit('item-dropped', {
            item: dragData.row,
            fromStatus: dragData.fromStatus,
            toStatus: props.status
        })

        latestDropItem.value = dragData.row
        showMoveModal.value = true
    } catch (error) {
        console.error('Drop error:', error)
    }
}

function rowProps(row) {
    const style = []
    const classes = []

    style.push(props.isDraggable ? 'cursor: grab;' : 'cursor: arrow;')

    if (props.accentIds.length) {
        if (props.accentIds.includes(row.id)) {
            style.push('--n-merged-td-color: #047857')
        }
    }

    return {
        draggable: props.isDraggable,
        style: style,
        onDragstart: (e) => {
            if (!props.isDraggable) return
            handleDragStart(e, row)
        },
        onDragend: (e) => {
            if (!props.isDraggableDrop) return
            handleDragEnd(e)
        },
        onDragover: (e) => {
            if (!props.isDraggableDrop) return
            handleDragOver(e)
        },
        onDrop: (e) => {
            if (!props.isDraggableDrop) return
            handleDrop(e)
        }
    }
}

const applySearch = useDebounceFn(async () => {
    await reportStore.setStatusSearch(props.status, searchValue.value)
}, 350)

const handlePageChange = async (page) => {
    await reportStore.setStatusPage(props.status, page)
}

watch(() => props.enabled, async (enabled) => {
    if (enabled) {
        await reportStore.ensureStatusLoaded(props.status)
    }
}, { immediate: true })

watch(() => reportStore.reportInfo?.dates, async () => {
    searchValue.value = ''
    if (props.enabled) {
        await reportStore.loadPatientsByStatus(props.status, { resetPage: true })
    }
}, { deep: true })
</script>

<template>
    <div>
        <NFlex vertical :size="8">
            <NInput
                v-model:value="searchValue"
                clearable
                size="small"
                placeholder="Поиск по ФИО или диагнозу"
                @update:value="applySearch"
            />

            <NSpin :show="statusState.loading">
                <NDataTable :columns="columns"
                            ref="tableRef"
                            :data="patientsData[status]"
                            size="small"
                            @drop="handleDrop"
                            @dragover="handleDragOver"
                            max-height="200"
                            min-height="200"
                            :row-props="rowProps"
                            :row-key="(row, index) => row.id"
                            class="text-sm!">
                </NDataTable>
            </NSpin>

            <NPagination
                v-if="showPagination"
                :page="statusState.page"
                :page-size="statusState.perPage"
                :item-count="statusState.total"
                :page-slot="7"
                @update:page="handlePageChange"
            />
        </NFlex>

        <MoveModalComment v-model:show="showMoveModal" :patient-id="latestDropItem?.id" />
        <OperationInfoModal v-model:show="showOperationInfoModal" :history-id="currentHistory" />
        <ManualPatientOutcomeModal v-model:show="showManualOutcomeModal" :patient="activePatient" />
        <ManualPatientLinkModal v-model:show="showManualLinkModal" :patient="activePatient" />
        <ManualPatientEditModal v-model:show="showManualEditModal" :patient="activePatient" :source-status="status" />
        <ManualPatientOperationsModal v-model:show="showManualOperationsModal" :patient="activePatient" :source-status="status" />
        <ReanimationIndicatorModal v-model:show="showReanimationIndicatorModal" :patient="activePatient" />
    </div>
</template>

<style scoped>
:deep(.n-data-table-th),
:deep(.n-data-table-td) {
    font-size: var(--n-font-size);
    text-align: left !important;
    white-space: nowrap !important;
}

:deep(.n-data-table-th__title),
:deep(.n-data-table-td__content) {
    justify-content: flex-start !important;
}
</style>
