<template>
    <div class="person-picker">
        <el-row :gutter="20" style="padding-bottom: 30px">
            <el-col :span="16">
                <!-- Tabs 切换 -->
                <el-tabs v-model="activeTab" @tab-change="handleTabChange">
                    <el-tab-pane label="人员" name="person">
                        <template #label>
                            <span>人员</span>
                            <el-badge
                                v-if="selectedPersonCount > 0"
                                :value="selectedPersonCount"
                                class="tab-badge"
                            />
                        </template>
                    </el-tab-pane>
                    <el-tab-pane label="分组" name="group">
                        <template #label>
                            <span>分组</span>
                            <el-badge
                                v-if="selectedGroupCount > 0"
                                :value="selectedGroupCount"
                                class="tab-badge"
                            />
                        </template>
                    </el-tab-pane>
                </el-tabs>

                <!-- 搜索栏 -->
                <div class="search-bar">
                    <el-input
                        v-if="activeTab === 'person'"
                        v-model.trim="searchKeyword"
                        placeholder="输入关键字"
                        clearable
                        prefix-icon="Search"
                        @input="handleSearch"
                    />
                    <el-input
                        v-else
                        v-model.trim="groupSearchKeyword"
                        placeholder="输入关键字"
                        clearable
                        prefix-icon="Search"
                        @input="handleGroupSearch"
                    />
                </div>

                <!-- 人员表格 -->
                <el-table
                    v-if="activeTab === 'person'"
                    border
                    ref="personTableRef"
                    :data="filteredPersonList"
                    height="400"
                    @selection-change="onPersonSelectionChange"
                >
                    <el-table-column type="selection" width="50" align="center" />
                    <el-table-column
                        show-overflow-tooltip
                        prop="orgName"
                        label="人员所属"
                        align="center"
                    />
                    <el-table-column
                        show-overflow-tooltip
                        prop="workerName"
                        label="姓名"
                        width="120"
                        align="center"
                    />
                    <el-table-column show-overflow-tooltip prop="sex" label="性别" align="center">
                        <template #default="{ row }">
                            {{ row.sex == 1 ? '男' : '女' }}
                        </template>
                    </el-table-column>
                    <el-table-column
                        show-overflow-tooltip
                        prop="phone"
                        label="电话"
                        align="center"
                    />
                </el-table>

                <!-- 分组表格 -->
                <el-table
                    v-else
                    border
                    ref="groupTableRef"
                    :data="filteredGroupList"
                    height="400"
                    @selection-change="onGroupSelectionChange"
                >
                    <el-table-column type="selection" width="50" align="center" />
                    <el-table-column
                        show-overflow-tooltip
                        prop="groupName"
                        label="分组名称"
                        align="center"
                    />
                </el-table>
            </el-col>

            <!-- 右侧已选内容 -->
            <el-col :span="8">
                <div class="selected-persons">
                    <div class="selected-header">
                        <span>{{ activeTab === 'person' ? '已选人员' : '已选分组人员' }}</span>
                        <el-button
                            type="text"
                            size="small"
                            @click="handleClearAll"
                            :disabled="
                                activeTab === 'person'
                                    ? directSelectedPersonIds.length === 0
                                    : selectedGroupIds.length === 0
                            "
                        >
                            清空
                        </el-button>
                    </div>
                    <div class="selected-list">
                        <!-- 人员tab：显示已选人员 -->
                        <template v-if="activeTab === 'person'">
                            <div
                                v-for="person in directSelectedPersons"
                                :key="person.id"
                                class="selected-item"
                            >
                                <span>{{ person.workerName }}</span>
                                <el-icon class="remove-icon" @click="handleRemovePerson(person.id)">
                                    <Close />
                                </el-icon>
                            </div>
                            <div v-if="directSelectedPersons.length === 0" class="empty-tip">
                                暂未选择人员
                            </div>
                        </template>
                        <!-- 分组tab：显示已选分组的所有人员 -->
                        <template v-else>
                            <div
                                v-for="person in groupSelectedPersons"
                                :key="`${person.groupId}-${person.id}`"
                                class="selected-item"
                            >
                                <span>{{ person.workerName }}</span>
                            </div>
                            <div v-if="groupSelectedPersons.length === 0" class="empty-tip">
                                暂未选择分组
                            </div>
                        </template>
                    </div>
                </div>
            </el-col>
        </el-row>
    </div>
</template>

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

const props = defineProps({
    modelValue: {
        type: Array,
        default: () => [],
    },
    groupList: {
        type: Array,
        default: () => [],
    },
})

const emit = defineEmits(['update:modelValue', 'update:groupList', 'confirm'])

const activeTab = ref('person')
const searchKeyword = ref('')
const groupSearchKeyword = ref('')
const personTableRef = ref(null)
const groupTableRef = ref(null)

// 数据列表
const personList = ref([])
const groupList = ref([])

// 直接选择的人员ID列表（只在人员tab中选择的）
const directSelectedPersonIds = ref([])

// 选中的分组ID列表
const selectedGroupIds = ref([])

// 标志位：是否正在同步选中状态
const isSyncing = ref(false)

// 标志位：是否已经初始化过（用于区分是用户操作还是外部数据变化）
const isInitialized = ref(false)

// 过滤后的人员列表
const filteredPersonList = computed(() => {
    if (!searchKeyword.value) {
        return personList.value
    }
    const keyword = searchKeyword.value.toLowerCase()
    return personList.value.filter((item) => {
        const orgName = (item.orgName || '').toLowerCase()
        const workerName = (item.workerName || '').toLowerCase()
        return orgName.includes(keyword) || workerName.includes(keyword)
    })
})

// 过滤后的分组列表
const filteredGroupList = computed(() => {
    if (!groupSearchKeyword.value) {
        return groupList.value
    }
    const keyword = groupSearchKeyword.value.toLowerCase()
    return groupList.value.filter((item) => {
        const groupName = (item.groupName || item.workerName || '').toLowerCase()
        return groupName.includes(keyword)
    })
})

// 选中的分组数量
const selectedGroupCount = computed(() => selectedGroupIds.value.length)

// 直接选择的人员列表（用于人员tab显示）
const directSelectedPersons = computed(() => {
    return directSelectedPersonIds.value
        .map((personId) => {
            const person = personList.value.find((p) => p.id === personId)
            if (person) {
                return {
                    id: person.id,
                    workerName: person.workerName,
                    orgName: person.orgName,
                    sex: person.sex,
                    phone: person.phone,
                }
            }
            return null
        })
        .filter(Boolean)
})

// 从分组中选择的人员列表（用于分组tab显示，不去重）
const groupSelectedPersons = computed(() => {
    const persons = []
    selectedGroupIds.value.forEach((groupId) => {
        const group = groupList.value.find((g) => g.id === groupId)
        if (group && group.workerList && Array.isArray(group.workerList)) {
            group.workerList.forEach((worker) => {
                if (worker && worker.id) {
                    persons.push({
                        id: worker.id,
                        groupId: groupId,
                        workerName: worker.workerName || worker.name || '',
                        orgName: worker.orgName || '',
                        sex: worker.sex,
                        phone: worker.phone || '',
                    })
                }
            })
        }
    })
    return persons
})

// 直接选择的人员数量
const selectedPersonCount = computed(() => {
    return directSelectedPersonIds.value.length
})

// Tab切换
const handleTabChange = (tabName) => {
    searchKeyword.value = ''
    groupSearchKeyword.value = ''
    // 切换tab时，只同步当前tab的选中状态，不清空已选项
    nextTick(() => {
        if (tabName === 'person') {
            syncPersonTableSelection()
        } else {
            syncGroupTableSelection()
        }
    })
}

// 搜索处理
const handleSearch = () => {
    nextTick(() => {
        syncPersonTableSelection()
    })
}

const handleGroupSearch = () => {
    nextTick(() => {
        syncGroupTableSelection()
    })
}

// 人员选择变化
const onPersonSelectionChange = (selection) => {
    if (isSyncing.value) {
        return
    }

    // 获取当前过滤后可见的人员ID集合
    const visiblePersonIds = new Set(filteredPersonList.value.map((item) => item.id))

    // 获取当前选中的可见人员ID集合
    const selectedVisibleIds = new Set(selection.map((item) => item.id))

    // 保留不在当前过滤列表中的已选人员（这些人员被搜索过滤掉了，但应该保留）
    const preservedIds = directSelectedPersonIds.value.filter((id) => !visiblePersonIds.has(id))

    // 合并保留的ID和当前选中的可见ID
    directSelectedPersonIds.value = [...preservedIds, ...selectedVisibleIds]

    // 触发更新，合并所有选中的人员
    updateSelectedPersons()
}

// 更新选中的内容
const updateSelectedPersons = () => {
    // 标记为已初始化，避免watch反向同步
    isInitialized.value = true

    // 更新人员列表
    const persons = directSelectedPersonIds.value
        .map((personId) => {
            const person = personList.value.find((p) => p.id === personId)
            if (person) {
                return {
                    id: person.id,
                    workerName: person.workerName,
                    orgName: person.orgName,
                    sex: person.sex,
                    phone: person.phone,
                }
            }
            return null
        })
        .filter(Boolean)
    emit('update:modelValue', persons)

    // 更新分组列表
    const groups = selectedGroupIds.value
        .map((groupId) => {
            const group = groupList.value.find((g) => g.id === groupId)
            return group ? { id: group.id, groupName: group.groupName || group.workerName } : null
        })
        .filter(Boolean)
    emit('update:groupList', groups)
}

// 分组选择变化
const onGroupSelectionChange = (selection) => {
    if (isSyncing.value) {
        return
    }

    // 获取当前过滤后可见的分组ID集合
    const visibleGroupIds = new Set(filteredGroupList.value.map((item) => item.id))

    // 获取当前选中的可见分组ID集合
    const selectedVisibleIds = new Set(selection.map((group) => group.id))

    // 保留不在当前过滤列表中的已选分组（这些分组被搜索过滤掉了，但应该保留）
    const preservedIds = selectedGroupIds.value.filter((id) => !visibleGroupIds.has(id))

    // 合并保留的ID和当前选中的可见ID
    selectedGroupIds.value = [...preservedIds, ...selectedVisibleIds]

    // 触发更新，传递分组列表
    updateSelectedPersons()
}

// 同步人员表格选中状态
const syncPersonTableSelection = () => {
    if (!personTableRef.value || directSelectedPersonIds.value.length === 0) {
        if (personTableRef.value) {
            isSyncing.value = true
            personTableRef.value.clearSelection()
            nextTick(() => {
                isSyncing.value = false
            })
        }
        return
    }

    isSyncing.value = true
    const selectedIds = new Set(directSelectedPersonIds.value.map((id) => Number(id)))

    nextTick(() => {
        personTableRef.value.clearSelection()
        filteredPersonList.value.forEach((row) => {
            const rowId = Number(row.id)
            if (selectedIds.has(rowId)) {
                personTableRef.value.toggleRowSelection(row, true)
            }
        })
        nextTick(() => {
            isSyncing.value = false
        })
    })
}

// 同步分组表格选中状态
const syncGroupTableSelection = () => {
    if (!groupTableRef.value || selectedGroupIds.value.length === 0) {
        if (groupTableRef.value) {
            isSyncing.value = true
            groupTableRef.value.clearSelection()
            nextTick(() => {
                isSyncing.value = false
            })
        }
        return
    }

    isSyncing.value = true
    const selectedIds = new Set(selectedGroupIds.value.map((id) => Number(id)))

    nextTick(() => {
        groupTableRef.value.clearSelection()
        filteredGroupList.value.forEach((row) => {
            const rowId = Number(row.id)
            if (selectedIds.has(rowId)) {
                groupTableRef.value.toggleRowSelection(row, true)
            }
        })
        nextTick(() => {
            isSyncing.value = false
        })
    })
}

// 移除单个人员（仅用于人员tab）
const handleRemovePerson = (personId) => {
    directSelectedPersonIds.value = directSelectedPersonIds.value.filter((id) => id !== personId)
    updateSelectedPersons()
    // 同步人员表格
    nextTick(() => {
        syncPersonTableSelection()
    })
}

// 清空所有选择
const handleClearAll = () => {
    isSyncing.value = true
    if (activeTab.value === 'person') {
        directSelectedPersonIds.value = []
        if (personTableRef.value) {
            personTableRef.value.clearSelection()
        }
    } else {
        selectedGroupIds.value = []
        if (groupTableRef.value) {
            groupTableRef.value.clearSelection()
        }
    }
    updateSelectedPersons()
    nextTick(() => {
        isSyncing.value = false
    })
}

// 获取人员列表
const getPersonList = async () => {
    try {
        const result = await getAllPersonAPI()
        if (result.code === 200 && result.rows) {
            personList.value = result.rows || []
            nextTick(() => {
                syncPersonTableSelection()
            })
        }
    } catch (error) {
        console.error('获取人员列表失败:', error)
    }
}

// 获取分组列表
const getGroupList = async () => {
    try {
        const result = await getAllGroupAPI()
        if (result.code === 200 && result.rows) {
            // 统一分组数据格式：将 workerName 转换为 groupName
            groupList.value = (result.rows || []).map((group) => ({
                ...group,
                groupName: group.groupName || group.workerName || '',
            }))
            nextTick(() => {
                syncGroupTableSelection()
            })
        }
    } catch (error) {
        console.error('获取分组列表失败:', error)
    }
}

// 监听 modelValue 变化
watch(
    () => props.modelValue,
    (newVal) => {
        if (!newVal || newVal.length === 0) {
            // 如果外部数据为空，且内部状态也为空，则不需要处理
            if (directSelectedPersonIds.value.length === 0) {
                return
            }
            // 如果外部数据为空，但内部状态有值，且未初始化过，则清空
            if (!isInitialized.value) {
                directSelectedPersonIds.value = []
            }
            return
        }

        // 获取外部传入的人员ID列表
        const externalPersonIds = newVal.map((p) => p.id).filter(Boolean)

        // 如果外部数据与内部状态一致，不需要更新
        const currentIds = new Set(directSelectedPersonIds.value.map((id) => Number(id)))
        const externalIds = new Set(externalPersonIds.map((id) => Number(id)))
        const isEqual =
            currentIds.size === externalIds.size &&
            [...currentIds].every((id) => externalIds.has(id))

        if (isEqual && isInitialized.value) {
            return
        }

        // 更新选中的人员ID（仅在未初始化或外部数据变化时）
        if (!isInitialized.value || !isEqual) {
            directSelectedPersonIds.value = externalPersonIds
            isInitialized.value = true

            if (activeTab.value === 'person') {
                nextTick(() => {
                    syncPersonTableSelection()
                })
            }
        }
    },
    { deep: true, immediate: true },
)

// 监听 groupList 变化
watch(
    () => props.groupList,
    (newVal) => {
        if (!newVal || newVal.length === 0) {
            // 如果外部数据为空，且内部状态也为空，则不需要处理
            if (selectedGroupIds.value.length === 0) {
                return
            }
            // 如果外部数据为空，但内部状态有值，且未初始化过，则清空
            if (!isInitialized.value) {
                selectedGroupIds.value = []
            }
            return
        }

        // 获取外部传入的分组ID列表
        const externalGroupIds = newVal.map((g) => g.id).filter(Boolean)

        // 如果外部数据与内部状态一致，不需要更新
        const currentIds = new Set(selectedGroupIds.value.map((id) => Number(id)))
        const externalIds = new Set(externalGroupIds.map((id) => Number(id)))
        const isEqual =
            currentIds.size === externalIds.size &&
            [...currentIds].every((id) => externalIds.has(id))

        if (isEqual && isInitialized.value) {
            return
        }

        // 更新选中的分组ID（仅在未初始化或外部数据变化时）
        if (!isInitialized.value || !isEqual) {
            selectedGroupIds.value = externalGroupIds
            isInitialized.value = true

            if (activeTab.value === 'group') {
                nextTick(() => {
                    syncGroupTableSelection()
                })
            }
        }
    },
    { deep: true, immediate: true },
)

onMounted(() => {
    // 重置初始化标志，确保能正确同步外部传入的数据
    isInitialized.value = false
    getPersonList()
    getGroupList()
})
</script>

<style lang="scss" scoped>
.person-picker {
    .search-bar {
        margin-bottom: 10px;
    }

    .selected-persons {
        border: 1px solid #dcdfe6;
        border-radius: 4px;
        background: #fff;
        height: 100%;
        display: flex;
        flex-direction: column;

        .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: 400px;

            .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;
            }
        }
    }

    :deep(.el-tabs) {
        margin-bottom: 10px;

        .el-tabs__header {
            margin-bottom: 10px;
        }

        .tab-badge {
            margin-left: 8px;
        }
    }
}
</style>

