<template>
    <div class="list-container">
        <div class="aside">
            <div class="aside-header">
                <div class="aside-title">组织架构</div>
                <div class="aside-action">
                    <el-button type="text" @click="state.condition1.hiddenDisable = !state.condition1.hiddenDisable">
                        {{ state.condition1.hiddenDisable ? '隐藏' : '显示' }}禁用部门
                    </el-button>
                </div>
            </div>
            <div class="aside-body">
                <el-tree
                    :data="list"
                    default-expand-all
                    :expand-on-click-node="false"
                    highlight-current
                    node-key="id"
                    :props="{
                        label: 'name',
                        value: 'id',
                        children: 'childDepartment',
                        disabled: (data) => !data.isEnable,
                    }"
                    @current-change="(data) => handleChange(data.id)"
                >
                    <template #default="{ data, node }">
                        <div class="flex">
                            <div class="name">
                                {{ data.name }}
                            </div>
                            <div class="btns">
                                <el-button type="text" @click.stop="handleCreate(null, data)">
                                    <el-icon name="Plus" />
                                </el-button>
                                <template v-if="node.level > 1">
                                    <el-button type="text" @click.stop="handleCreate(data)">
                                        <el-icon name="Edit" />
                                    </el-button>
                                    <el-switch v-model="data.isEnable" @click.stop="handleEnabled(data)" />
                                </template>
                            </div>
                        </div>
                    </template>
                </el-tree>
                <el-dialog
                    v-model="formState.formVisible"
                    :title="(formState.form.id ? '编辑' : '新增') + '部门'"
                    width="300px"
                >
                    <el-form
                        ref="refsForm"
                        v-loading="formState.submitting"
                        label-width="100px"
                        :model="formState.form"
                        :rules="formState.rules"
                    >
                        <el-form-item label="上级组织" prop="parentId">
                            <el-cascader
                                v-model="formState.form.parentId"
                                :options="list"
                                :props="{
                                    label: 'name',
                                    value: 'id',
                                    children: 'childDepartment',
                                    disabled: (data) => !data.isEnable,
                                    checkStrictly: true,
                                    expandTrigger: 'hover',
                                    emitPath: false,
                                }"
                            />
                        </el-form-item>
                        <el-form-item label="组织名称" prop="name">
                            <el-input v-model="formState.form.name" maxlength="10" />
                        </el-form-item>
                    </el-form>
                    <template #footer>
                        <el-button @click="handleCancel">取消</el-button>
                        <el-button :loading="formState.submitting" type="primary" @click="handleSave">保存</el-button>
                    </template>
                </el-dialog>
            </div>
        </div>
        <div class="content">
            <el-tabs v-model="currentTab" type="border-card">
                <el-tab-pane label="员工" name="employee">
                    <table-list
                        ref="refsTable"
                        v-loading="loading2"
                        :code="employeeCode"
                        :config="employeeConfig"
                        :data="employeeList"
                        :operation="['search']"
                        @search="handleSearchEmployee"
                    >
                        <template #search>
                            <el-form inline :model="state.condition2">
                                <el-form-item label="姓名" prop="employeeName">
                                    <el-input v-model="state.condition2.employeeName" />
                                </el-form-item>
                                <el-form-item label="花名" prop="userName">
                                    <el-input v-model="state.condition2.userName" />
                                </el-form-item>
                                <el-form-item label="手机号" prop="phone">
                                    <el-input v-model="state.condition2.phone" />
                                </el-form-item>
                            </el-form>
                        </template>
                    </table-list>
                </el-tab-pane>
                <el-tab-pane label="角色" name="role">
                    <template v-if="state.condition2.departmentId">
                        <div class="role-list">
                            <div v-for="(item, index) in opts.system" :key="index" class="system">
                                <h3 class="system-header">
                                    {{ item.systemName }}
                                </h3>
                                <div class="flex">
                                    <el-tag
                                        v-for="(role, j) in store.getters['deptRole/roleList'](item.id)"
                                        :key="index + '' + j"
                                        closable
                                        size="large"
                                        @close="(delRoleId = role.id), (delVisible = true)"
                                    >
                                        {{ role.roleName }}
                                    </el-tag>
                                    <el-button @click="handleAddRole(item.id)">添加角色</el-button>
                                </div>
                            </div>
                        </div>
                    </template>
                    <div v-else class="empty">请选择组织架构</div>
                    <el-dialog v-model="roleVisible" title="添加角色">
                        <el-form v-loading="loading3">
                            <el-form-item>
                                <el-select
                                    v-model="checkedRole"
                                    :config="{
                                        label: 'roleName',
                                        value: 'id',
                                        disabled: (item) =>
                                            store.getters['deptRole/roleList'](currentSystemId).findIndex(
                                                (role) => role.id === item.id
                                            ) !== -1,
                                    }"
                                    multiple
                                    :opts="systemRoleList"
                                />
                            </el-form-item>
                        </el-form>
                        <template #footer>
                            <el-button @click="roleVisible = false">取消</el-button>
                            <el-button :loading="loading3" type="primary" @click="handleSaveRole">确定</el-button>
                        </template>
                    </el-dialog>
                    <el-dialog v-model="delVisible" title="提示">
                        <h3 style="display: flex; align-items: center">
                            <el-icon name="Warning" size="20" style="margin-right: 10px" />
                            确定删除组织中的角色吗？
                        </h3>
                        <p>删除角色后，组织下的员工将失去对应角色权限</p>
                        <el-checkbox
                            v-model="isDeleteDepartmentOfEmployeeRole"
                            label="仅删除组织角色，不删除组织下员工角色"
                        />
                        <template #footer>
                            <el-button @click="delVisible = false">取消</el-button>
                            <el-button :loading="loading4" type="primary" @click="handleDelRole">确定</el-button>
                        </template>
                    </el-dialog>
                </el-tab-pane>
            </el-tabs>
        </div>
    </div>
</template>

<script setup lang="jsx">
    import ElButton from '@/components/extra/ElButton.vue';
    import ElSwitch from '@/components/extra/ElSwitch.vue';
    const router = useRouter();
    const store = useStore();
    const { proxy } = getCurrentInstance();
    const opts = computed(() => store.state.dept.opts);
    if (!unref(opts).init) {
        store.dispatch('dept/load');
    }

    /* 查询树结构 */
    const loading = ref(false);
    const list = computed(() => _.cloneDeep(store.state.dept.list));
    const state = reactive({
        condition1: { hiddenDisable: false },
        condition2: { employeeName: null, userName: null, phone: null, departmentId: null },
        condition3: { departmentId: null },
    });
    const handleSearch = async () => {
        loading.value = true;
        await store.dispatch('dept/search');
        loading.value = false;
    };
    const handleChange = (id) => {
        state.condition2.departmentId = id;
        state.condition3.departmentId = id;
    };
    watch(
        () => state.condition1,
        (value) => {
            store.commit('dept/setCondition', _.cloneDeep(value));
            handleSearch();
        },
        { immediate: true, deep: true }
    );

    const currentTab = ref('employee');

    /* 员工 */
    const loading2 = ref(false);
    const refsTable = ref(null);
    const employeeCode = computed(() => store.state.deptEmployee.code);
    const employeeList = computed(() => _.cloneDeep(store.state.deptEmployee.list));
    const handleSearchEmployee = async () => {
        if (state.condition2.departmentId) {
            loading2.value = true;
            await store.dispatch('deptEmployee/search');
            loading2.value = false;
        } else {
            proxy.$message.error('请先选择部门');
        }
    };
    watch(
        () => state.condition2,
        (value) => {
            let search = value?.departmentId && value?.departmentId !== store.state.deptEmployee.condition.departmentId;
            store.commit('deptEmployee/setCondition', _.cloneDeep(value));
            if (search) {
                handleSearchEmployee();
            }
        },
        { immediate: true, deep: true }
    );
    const handleUpdateEmployee = (row) => {
        router.push({
            name: 'UpdateEmployee',
            params: {
                id: row.id,
            },
        });
    };
    const handleTransferEmployee = () => {};
    let employeeConfig = reactive({
        page: false,
        columns: [
            {
                label: '工号',
                prop: 'id',
                width: 100,
            },
            {
                label: '姓名',
                prop: 'employeeName',
                minWidth: 160,
            },
            {
                label: '花名',
                prop: 'userName',
                minWidth: 160,
            },
            {
                label: '手机号',
                prop: 'phone',
                minWidth: 160,
            },
            {
                label: '状态',
                width: 160,
                slots: {
                    default: ({ row }) => <ElSwitch v-model={row.isEnable} />,
                },
            },
            {
                label: '创建人',
                prop: 'createUserName',
                width: 180,
            },
            {
                label: '创建时间',
                prop: 'createTime',
                width: 180,
            },
            {
                label: '操作',
                width: 300,
                slots: {
                    default: ({ row }) => (
                        <div>
                            <ElButton type="text" onClick={() => handleUpdateEmployee(row)}>
                                编辑
                            </ElButton>
                            <ElButton type="text" onClick={() => handleTransferEmployee(row)}>
                                调动
                            </ElButton>
                        </div>
                    ),
                },
            },
        ],
    });

    /* 角色 */
    const loading3 = ref(false);
    const roleVisible = ref(false);
    const systemRoleList = ref([]);
    const currentSystemId = ref(null);
    const checkedRole = ref([]);
    const handleSearchRole = async () => {
        if (state.condition3.departmentId) {
            loading3.value = true;
            await store.dispatch('deptRole/search');
            loading3.value = false;
        } else {
            proxy.$message.error('请先选择部门');
        }
    };
    watch(
        () => state.condition3,
        (value) => {
            let search = value?.departmentId && value?.departmentId !== store.state.deptRole.condition.departmentId;
            store.commit('deptRole/setCondition', _.cloneDeep(value));
            if (search) {
                handleSearchRole();
            }
        },
        { immediate: true, deep: true }
    );
    const handleAddRole = async (id) => {
        loading3.value = true;
        roleVisible.value = true;
        currentSystemId.value = id;
        systemRoleList.value = await store.dispatch('deptRole/role', id);
        loading3.value = false;
    };
    const handleSaveRole = async () => {
        loading3.value = true;
        let res =
            !unref(checkedRole).length ||
            (await store.dispatch('deptRole/save', {
                departmentId: state.condition3.departmentId,
                isDistributionCurrentDepartmentEmployee: true,
                roleIds: unref(checkedRole),
            }));
        if (res) {
            roleVisible.value = false;
            handleSearchRole();
        }
        loading3.value = false;
    };
    const loading4 = ref(false);
    const delVisible = ref(false);
    const delRoleId = ref(null);
    const isDeleteDepartmentOfEmployeeRole = ref(false);
    const handleDelRole = async () => {
        loading4.value = true;
        await store.dispatch('deptRole/remove', {
            departmentId: state.condition3.departmentId,
            isDeleteDepartmentOfEmployeeRole: !unref(isDeleteDepartmentOfEmployeeRole),
            roleId: unref(delRoleId),
        });
        loading4.value = false;
        delVisible.value = false;
    };

    /* 表单 */
    const refsForm = ref(null);
    const formState = reactive({
        formVisible: false,
        submitting: false,
        form: {
            id: null,
            parentId: null,
            name: null,
        },
        rules: {
            name: [{ required: true, message: '请输入组织名称' }],
            parentId: [{ required: true, message: '请选择组织类型' }],
        },
    });
    const handleCreate = (row, parent) => {
        formState.formVisible = true;
        Object.assign(
            formState.form,
            row || {
                id: null,
                parentId: null,
                name: null,
                isEnable: true,
            }
        );
        if (parent) {
            formState.form.parentId = parent.id;
        }
    };
    const handleCancel = () => {
        formState.formVisible = false;
    };
    const handleEnabled = (row) => {
        store.dispatch('dept/enable', row);
    };
    const handleSave = async () => {
        formState.submitting = true;
        try {
            await proxy.$validate(refsForm);
            let data = _.cloneDeep(formState.form);
            await store.dispatch('dept/save', data);
            formState.formVisible = false;
        } catch (e) {
            console.info('取消保存', e);
        }
        formState.submitting = false;
    };
</script>

<style lang="less" scoped>
    .list-container {
        display: flex;
        flex-direction: row;
        .aside {
            margin-right: @layout-space;
            .aside-header {
                min-width: max-content;
                display: flex;
                justify-content: space-between;
                align-items: center;
                margin-bottom: @layout-space;
                .aside-title {
                    font-size: @layout-h3;
                }
                .aside-action {
                    margin-left: @layout-space;
                }
            }
            .aside-body {
                :deep(.el-tree) {
                    .flex {
                        width: 100%;
                        display: flex;
                        align-items: center;
                        justify-content: space-between;
                    }
                    .btns {
                        display: flex;
                        align-items: center;
                        margin-left: @layout-space-super;
                        .el-button {
                            position: relative;
                            top: 2px;
                            + .el-button {
                                margin-left: @layout-space-small;
                            }
                        }
                        .el-switch {
                            height: 100%;
                            transform: scale(0.6);
                        }
                    }
                }
            }
        }
        .content {
            width: 100%;
            flex-shrink: 1;
            display: flex;
            overflow: hidden;
            .el-tabs {
                width: 100%;
                height: 100%;
                display: flex;
                flex-direction: column;
                :deep(.el-tabs__content) {
                    height: 100%;
                    .el-tab-pane {
                        height: 100%;
                    }
                }
            }
            .common-list {
                width: 100%;
                overflow: hidden;
            }
            .role-list {
                .system {
                    & + .system {
                        margin-top: @layout-space;
                    }
                    .system-header {
                        margin-bottom: @layout-space;
                    }
                    .flex {
                        display: flex;
                        align-items: center;
                        flex-wrap: wrap;
                    }
                    .el-tag {
                        margin: @layout-space-small @layout-space @layout-space-small 0;
                    }
                }
            }
        }
    }
</style>
