<template>
    <el-form
        size="large"
        label-width="auto"
        :model="formData"
        ref="formRef"
        :rules="rules"
        class="add-and-edit-form"
    >
        <el-form-item label="分组名称" prop="groupName">
            <el-input
                clearable
                maxlength="50"
                show-word-limit
                placeholder="请输入分组名称"
                v-model.trim="formData.groupName"
            />
        </el-form-item>

        <el-form-item label="选择组员" prop="workerList" class="member-select-item">
            <div class="member-select-container">
                <!-- 左侧：可选人员列表 -->
                <div class="member-list-left">
                    <div class="search-bar">
                        <el-row :gutter="10">
                            <el-col :span="12">
                                <el-input
                                    v-model="searchDept"
                                    placeholder="输入部门名称"
                                    clearable
                                    prefix-icon="Search"
                                />
                            </el-col>
                            <el-col :span="12">
                                <el-input
                                    v-model="searchName"
                                    placeholder="输入人员姓名"
                                    clearable
                                    prefix-icon="Search"
                                />
                            </el-col>
                        </el-row>
                    </div>
                    <div class="table-container">
                        <el-table
                            ref="personTableRef"
                            :data="filteredPersonList"
                            height="300"
                            @selection-change="handleSelectionChange"
                        >
                            <el-table-column type="selection" width="55" />
                            <el-table-column prop="orgName" label="人员所属" width="150" />
                            <el-table-column prop="workerName" label="姓名" width="120" />
                            <el-table-column prop="sex" label="性别" width="80">
                                <template #default="{ row }">
                                    {{ row.sex == 1 ? '男' : '女' }}
                                </template>
                            </el-table-column>
                            <el-table-column prop="phone" label="电话" />
                        </el-table>
                    </div>
                </div>

                <!-- 右侧：已选人员列表 -->
                <div class="member-list-right">
                    <div class="selected-header">
                        <span>已选人员</span>
                        <el-button
                            type="text"
                            size="small"
                            @click="handleClearAll"
                            :disabled="selectedMembers.length === 0"
                        >
                            清空
                        </el-button>
                    </div>
                    <div class="selected-list">
                        <div
                            v-for="member in selectedMembers"
                            :key="member.id"
                            class="selected-item"
                        >
                            <span>{{ member.workerName }}</span>
                            <el-icon class="remove-icon" @click="handleRemoveMember(member.id)">
                                <Close />
                            </el-icon>
                        </div>
                        <div v-if="selectedMembers.length === 0" class="empty-tip">
                            暂无已选人员
                        </div>
                    </div>
                </div>
            </div>
        </el-form-item>

        <el-form-item label="备注" prop="remark">
            <el-input
                type="textarea"
                :rows="3"
                maxlength="200"
                show-word-limit
                placeholder="请输入备注"
                v-model.trim="formData.remark"
            />
        </el-form-item>
    </el-form>
</template>

<script setup name="AddAndEditForm">
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import { getAllPersonAPI } from '@/api/personManage/person.js'
import { Close } from '@element-plus/icons-vue'

const props = defineProps({
    formData: {
        type: Object,
        default: () => ({}),
    },
})

const formRef = ref(null)
const personTableRef = ref(null)
const searchDept = ref('') // 部门搜索关键词
const searchName = ref('') // 姓名搜索关键词
const personList = ref([])
const selectedPersonList = ref([])
// 标志位：是否正在同步选中状态，防止循环触发
const isSyncing = ref(false)

// 表单验证规则
const rules = {
    groupName: [{ required: true, message: '请输入分组名称', trigger: 'blur' }],
    workerList: [
        {
            required: true,
            message: '请至少选择一个组员',
            trigger: 'change',
            validator: (rule, value, callback) => {
                if (!value || value.length === 0) {
                    callback(new Error('请至少选择一个组员'))
                } else {
                    callback()
                }
            },
        },
    ],
}

// 过滤后的人员列表
const filteredPersonList = computed(() => {
    let filtered = personList.value

    // 部门过滤
    if (searchDept.value) {
        const deptKeyword = searchDept.value.toLowerCase()
        filtered = filtered.filter((item) => {
            const org = (item.orgName || '').toLowerCase()
            return org.includes(deptKeyword)
        })
    }

    // 姓名过滤
    if (searchName.value) {
        const nameKeyword = searchName.value.toLowerCase()
        filtered = filtered.filter((item) => {
            const name = (item.workerName || '').toLowerCase()
            return name.includes(nameKeyword)
        })
    }

    return filtered
})

// 已选人员列表
const selectedMembers = computed(() => {
    if (!props.formData.workerList || props.formData.workerList.length === 0) {
        return []
    }
    return personList.value.filter((item) => props.formData.workerList.includes(item.id))
})

// 获取人员列表
const getPersonList = async () => {
    try {
        const result = await getAllPersonAPI()

        if (result.code === 200) {
            // 处理返回数据，可能是 result.rows 或 result.data 或直接是数组
            const data = result.rows || result.data || result || []
            personList.value = data.map((item) => ({
                id: item.id,
                workerName: item.workerName,
                orgName: item.orgName,
                sex: item.sex,
                phone: item.phone,
            }))
            // 人员列表加载完成后，watch 监听器会自动处理选中状态同步
            // 不需要在这里手动调用 syncTableSelection，避免循环触发
        }
    } catch (error) {
        console.error('获取人员列表失败:', error)
        // 重置同步标志，防止卡死
        isSyncing.value = false
    }
}

// 监听formData.workerList变化，同步表格选中状态
watch(
    () => props.formData.workerList,
    (newVal, oldVal) => {
        // 如果正在同步中，跳过，防止循环触发
        if (isSyncing.value) {
            return
        }
        // 只有当人员列表已加载且workerList有值时才同步
        if (personList.value.length > 0 && newVal && newVal.length > 0) {
            // 检查值是否真的变化了（避免不必要的同步）
            const newValStr = JSON.stringify(newVal.sort())
            const oldValStr = oldVal ? JSON.stringify(oldVal.sort()) : ''
            if (newValStr !== oldValStr) {
                nextTick(() => {
                    syncTableSelection()
                })
            }
        }
    },
    { deep: true },
)

// 监听人员列表加载完成，同步选中状态
watch(
    () => personList.value.length,
    (newLength, oldLength) => {
        // 如果正在同步中，跳过
        if (isSyncing.value) {
            return
        }
        // 当人员列表从0变为有数据时，如果有已选人员，同步选中状态
        if (
            oldLength === 0 &&
            newLength > 0 &&
            props.formData.workerList &&
            props.formData.workerList.length > 0
        ) {
            nextTick(() => {
                syncTableSelection()
            })
        }
    },
)

// 同步表格选中状态
const syncTableSelection = () => {
    if (
        !personTableRef.value ||
        !props.formData.workerList ||
        props.formData.workerList.length === 0
    ) {
        // 如果没有选中项，清空所有选中状态
        if (personTableRef.value) {
            isSyncing.value = true
            personTableRef.value.clearSelection()
            // 延迟重置标志位，确保 clearSelection 触发的事件被忽略
            nextTick(() => {
                isSyncing.value = false
            })
        }
        return
    }

    // 设置同步标志，防止触发 watch 和 handleSelectionChange
    isSyncing.value = true

    // 确保 workerList 是数字数组
    const selectedIds = props.formData.workerList.map((id) => Number(id))

    nextTick(() => {
        // 先清空所有选中状态（这会触发 selection-change，但由于 isSyncing=true，会被忽略）
        personTableRef.value.clearSelection()

        // 遍历当前过滤后的人员列表，只选中在当前过滤结果中的已选人员
        // 这样可以确保即使搜索条件变化，已选中的行也能正确显示
        filteredPersonList.value.forEach((row) => {
            const rowId = Number(row.id)
            if (selectedIds.includes(rowId)) {
                personTableRef.value.toggleRowSelection(row, true)
            }
        })

        // 同步完成后，延迟重置标志位，确保所有事件处理完成
        nextTick(() => {
            nextTick(() => {
                isSyncing.value = false
            })
        })
    })
}

// 表格选择变化
const handleSelectionChange = (selection) => {
    // 如果正在同步中，跳过，防止循环触发和误删已选项
    if (isSyncing.value) {
        return
    }

    selectedPersonList.value = selection
    // 更新表单数据中的workerList
    // 保留所有已选中的ID（包括不在当前过滤列表中的）
    const allSelectedIds = new Set(props.formData.workerList || [])

    // 获取当前过滤列表中所有人员的ID
    const currentFilteredIds = new Set(filteredPersonList.value.map((item) => item.id))

    // 移除当前过滤列表中未选中的项（只处理当前可见的过滤结果）
    // 注意：不在当前过滤结果中的已选项不会被删除，因为它们不在 currentFilteredIds 中
    currentFilteredIds.forEach((id) => {
        if (!selection.find((s) => s.id === id)) {
            allSelectedIds.delete(id)
        }
    })

    // 添加当前过滤列表中选中的项
    selection.forEach((item) => {
        allSelectedIds.add(item.id)
    })

    // 设置同步标志，防止触发 watch
    isSyncing.value = true
    props.formData.workerList = Array.from(allSelectedIds)
    nextTick(() => {
        isSyncing.value = false
    })
}

// 移除单个已选人员
const handleRemoveMember = (memberId) => {
    if (!props.formData.workerList) {
        props.formData.workerList = []
        return
    }
    // 设置同步标志，防止触发 watch
    isSyncing.value = true
    props.formData.workerList = props.formData.workerList.filter((id) => id !== memberId)
    nextTick(() => {
        // 同步更新表格选中状态
        syncTableSelection()
    })
}

// 清空所有已选人员
const handleClearAll = () => {
    // 设置同步标志，防止触发 watch
    isSyncing.value = true
    props.formData.workerList = []
    if (personTableRef.value) {
        personTableRef.value.clearSelection()
    }
    nextTick(() => {
        isSyncing.value = false
    })
}

// 监听搜索关键词变化，重新同步选中状态
watch([() => searchDept.value, () => searchName.value], () => {
    // 搜索关键词变化时，需要重新同步选中状态
    // 因为表格数据源变化可能导致选中状态丢失
    if (
        personList.value.length > 0 &&
        props.formData.workerList &&
        props.formData.workerList.length > 0
    ) {
        // 设置同步标志，防止 handleSelectionChange 误删已选项
        isSyncing.value = true

        // 延迟一下，确保表格数据更新完成
        nextTick(() => {
            nextTick(() => {
                syncTableSelection()
            })
        })
    }
})

onMounted(() => {
    getPersonList()
})

// 暴露校验方法和重置方法给父组件
defineExpose({
    validate: () => formRef.value.validate(),
    resetFields: () => formRef.value.resetFields(),
    clearValidate: () => formRef.value.clearValidate(),
})
</script>

<style lang="scss" scoped>
.add-and-edit-form {
    padding: 10px 20px;

    .member-select-item {
        :deep(.el-form-item__content) {
            width: 100%;
        }
    }

    .member-select-container {
        display: flex;
        gap: 20px;
        width: 100%;
        border: 1px solid #dcdfe6;
        border-radius: 4px;
        padding: 15px;
        background: #fafafa;
    }

    .member-list-left {
        flex: 1;
        display: flex;
        flex-direction: column;

        .search-bar {
            margin-bottom: 10px;

            :deep(.el-row) {
                width: 100%;
            }

            :deep(.el-col) {
                padding: 0;
            }
        }

        .table-container {
            flex: 1;
            border: 1px solid #dcdfe6;
            border-radius: 4px;
            overflow: hidden;
            background: #fff;
        }
    }

    .member-list-right {
        width: 200px;
        display: flex;
        flex-direction: column;
        border: 1px solid #dcdfe6;
        border-radius: 4px;
        background: #fff;

        .selected-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px 15px;
            border-bottom: 1px solid #dcdfe6;
            font-weight: 500;
        }

        .selected-list {
            flex: 1;
            padding: 10px;
            overflow-y: auto;
            max-height: 300px;

            .selected-item {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 2px 10px;
                margin-bottom: 5px;
                background: #f0f9ff;
                border: 1px solid #b3d8ff;
                border-radius: 4px;
                cursor: pointer;
                transition: all 0.3s;

                &:hover {
                    background: #e1f3ff;
                    border-color: #409eff;
                }

                .remove-icon {
                    color: #909399;
                    cursor: pointer;
                    font-size: 16px;

                    &:hover {
                        color: #f56c6c;
                    }
                }
            }

            .empty-tip {
                text-align: center;
                color: #909399;
                padding: 20px;
            }
        }
    }
}
</style>

