package org.xyzh.system.department.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.dto.dept.TbSysDept;
import org.xyzh.common.dto.dept.TbSysDeptRole;
import org.xyzh.common.dto.role.TbSysRole;
import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.utils.IDUtils;
import org.xyzh.system.department.service.SysDepartmentService;
import org.xyzh.system.mapper.DepartmentMapper;
import org.xyzh.system.mapper.DeptRoleMapper;
import org.xyzh.system.utils.LoginUtil;

import java.util.List;
import java.util.ArrayList;
import java.util.Date;

/**
 * @description SysDepartmentServiceImpl.java文件描述 系统部门服务实现类
 * @filename SysDepartmentServiceImpl.java
 * @author yslg
 * @copyright xyzh
 * @since 2025-09-28
 */
@Service
public class SysDepartmentServiceImpl implements SysDepartmentService {
    
    private static final Logger logger = LoggerFactory.getLogger(SysDepartmentServiceImpl.class);
    
    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private DeptRoleMapper deptRoleMapper;

    @Override
    public ResultDomain<TbSysDept> getAllDepartments() {
        ResultDomain<TbSysDept> resultDomain = new ResultDomain<>();

        try {
            logger.info("开始查询所有部门");
            TbSysDept filter = new TbSysDept();
            filter.setDeleted(false);
            List<TbSysDept> departments = departmentMapper.selectDepts(filter);
            
            logger.info("查询所有部门完成，共找到{}个部门", departments.size());
            resultDomain.success("查询成功", departments);
            return resultDomain;
            
        } catch (Exception e) {
            logger.error("查询所有部门失败", e);
            resultDomain.fail("查询部门失败：" + e.getMessage());
            return resultDomain;
        }
    }


    @Override
    public ResultDomain<TbSysDept> getDeptList(TbSysDept filter) {
        ResultDomain<TbSysDept> resultDomain = new ResultDomain<>();
        try {
            logger.info("开始查询部门列表");
            List<TbSysDept> departments = departmentMapper.selectDepts(filter);
            if (departments.isEmpty()) {
                resultDomain.fail("未找到部门");
                return resultDomain;
            }
            resultDomain.success("查询成功", departments);
            return resultDomain;
        } catch (Exception e) {
            logger.error("查询部门列表失败", e);
            resultDomain.fail("查询部门列表失败：" + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbSysDeptRole> getDeptByRoleList() {
        ResultDomain<TbSysDeptRole> resultDomain = new ResultDomain<>();
        List<TbSysDeptRole> deptRoles = deptRoleMapper.selectDeptRoleList();
        resultDomain.success("查询成功", deptRoles);
        return resultDomain;
    }

    @Override
    public ResultDomain<TbSysDept> getDepartmentById(String deptId) {
        ResultDomain<TbSysDept> resultDomain = new ResultDomain<>();
        try {
            logger.info("开始根据ID查询部门：{}", deptId);
            
            if (!StringUtils.hasText(deptId)) {
                resultDomain.fail("部门ID不能为空");
                return resultDomain;
            }
            
            TbSysDept filter = new TbSysDept();
            filter.setDeptID(deptId);
            List<TbSysDept> departments = departmentMapper.selectDepts(filter);
            TbSysDept department = departments.isEmpty() ? null : departments.get(0);
            
            if (department == null) {
                logger.warn("未找到部门：{}", deptId);
                resultDomain.fail("未找到指定部门");
                return resultDomain;
            }
            
            logger.info("根据ID查询部门完成：{}", deptId);
            resultDomain.success("查询成功", department);
            return resultDomain;
            
        } catch (Exception e) {
            logger.error("根据ID查询部门失败：{}", deptId, e);
            resultDomain.fail("查询部门失败：" + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbSysDept> getDepartmentsByParentId(String parentId) {
        ResultDomain<TbSysDept> resultDomain = new ResultDomain<>();
        try {
            logger.info("开始根据父部门ID查询子部门：{}", parentId);
            
            List<TbSysDept> departments = departmentMapper.selectByParentId(parentId);
            
            logger.info("根据父部门ID查询子部门完成，共找到{}个子部门", departments.size());
            resultDomain.success("查询成功", departments);
            return resultDomain;
            
        } catch (Exception e) {
            logger.error("根据父部门ID查询子部门失败：{}", parentId, e);
            resultDomain.fail("查询子部门失败：" + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbSysDept> createDepartment(TbSysDept department) {
        ResultDomain<TbSysDept> resultDomain = new ResultDomain<>();
        try {
            logger.info("开始创建部门：{}", department.getName());
            
            // 参数校验
            if (!StringUtils.hasText(department.getName())) {
                resultDomain.fail("部门名称不能为空");
                return resultDomain;
            }
            
            // 检查部门名称是否已存在
            ResultDomain<Boolean> checkResult = checkDepartmentNameExists(department.getName(), null);
            if (!checkResult.isSuccess()) {
                resultDomain.fail(checkResult.getMessage());
                return resultDomain;
            }
            if (checkResult.getData()) {
                resultDomain.fail("部门名称已存在");
                return resultDomain;
            }
            
            // 设置基础信息
            department.setID(IDUtils.generateID());
            department.setDeptID(IDUtils.generateID());
            department.setCreateTime(new Date());
            department.setDeleted(false);
            
            // 插入数据库
            int result = departmentMapper.insertDept(department);
            
            if (result > 0) {
                logger.info("创建部门成功：{}", department.getName());
                resultDomain.success("创建部门成功", department);
                return resultDomain;
            } else {
                logger.warn("创建部门失败：{}", department.getName());
                resultDomain.fail("创建部门失败");
            }
            
            return resultDomain;
        } catch (Exception e) {
            logger.error("创建部门异常：{}", department.getName(), e);
            resultDomain.fail("创建部门失败：" + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbSysDept> updateDepartment(TbSysDept department) {
        ResultDomain<TbSysDept> resultDomain = new ResultDomain<>();
        try {
            logger.info("开始更新部门：{}", department.getDeptID());
            
            // 参数校验
            if (!StringUtils.hasText(department.getDeptID())) {
                resultDomain.fail("部门ID不能为空");
                return resultDomain;
            }
            if (!StringUtils.hasText(department.getName())) {
                resultDomain.fail("部门名称不能为空");
                return resultDomain;
            }
            
            // 检查部门是否存在
            ResultDomain<TbSysDept> existResult = getDepartmentById(department.getDeptID());
            if (!existResult.isSuccess()) {
                resultDomain.fail(existResult.getMessage());
                return resultDomain;
            }
            
            // 检查部门名称是否已存在（排除自身）
            ResultDomain<Boolean> checkResult = checkDepartmentNameExists(department.getName(), department.getID());
            if (!checkResult.isSuccess()) {
                resultDomain.fail(checkResult.getMessage());
                return resultDomain;
            }
            if (checkResult.getData()) {
                resultDomain.fail("部门名称已存在");
                return resultDomain;
            }
            
            // 设置更新时间
            department.setUpdateTime(new Date());
            
            // 更新数据库
            int result = departmentMapper.updateDept(department);
            
            if (result > 0) {
                logger.info("更新部门成功：{}", department.getDeptID());
                resultDomain.success("更新部门成功", department);
                return resultDomain;
            } else {
                logger.warn("更新部门失败：{}", department.getDeptID());
                resultDomain.fail("更新部门失败");
                return resultDomain;
            }
            
        } catch (Exception e) {
            logger.error("更新部门异常：{}", department.getDeptID(), e);
            resultDomain.fail("更新部门失败：" + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbSysDept> deleteDepartment(String deptId) {
        ResultDomain<TbSysDept> resultDomain = new ResultDomain<>();
        try {
            logger.info("开始删除部门：{}", deptId);
            
            if (!StringUtils.hasText(deptId)) {
                resultDomain.fail("部门ID不能为空");
                return resultDomain;
            }
            
            // 检查部门是否存在
            ResultDomain<TbSysDept> existResult = getDepartmentById(deptId);
            if (!existResult.isSuccess()) {
                resultDomain.fail(existResult.getMessage());
                return resultDomain;
            }
            
            // 检查是否有子部门
            ResultDomain<TbSysDept> childrenResult = getDepartmentsByParentId(deptId);
            if (childrenResult.isSuccess() && childrenResult.getData() != null) {
                resultDomain.fail("该部门下有子部门，无法删除");
                return resultDomain;
            }
            
            // 逻辑删除
            TbSysDept department = existResult.getData();
            department.setDeleted(true);
            department.setDeleteTime(new Date());
            
            int result = departmentMapper.deleteDept(department);
            
            if (result > 0) {
                logger.info("删除部门成功：{}", deptId);
                resultDomain.success("删除部门成功", department);
                return resultDomain;
            } else {
                logger.warn("删除部门失败：{}", deptId);
                resultDomain.fail("删除部门失败");
                return resultDomain;
            }
            
        } catch (Exception e) {
            logger.error("删除部门异常：{}", deptId, e);
            resultDomain.fail("删除部门失败：" + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<Boolean> checkDepartmentNameExists(String deptName, String excludeId) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();
        try {
            logger.info("检查部门名称是否存在：{}", deptName);
            
            if (!StringUtils.hasText(deptName)) {
                resultDomain.fail("部门名称不能为空");
                return resultDomain;
            }
            
            int count = departmentMapper.countByDeptName(deptName, excludeId);
            boolean exists = count > 0;
            
            logger.info("部门名称存在性检查完成：{}，存在：{}", deptName, exists);
            resultDomain.success("检查完成", exists);
            return resultDomain;
            
        } catch (Exception e) {
            logger.error("检查部门名称存在性失败：{}", deptName, e);
            resultDomain.fail("检查失败：" + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbSysRole> getDeptByRole(String deptId) {
        ResultDomain<TbSysRole> resultDomain = new ResultDomain<>();
        try {
            logger.info("开始查询部门绑定角色：{}", deptId);
            List<TbSysRole> roles = deptRoleMapper.selectDeptRole(deptId);
            resultDomain.success("查询成功", roles);
            return resultDomain;
        } catch (Exception e) {
            logger.error("查询部门绑定角色失败", e);
            resultDomain.fail("查询部门绑定角色失败：" + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbSysDeptRole> bindDeptRole(List<String> deptIDs, List<String> roleIDs) {
        ResultDomain<TbSysDeptRole> resultDomain = new ResultDomain<>();
        TbSysUser user = LoginUtil.getCurrentUser();
        if (user == null) {
            resultDomain.fail("当前用户未登录");
            return resultDomain;
        }
        try {
            logger.info("开始绑定部门角色：{}", deptIDs);
            List<TbSysDeptRole> deptRoles = new ArrayList<>();
            Date now = new Date();
            for (String deptID : deptIDs) {
                for (String roleID : roleIDs) {
                    TbSysDeptRole deptRole = new TbSysDeptRole();
                    deptRole.setID(IDUtils.generateID());
                    deptRole.setDeptID(deptID);
                    deptRole.setRoleID(roleID);
                    deptRole.setCreateTime(now);
                    deptRole.setDeleted(false);
                    deptRole.setCreator(user.getID());
                    deptRoles.add(deptRole);
                }
            }
            int result = deptRoleMapper.batchBindDeptRole(deptRoles);
            if (result > 0) {
                logger.info("绑定部门角色成功：{}", deptIDs);
                resultDomain.success("绑定部门角色成功", deptRoles);
                return resultDomain;
            } else {
                logger.warn("绑定部门角色失败：{}", deptIDs);
                resultDomain.fail("绑定部门角色失败");
                return resultDomain;
            }
        } catch (Exception e) {
            logger.error("绑定部门角色失败", e);
            resultDomain.fail("绑定部门角色失败：" + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbSysDeptRole> unbindDeptRole(List<String> deptIDs, List<String> roleIDs) {
        ResultDomain<TbSysDeptRole> resultDomain = new ResultDomain<>();
        try {
            logger.info("开始解绑部门角色：{}", deptIDs);
            List<TbSysDeptRole> deptRoles = new ArrayList<>();
            for (String deptID : deptIDs) {
                for (String roleID : roleIDs) {
                    TbSysDeptRole deptRole = new TbSysDeptRole();
                    deptRole.setDeptID(deptID);
                    deptRole.setRoleID(roleID);
                    deptRoles.add(deptRole);
                }
            }
            int result = deptRoleMapper.batchUnbindDeptRole(deptRoles);
            if (result > 0) {
                logger.info("解绑部门角色成功：{}", deptIDs);
                resultDomain.success("解绑部门角色成功", deptRoles);
                return resultDomain;
            } else {
                logger.warn("解绑部门角色失败：{}", deptIDs);
                resultDomain.fail("解绑部门角色失败");
                return resultDomain;
            }
        } catch (Exception e) {
            logger.error("解绑部门角色失败", e);
            resultDomain.fail("解绑部门角色失败：" + e.getMessage());
            return resultDomain;
        }
    }
}
