package cn.ezhizao.project.system.controller;

import cn.ezhizao.common.constant.UserConstants;
import cn.ezhizao.common.utils.SecurityUtils;
import cn.ezhizao.common.utils.StringUtils;
import cn.ezhizao.common.utils.poi.ExcelUtil;
import cn.ezhizao.framework.aspectj.lang.annotation.Log;
import cn.ezhizao.framework.aspectj.lang.enums.BusinessType;
import cn.ezhizao.framework.web.controller.BaseController;
import cn.ezhizao.framework.web.domain.AjaxResult;
import cn.ezhizao.framework.web.page.TableDataInfo;
import cn.ezhizao.project.business.innerTurnover.domain.BizInnerTurnover;
import cn.ezhizao.project.system.domain.*;
import cn.ezhizao.project.system.mapper.SysUserMapper;
import cn.ezhizao.project.system.service.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户信息
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController {
    @Resource
    private ISysUserService userService;

    @Resource
    private ISysRoleService roleService;

    @Resource
    private ISysDeptService deptService;

    @Resource
    private ISysPostService postService;

    /*
     * @Resource
     * private IBizUserTenantService userTenantService;
     */

    @Resource
    private HttpServletRequest request;
    @Resource
    private ISysDeptUserService deptUserService;

    @Resource
    private SysUserMapper sysUserMapper;

    /**
     * 获取用户列表
     */
    //@PreAuthorize("@ss.hasPermi('system:user:list')")
    @Log(title = "查询用户列表", businessType = BusinessType.SELECT)
    @GetMapping("/list")
    public TableDataInfo list(SysUser user) throws NoSuchFieldException, IllegalAccessException {
//        String tenantId = request.getHeader("tenantId");
//        user.setTenantId(Long.valueOf(tenantId));
        startPage();
        List<SysUser> list = userService.selectUserList(user);
        return getDataTable(list);
    }
    //包装线添加员工已经添加的不显示
    @Log(title = "用户查询，包装线添加员工", businessType = BusinessType.SELECT)
    @GetMapping("/notHasAddList")
    public TableDataInfo notHasAddList(SysUser user) throws NoSuchFieldException, IllegalAccessException {
//        String tenantId = request.getHeader("tenantId");
//        user.setTenantId(Long.valueOf(tenantId));
        startPage();
        List<SysUser> list = userService.selectNotAddList(user);
        return getDataTable(list);
    }
    @Log(title = "通过厂别查询用户", businessType = BusinessType.SELECT)
    @GetMapping("/tenantList")
    public TableDataInfo tenantList(SysUser user) throws NoSuchFieldException, IllegalAccessException {
        startPage();
        List<SysUser> list = userService.selectTenantList(user);
        return getDataTable(list);
    }
    @Log(title = "用户名和用户账户查询用户", businessType = BusinessType.SELECT)
    @GetMapping("/listByLikeNickNameOrUserName")
    public TableDataInfo listByLikeNickNameOrUserName(SysUser user) throws NoSuchFieldException, IllegalAccessException {
        startPage();
        List<SysUser> userList = userService.listByLikeNickNameOrUserName(user);
        return getDataTable(userList);
    }
    @Log(title = "用户查询", businessType = BusinessType.SELECT)
    @GetMapping("/listEmployee")
    public TableDataInfo listEmployee(SysUser user) throws NoSuchFieldException, IllegalAccessException {
        startPage();
        String tenantId = request.getHeader("tenantId");
        user.setTenantId(Long.valueOf(tenantId));
        List<SysUser> list = userService.selectEmployeeList(user);
        return getDataTable(list);
    }
    @Log(title = "通过用户id查询菜单权限", businessType = BusinessType.SELECT)
    @PostMapping("/selectUserPermissionList")
    public AjaxResult selectUserPermissionList(@RequestBody SysUser user) throws NoSuchFieldException, IllegalAccessException {
        Long userId = SecurityUtils.getLoginUser().getUserId();
        List<SysMenu> sysMenus = userService.selectUserPermissionList(userId);
        return success(sysMenus);
    }
    @Log(title = "用户查询", businessType = BusinessType.SELECT)
    @GetMapping("/getUserList")
    public TableDataInfo getUserList(SysUser user) throws NoSuchFieldException, IllegalAccessException {
        startPage();
        String tenantId = request.getHeader("tenantId");
        user.setTenantId(Long.valueOf(tenantId));
        List<SysUser> list = userService.getUserList(user);
        return getDataTable(list);
    }

    /**
     * 获取中间表信息
     */
    @Log(title = "查询工段下员工信息", businessType = BusinessType.SELECT)
    @GetMapping("/deptUser")
    public TableDataInfo deptUser(SysDeptUser deptUser) {
//        String tenantId = request.getHeader("tenantId");
//        deptUser.setTenantId(Long.valueOf(tenantId));
        startPage();
        List<SysDeptUser> list = deptUserService.getList(deptUser);
//        List<SysDeptUser> filteredList = list.stream()
//                .distinct()
//                .collect(Collectors.toList());
        return getDataTable(list);
    }

    /**
     * 获取用户部门
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @Log(title = "工段下员工信息查询", businessType = BusinessType.SELECT)
    @GetMapping("/getUsersByDeptId")
    public TableDataInfo getUsersByDeptId( SysDept data) {
        Long deptId = data.getDeptId();
        String tenantId = request.getHeader("tenantId");
        startPage();
        SysDept dept = deptService.selectDeptById(deptId);
        SysDept deptItem = new SysDept();
        deptItem.setTenantId(Long.valueOf(tenantId));
        List<SysDept> sysDepts = deptService.selectDeptList(deptItem);
        List<SysDept> allSubDepartments = getAllSubDepartments(dept, sysDepts);
        List<Long> ids = new ArrayList<>();
        ids.add(deptId);
        for (SysDept item: allSubDepartments
             ) {
            ids.add(item.getDeptId());
        }
        startPage();
        List<SysUser> list = userService.getListByDept(ids);
        List<SysUser> distinct = list.stream().distinct().collect(Collectors.toList());
        return getDataTable(distinct);
    }

    /**
     * 获取用户通过deptId
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @Log(title = "通过工段查询工段下员工信息", businessType = BusinessType.SELECT)
    @GetMapping("/getUsersItemByDeptId")
    public TableDataInfo getUsersItemByDeptId(SysDeptUser sysDeptUser) {
        String tenantId = request.getHeader("tenantId");
        sysDeptUser.setTenantId(Long.valueOf(tenantId));
        List<SysDeptUser> list = deptUserService.getList(sysDeptUser);
        return getDataTable(list);
    }
    //获取用户详细通过deptId
    @Log(title = "过工段查询工段下员工信息", businessType = BusinessType.SELECT)
    @PostMapping("/getUserInfoByDeptId")
    public TableDataInfo getUserInfoByDeptId(@RequestBody SysDeptUser sysDeptUser) {
        startPage();
        List<SysUser> list = deptUserService.getUserInfoByDeptId(sysDeptUser);
        return getDataTable(list);
    }

    /** 递归获取所有下级部门 */
    public static List<SysDept> getAllSubDepartments(SysDept department, List<SysDept> allDepartments) {
        List<SysDept> subDepartments = new ArrayList<>();
        for (SysDept dep : allDepartments) {
            if (dep.getParentId().equals(department.getDeptId())) {
                subDepartments.add(dep);
                subDepartments.addAll(getAllSubDepartments(dep, allDepartments));
            }
        }
        return subDepartments;
    }
    @Log(title = "用户管理导出", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:user:export')")
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysUser user) throws NoSuchFieldException, IllegalAccessException {
        List<SysUser> list;
        if (user.getIds().size() > 0) {
            list = userService.selectUserListByIds(user.getIds());
        } else {
            list = userService.selectUserList(user);
        }
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        util.exportExcel(response, list, "用户数据");
    }

    @Log(title = "用户管理导入", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('system:user:import')")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
        ExcelUtil<SysUser> util = new ExcelUtil<>(SysUser.class);
        List<SysUser> userList = util.importExcel(file.getInputStream());
        String operName = getUsername();
        String message = userService.importUser(userList, updateSupport, operName);
        return success(message);
    }
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil<SysUser> util = new ExcelUtil<>(SysUser.class);
        util.importTemplateExcel(response, "用户数据");
    }

    /**
     * 根据用户编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:user:query')")
    @Log(title = "根据用户编号获取详细信息", businessType = BusinessType.IMPORT)
    @GetMapping(value = { "/", "/{userId}" })
    public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) {
        userService.checkUserDataScope(userId);
        AjaxResult ajax = AjaxResult.success();
        List<SysRole> roles = roleService.selectRoleAll();
        ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        ajax.put("posts", postService.selectPostAll());
        if (StringUtils.isNotNull(userId) && userId>0) {
            SysUser sysUser = userService.selectUserById(userId);
            ajax.put(AjaxResult.DATA_TAG, sysUser);
            ajax.put("postIds", postService.selectPostListByUserId(userId));
            ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
//            List<SysDeptUser> user = deptUserService.query().eq("user_id", userId).list();
//            List<SysDept> depts = deptService.selectDeptList(new SysDept());
//            depts = depts.stream().filter(e -> user.stream().anyMatch(t -> t.getDeptId().equals(e.getDeptId()))).collect(Collectors.toList());
//            ajax.put("depts", depts);
        }
        return ajax;
    }

    /**
     * 新增用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:add')")
    @Log(title = "用户管理新增", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysUser user) {
        String tenantId = request.getHeader("tenantId");
        user.setTenantId(Long.valueOf(tenantId));
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user))) {
            return error("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(user.getPhoneNumber())
                && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            return error("新增用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail())
                && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
            return error("新增用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        user.setCreateBy(getUsername());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
//        if (StringUtils.isNotEmpty(tenantId)) {
            user.setUserType("02");
//        }
        int rows = userService.insertUser(user);
   /**   tenant现在没有注释掉
    *  boolean bool = false;
        if (StringUtils.isNotEmpty(tenantId) && rows > 0) {
            userTenant.setUserId(user.getUserId());
            userTenant.setTenantId(Long.parseLong(tenantId));
            bool = userTenantService.save(userTenant);
        }*/
        return toAjax(rows);
    }

    /**
     * 新增管理员用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:add')")
    @Log(title = "用户管理新增管理员用户", businessType = BusinessType.INSERT)
    @PostMapping("/saveAdmin")
    public AjaxResult saveAdmin(@Validated @RequestBody SysUser user) {
        if(user.getTenantId() == null) {
            String tenantId = request.getHeader("tenantId");
            user.setTenantId(Long.valueOf(tenantId));
            user.setUserType("01");
        }
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user))) {
            return error("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(user.getPhoneNumber())
                && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            return error("新增用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail())
                && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
            return error("新增用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        user.setCreateBy(getUsername());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        if (user.getTenantId() != null) {
            user.setUserType("01");
        }
        int rows = userService.insertUser(user);
        /**   tenant现在没有注释掉
         *  boolean bool = false;
         if (StringUtils.isNotEmpty(tenantId) && rows > 0) {
         userTenant.setUserId(user.getUserId());
         userTenant.setTenantId(Long.parseLong(tenantId));
         bool = userTenantService.save(userTenant);
         }*/
        return toAjax(rows);
    }

    /**
     * 新增或修改用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:add')")
    @Log(title = "用户管理保存", businessType = BusinessType.INSERT)
    @PostMapping(value = "save")
    @Transactional
    public AjaxResult save(@Validated @RequestBody SysUser user) {
        String tenantId = request.getHeader("tenantId");
        user.setTenantId(Long.valueOf(tenantId));
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user))) {
            return error("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(user.getPhoneNumber())
                && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            return error("新增用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail())
                && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
            return error("新增用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        user.setCreateBy(getUsername());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
//        if(StringUtils.isNotEmpty(tenantId)){
//            user.setUserType("02");
//        }
        int rows = 0;
        if (user.getUserId() == null) {
             rows = userService.insertUser(user);

        } else {
            user.setUpdateBy(getUsername());
            rows = userService.updateUser(user);
        }
//        boolean bool = false;
//        if(StringUtils.isNotEmpty(tenantId) && rows > 0){
//            userTenant.setUserId(user.getUserId());
//            userTenant.setUserId(user.getDeptId());
//            userTenant.setTenantId(Long.parseLong(tenantId));
//            bool = userTenantService.save(userTenant);
//        }
        return toAjax(rows);
    }

    /**
     * 新增或修改中间表用户
     */
//    @PreAuthorize("@ss.hasPermi('system:user:add')")
    @Log(title = "工段下员工信息保存", businessType = BusinessType.INSERT)
    @PostMapping(value = "saveDeptUser")
    @Transactional
    public AjaxResult saveDeptUser(@Validated @RequestBody List<SysDeptUser> deptUserList) {
        String tenantId = request.getHeader("tenantId");
        List<SysDeptUser> deptUsers = new ArrayList<>();
        for (SysDeptUser deptUser: deptUserList
        ) {
            deptUser.setTenantId(Long.valueOf(tenantId));
            List<SysDeptUser> list = deptUserService.query().eq("user_id", deptUser.getUserId()).eq("dept_id", deptUser.getDeptId()).eq("tenant_id", deptUser.getTenantId()).eq("deleted", 0).list();
            if (list.size() == 0) {
                deptUsers.add(deptUser);

            }

        }

        if (deptUsers.size() == 0) {
            return AjaxResult.error("选择用户重复，请重新选择");
        }

        return toAjax(deptUserService.saveBatch(deptUsers));
    }

    /**
     * 修改中间表用户是否是工段长或调机或主管或调度
     */
//    @PreAuthorize("@ss.hasPermi('system:user:add')")
    @Log(title = "工段下员工修改", businessType = BusinessType.INSERT)
    @PutMapping("/updateDeptUser")
    @Transactional
    public AjaxResult updateDeptUser(@RequestBody SysDeptUser data) {
        String tenantId = request.getHeader("tenantId");
        data.setTenantId(Long.valueOf(tenantId));
        return toAjax(deptUserService.updateDeptUser(data));
    }

    /**
     * 修改用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理修改", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysUser user) throws NoSuchFieldException, IllegalAccessException {
        userService.checkUserAllowed(user);
        userService.checkUserDataScope(user.getUserId());
        user.setTenantId(user.getUsageCompanyId());
        if(user.getTenantId() == null) {
            String tenantId = request.getHeader("tenantId");
            user.setTenantId(Long.valueOf(tenantId));
        }
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user))) {
            return error("修改用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(user.getPhoneNumber())
                && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            return error("修改用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail())
                && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
            return error("修改用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        user.setUpdateBy(getUsername());
        return toAjax(userService.updateUser(user));
    }

    /**
     * 删除用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:remove')")
    @Log(title = "用户管理删除", businessType = BusinessType.DELETE)
    @DeleteMapping("/{userIds}")
    public AjaxResult remove(@PathVariable List<Long> userIds) {
        if (userIds.contains(getUserId())) {
            return error("当前用户不能删除");
        }
        return toAjax(userService.deleteUserByIds(userIds));
    }

//    @PreAuthorize("@ss.hasPermi('system:user:remove')")
    @Log(title = "删除工段下员工信息", businessType = BusinessType.DELETE)
    @PostMapping("/delDeptUser")
    public AjaxResult delDeptUser(@RequestBody List<SysDeptUser> deptUsers) {
        Long userId = SecurityUtils.getLoginUser().getUserId();
        List<Long> userIds = deptUsers.stream()
                .map(SysDeptUser::getUserId)
                .collect(Collectors.toList());
        if(userIds.contains(userId)) {
            return error("工段长不能删除自己");
        }
        for (SysDeptUser item: deptUsers
             ) {
            deptUserService.deleteByDeptIdAndUserId(item);
        }

        return success();
    }
    /**
     * 重置密码
     */
    @PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
    @Log(title = "用户管理重置密码", businessType = BusinessType.UPDATE)
    @PutMapping("/resetPwd")
    public AjaxResult resetPwd(@RequestBody SysUser user) {
        userService.checkUserAllowed(user);
        userService.checkUserDataScope(user.getUserId());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        user.setUpdateBy(getUsername());
        return toAjax(userService.resetPwd(user));
    }

    /**
     * 状态修改
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理状态修改", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody SysUser user) {
        userService.checkUserAllowed(user);
        userService.checkUserDataScope(user.getUserId());
        user.setUpdateBy(getUsername());
        return toAjax(userService.updateUserStatus(user));
    }

    /**
     * 根据用户编号获取授权角色
     */
    @PreAuthorize("@ss.hasPermi('system:user:query')")
    @Log(title = "根据用户编号获取授权角色", businessType = BusinessType.UPDATE)
    @GetMapping("/authRole/{userId}")
    public AjaxResult authRole(@PathVariable("userId") Long userId) {
        AjaxResult ajax = AjaxResult.success();
        SysUser user = userService.selectUserById(userId);
        List<SysRole> roles = roleService.selectRolesByUserId(userId);
        ajax.put("user", user);
        ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        return ajax;

    }

    /**
     * 用户授权角色
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理授权角色", businessType = BusinessType.GRANT)
    @PutMapping("/authRole")
    public AjaxResult insertAuthRole(Long userId, Long[] roleIds) {
        userService.checkUserDataScope(userId);
        userService.insertUserAuth(userId, roleIds);
        return success();
    }

    /**
     * 获取部门树列表
     */
    @Log(title = "获取部门树列表", businessType = BusinessType.SELECT)
    @GetMapping("/deptTree")
    public AjaxResult deptTree(SysDept dept) throws NoSuchFieldException, IllegalAccessException {
        String tenantId = request.getHeader("tenantId");
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        dept.setUserId(userId);
        dept.setTenantId(Long.valueOf(tenantId));
        return success(deptService.selectDeptTreeList(dept));
    }
    @Log(title = "工段下内部周转用户", businessType = BusinessType.SELECT)
    @GetMapping("/listInnerUserByDeptId")
    public TableDataInfo listInnerUserByDeptId(SysDept sysDept) {
        startPage();
       return getDataTable(deptUserService.selectInnerUserByDeptId(sysDept));
    }
    /**
     * 根据userName获取id
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @Log(title = "用户管理，根据userName获取id", businessType = BusinessType.SELECT)
    @GetMapping("/getUserByCode")
    public SysUser getUserByCode(String userName) {

        return userService.getUserByCode(userName);
    }
}
