<script setup>
import {NIcon, NText, NDataTable, NButton, NBadge, NTabs, NTabPane} from "naive-ui";
import {useReportStore} from "../../../Stores/report.js";
import {computed, h, onMounted, ref, watch} from "vue";
import { VueDraggableNext } from 'vue-draggable-next'
import {storeToRefs} from "pinia";
import {TbGripVertical, TbEye} from "vue-icons-plus/tb";
import MoveModalComment from "./MoveModalComment.vue";

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

const isFillableMode = computed(() => props.mode.toLowerCase() === 'fillable')
const isReadonlyMode = computed(() => props.mode.toLowerCase() === 'readonly')

const tableRef = ref()

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

const reportStore = useReportStore()
const {patientsData} = storeToRefs(reportStore)
// Получаем базовые колонки
const baseColumns = reportStore.getColumnsByKey(props.keys)
const data = ref([])
const isLoading = ref(true)
const showMoveModal = ref(false)
const latestDropItem = ref(null)
const activePatient = ref(null)

// Добавляем drag колонку если режим fillable
const columns = computed(() => {
    // if (!isFillableMode.value) return baseColumns

    const newColumns = []

    const dragColumn = {
        title: '',
        key: 'drag',
        width: 40,
        render: (row) => h(
            'div',
            {
                style: {
                    cursor: 'grab',
                    textAlign: 'center',
                    userSelect: 'none'
                }
            },
            [
                h(NIcon, {
                    depth: '2',
                    component: TbGripVertical
                }, [])
            ]
        )
    }

    const removeColumn = {
        title: '',
        key: 'remove',
        render: (row) => h(
            NButton,
            {
                text: true,
                onClick: () => {
                    axios.post('/api/report/observation/remove', {
                        id: row.id
                    }).then(async () => {
                        await fetchPatients()
                    })
                }
            },
            [
                'Снять с наблюдения'
            ]
        )
    }

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

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

    if (props.status === 'observation') {
        newColumns.push(expandColumn)
        newColumns.push(fillableColumn)
    }

    if (props.isDraggable) newColumns.push(dragColumn)
    newColumns.push(...baseColumns)
    if (props.isRemovable) newColumns.push(removeColumn)

    if (props.status === 'emergency' || props.status === 'plan') {
        const operationColumn = {
            title: 'Операции',
            key: 'operations',
            render: (row) => row.operations?.length ?
                h(
                    NText,
                    {},
                    [
                        row.operations.map(itm => {
                            return `${itm.code}; `
                        })
                    ]
                ) : h('div', {}, '-'),
            ellipsis: {
                tooltip: true
            }
        }
        newColumns.push(operationColumn)
    }

    if (props.status === 'outcome') {
        const typeColumn = {
            title: 'Причина',
            key: 'outcome_type',
            ellipsis: {
                tooltip: true
            }
        }
        newColumns.push(typeColumn)
    }

    return newColumns
})

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

    const rowElement = e.target

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

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

const handleDragEnd = (e) => {
    if (e.target) {
        e.target.classList.remove('dragging')
    }
}

const handleDragOver = (e) => {
    e.preventDefault()
}

const handleDrop = (e) => {
    e.preventDefault()

    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)
    }
}

const fetchPatients = async () => {
    isLoading.value = true
    const data = {
        status: props.status,
        startAt: reportStore.timestampCurrentRange[0],
        endAt: reportStore.timestampCurrentRange[1],
        departmentId: reportStore.reportInfo.department.department_id
    }
    await axios.post('/api/mis/patients', data).then((res) => {
        patientsData.value[props.status] = reportStore.addRowNumbers(res.data)
    }).finally(() => {
        isLoading.value = false
    })
}

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.isDraggable) return
            handleDragEnd(e)
        },
        onDragover: (e) => {
            if (!props.isDraggable) return
            handleDragOver(e)
        },
        onDrop: (e) => {
            if (!props.isDraggable) return
            handleDrop(e)
        }
    }
}

onMounted(async () => {
    await fetchPatients()
})
</script>

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

        <MoveModalComment v-model:show="showMoveModal" :patient-id="latestDropItem?.id" />
</template>

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