<template>
    <el-dialog class="cn-operate-dialog" draggable width="500px" v-model="dialogVisible" :title="title">
        <el-form :model="form" class="form-one" label-width="auto" ref="formRef" :rules="rules">
            <el-form-item label="治理点名称" prop="governName">
                <el-input maxlength="32" show-word-limit clearable v-model.trim="form.governName"
                    placeholder="请输入治理点名称" />
            </el-form-item>
            <el-form-item label="治理类型" prop="governType">
                <el-select v-model="form.governType" placeholder="请选择治理类型" style="width: 100%">
                    <el-option label="稳态治理" value="harmonic" />
                    <el-option label="暂态治理" value="event" />
                </el-select>
            </el-form-item>
            <el-form-item label="治理方法" prop="governMethod">
                <el-input maxlength="32" show-word-limit clearable v-model="form.governMethod"
                    placeholder="例: 250A APF 或 100kVar SVG" />
            </el-form-item>
          
            <el-form-item label="治理前-监测点">
                <el-tree-select v-model="form.governBefore" :data="lineTreeData" clearable :props="treeProps" filterable
                    :filter-node-method="filterNode" check-strictly default-expand-all placeholder="请选择监测点"
                    style="width: 100%">
                    <template #default="{ data }">
                        <span>{{ data.name }}{{ getBoundSuffix(data) }}</span>
                    </template>
                </el-tree-select>
            </el-form-item>
            <el-form-item label="治理后-监测点">
                <el-tree-select v-model="form.governAfter" :data="lineTreeData" clearable :props="treeProps" filterable
                    :filter-node-method="filterNode" check-strictly default-expand-all placeholder="请选择监测点"
                    style="width: 100%">
                    <template #default="{ data }">
                        <span>{{ data.name }}{{ getBoundSuffix(data) }}</span>
                    </template>
                </el-tree-select>
            </el-form-item>
            <el-form-item label="排序" prop="sort">
                <el-input-number style="width: 100%" :min="0" v-model.number="form.sort" placeholder="请输入排序" />
            </el-form-item>
        </el-form>

        <template #footer>
            <span class="dialog-footer">
                <el-button @click="dialogVisible = false">取消</el-button>
                <el-button type="primary" @click="submit" :loading="loading">确定</el-button>
            </span>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, inject, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import TableStore from '@/utils/tableStore'
import { isLineTreeLeaf } from '@/components/tree/govern/lineTreeUtils'
import { createTreeFilterNode } from '@/components/tree/govern/treeFilterUtils'
import { getLineTree } from '@/api/cs-device-boot/csLedger'
import { saveGovernPlan, updateGovernPlan } from '@/api/cs-device-boot/sensitiveLoadMange'

const props = defineProps<{
    pid: string | number
}>()

const tableStore = inject('tableStore') as TableStore
const formRef = ref()
const dialogVisible = ref(false)
const title = ref('新增')
const loading = ref(false)
const lineTreeData = ref<any[]>([])
const filterNode = createTreeFilterNode()
/** 打开弹窗时传入的治理前/后监测点 id，未变更时不做绑定冲突校验 */
const originalGovernBefore = ref<any>(null)
const originalGovernAfter = ref<any>(null)

const treeProps = {
    value: 'id',
    label: 'name',
    children: 'children',
    disabled: 'disabled'
}

const form = reactive<any>({
    id: null,
    pid: null,
    governName: '',
    governMethod: '',
    governType: '',
    governBefore: '',
    governAfter: '',
    sort: 100
})

const isEmptyPoint = (val: any) => val === '' || val === null || val === undefined

const isSamePointId = (current: any, original: any) => {
    if (isEmptyPoint(current) && isEmptyPoint(original)) return true
    return String(current) === String(original)
}

const getGovernPointError = (): string => {
    const beforeEmpty = isEmptyPoint(form.governBefore)
    const afterEmpty = isEmptyPoint(form.governAfter)

    if (beforeEmpty && afterEmpty) return ''
    if (beforeEmpty) return '已选择治理后监测点，请同时选择治理前监测点'
    if (afterEmpty) return '已选择治理前监测点，请同时选择治理后监测点'
    if (form.governBefore === form.governAfter) return '治理前与治理后监测点不能相同'
    return ''
}

const rules = {
    governName: [{ required: true, message: '请输入治理点名称', trigger: 'blur' }],
    governMethod: [{ required: true, message: '请输入治理方法', trigger: 'blur' }],
    governType: [{ required: true, message: '请选择治理类型', trigger: 'change' }],
    sort: [{ required: true, message: '请输入排序', trigger: 'blur' }]
}

const getBoundSuffix = (node: any) => {
    if (node?.sensitiveUserName) {
        return `(已绑_${node.sensitiveUserName}_${node.governPlanName || ''})`
    }
    return ''
}

const findTreeNodeById = (nodes: any[], id: any): any => {
    for (const node of nodes) {
        if (node.id === id) return node
        if (node.children?.length) {
            const found = findTreeNodeById(node.children, id)
            if (found) return found
        }
    }
    return null
}

/** 监测点是否已被其他方案绑定（编辑时排除当前方案） */
const isPointBoundConflict = (node: any) => {
    if (!node?.sensitiveUserName) return false
    if (form.id && (node.governPlanId === form.id || node.governPlanName === form.governName)) {
        return false
    }
    return true
}

const getBoundPointError = (): string => {
    const messages: string[] = []

    if (
        !isEmptyPoint(form.governBefore) &&
        !isSamePointId(form.governBefore, originalGovernBefore.value)
    ) {
        const node = findTreeNodeById(lineTreeData.value, form.governBefore)
        if (node && isPointBoundConflict(node)) {
            messages.push(`治理前监测点「${node.name}」${getBoundSuffix(node)}`)
        }
    }
    if (
        !isEmptyPoint(form.governAfter) &&
        !isSamePointId(form.governAfter, originalGovernAfter.value)
    ) {
        const node = findTreeNodeById(lineTreeData.value, form.governAfter)
        if (node && isPointBoundConflict(node)) {
            messages.push(`治理后监测点「${node.name}」${getBoundSuffix(node)}`)
        }
    }

    return messages.length ? `${messages.join('；')}，请选择未绑定的监测点` : ''
}

const markNonLeafDisabled = (nodes: any[] = []) => {
    nodes.forEach(node => {
        node.disabled = !isLineTreeLeaf(node)
        if (node.children?.length) {
            markNonLeafDisabled(node.children)
        }
    })
}

const loadLineTree = () => {
    getLineTree({ type: 'engineering' }).then(res => {
        const data = JSON.parse(JSON.stringify(res.data || []))
        markNonLeafDisabled(data)
        lineTreeData.value = data
    })
}

const resetForm = () => {
    form.id = null
    form.pid = props.pid
    form.governName = ''
    form.governMethod = ''
    form.governType = ''
    form.governBefore = ''
    form.governAfter = ''
    form.sort = 100
    originalGovernBefore.value = null
    originalGovernAfter.value = null
}

const open = (text: string, data?: anyObj) => {
    loadLineTree()
    formRef.value?.resetFields()
    title.value = text
    dialogVisible.value = true
    resetForm()
    if (data) {
        form.id = data.id
        form.governName = data.governName ?? ''
        form.governMethod = data.governMethod ?? ''
        form.governType = data.governType ?? ''
        form.governBefore = data.governBeforeId ?? data.governBefore ?? ''
        form.governAfter = data.governAfterId ?? data.governAfter ?? ''
        form.sort = data.sort ?? 100
        originalGovernBefore.value = form.governBefore
        originalGovernAfter.value = form.governAfter
    }
}

const submit = () => {
    const pointError = getGovernPointError()
    if (pointError) {
        ElMessage.warning(pointError)
        return
    }

    const boundError = getBoundPointError()
    if (boundError) {
        ElMessage.warning(boundError)
        return
    }

    formRef.value.validate(async (valid: boolean) => {
        if (!valid) return
        const payload = {
            id: form.id,
            pid: props.pid,
            governName: form.governName,
            governMethod: form.governMethod,
            governType: form.governType,
            governBefore: form.governBefore,
            governAfter: form.governAfter,
            sort: form.sort
        }
        loading.value = true
        if (form.id) {
            await updateGovernPlan(payload)
        } else {
            await saveGovernPlan(payload)
        }
        ElMessage.success('操作成功')
        tableStore.index()
        dialogVisible.value = false
        loading.value = false
    })
}

onMounted(() => {

})

defineExpose({ open })
</script>
