package com.bonus.system.basic.controller;

import com.bonus.common.core.utils.UploadCheckUtils;
import com.bonus.common.core.utils.poi.ExcelUtil;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.core.web.page.TableDataInfo;
import com.bonus.common.log.annotation.Log;
import com.bonus.common.log.enums.BusinessType;
import com.bonus.common.security.annotation.RequiresPermissions;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.system.api.domain.MapVo;
import com.bonus.system.api.domain.SysRole;
import com.bonus.system.api.domain.SysUser;
import com.bonus.system.att.tasks.WechatTasks;
import com.bonus.system.basic.dao.SysOrgDao;
import com.bonus.system.basic.dao.SysUserMapper;
import com.bonus.system.basic.service.SysMenuService;
import com.bonus.system.basic.service.SysUserService;
import com.bonus.system.dept.dao.ProDeptRoleDao;
import com.bonus.system.dept.entity.ProDeptRoleDo;
import com.bonus.system.holiday.dao.WorkReportDao;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.bonus.common.core.domain.R;
import com.bonus.common.core.web.controller.BaseController;
import com.bonus.common.security.annotation.InnerAuth;
import com.bonus.system.api.model.LoginUser;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 用户信息
 *
 * @author zys
 */
@RestController
@RequestMapping("/user")
public class SysUserController extends BaseController {
    @Autowired
    private SysUserService userService;

    @Resource(name = "sysMenuService")
    private SysMenuService sysMenuService;

    @Autowired
    private WechatTasks wechatTasks;

    @Resource(name = "WorkReportDao")
    private WorkReportDao dao;

    @Resource
    private SysUserMapper userMapper;

    @Resource(name = "ProDeptRoleDao")
    private ProDeptRoleDao proDeptRoleDao;

    @Resource
    private SysOrgDao sysOrgDao;


    @RequiresPermissions("system:user:list")
    @GetMapping("/list")
    @Log(title = "系统管理->人员信息->查询人员列表", businessType = BusinessType.QUERY)
    public TableDataInfo list(SysUser bean) {
        try{
            SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
            List<String> roleId = sysUser.getRoleList();
            //管理员与人资角色可以看到所有
            if (roleId != null && !roleId.isEmpty()) {
                if (Collections.frequency(roleId, "1") == 0 && Collections.frequency(roleId, "16") == 0) {
                    // 根据用户id查询是否是管理员或帮忙负责人
                    Long userId = SecurityUtils.getUserId();
                    List<MapVo> orgList = sysOrgDao.getOrgIdList(userId);
                    if (!orgList.isEmpty()) {
                        // 使用 LinkedHashSet 来保证顺序并自动去重
                        Set<String> idsSet = new LinkedHashSet<>();
                        for (MapVo mapVo : orgList) {
                            String id = proDeptRoleDao.getOrgChildById(mapVo.getId());
                            if (id != null && !id.trim().isEmpty()) { // 防止空或仅含空白字符的字符串
                                // 将分割后的数组添加到 Set 中，自动去重
                                Collections.addAll(idsSet, id.split(","));
                            }
                        }
                        // 如果需要转换回 List 类型
                        List<String> uniqueIds = new ArrayList<>(idsSet);
                        bean.setOrgIdList(uniqueIds);
                    }else{
                        bean.setUserId(userId);
                    }
                }
            }
            startPage();
            List<SysUser> list = userService.selectUserList(bean);
            return getDataTable(list);
        }catch (Exception e){
            logger.error(e.toString(),e);
        }
        return  getDataTableError(new ArrayList<>());
    }


    @GetMapping("/listPro")
    @Log(title = "系统管理->分公司项目部管理->权限分配->查询人员列表", businessType = BusinessType.QUERY)
    public TableDataInfo listPro(SysUser bean) {
        try{
//            List<SysUser> list = userService.selectUserList(bean);
//            return endPage(list);
            startPage();
            List<SysUser> list = userService.selectUserList(bean);
            return getDataTable(list);
        }catch (Exception e){
            logger.error(e.toString(),e);
        }
        return  getDataTableError(new ArrayList<>());
    }

    /**
     * 用户新增
     */
    @RequiresPermissions("system:user:add")
    @PostMapping("/addUser")
    @Log(title = "系统管理->人员信息->新增人员", businessType = BusinessType.INSERT)
    public AjaxResult add(@Validated @RequestBody SysUser user) {
        return userService.insertUser(user);
    }

    /**
     * 重置密码
     */
    @RequiresPermissions("system:user:pwd")
    @Log(title = "系统管理->人员信息->重置密码", businessType = BusinessType.UPDATE)
    @PostMapping("/resetPwd")
    public AjaxResult resetPwd(@Validated @RequestBody SysUser user){
        return userService.resetPwd(user);
    }

    /**
     * 修改密码
     */
    @Log(title = "系统管理->人员信息->修改密码", businessType = BusinessType.UPDATE)
    @PostMapping("/updatePwd")
    public AjaxResult updatePwd(@Validated @RequestBody SysUser user){
        return userService.updatePwd(user);
    }


    /**
     * 授予更新人脸权
     */
    @Log(title = "系统管理->人员信息->授予更新人脸权", businessType = BusinessType.UPDATE)
    @PostMapping("/updateIsFace")
    public AjaxResult updateIsFace(@Validated @RequestBody SysUser user){
        wechatTasks.updateWechatIsFace(user);
        return userService.updateIsFace(user);
    }

    /**
     * 修改用户
     */
    @RequiresPermissions("system:user:edit")
    @Log(title = "系统管理->人员信息->修改人员", businessType = BusinessType.UPDATE)
    @PostMapping("updateUser")
    public AjaxResult edit(@Validated @RequestBody SysUser user) {
        try{
            if (StringUtils.isNotEmpty(user.getPhone()) && !userService.checkPhoneUnique(user)) {
                return error("修改用户'" + user.getUserName() + "'失败，手机号码已存在");
            }
            if (StringUtils.isNotEmpty(user.getIdNumber()) && !userService.checkIdNumberUnique(user)){
                return error("修改用户'" + user.getUserName() + "'失败，身份证号已存在");
            }
            if (StringUtils.isNotEmpty(user.getUserName()) && !userService.checkUserNameUnique(user)){
                return error("修改用户'" + user.getUserName() + "'失败，用户名已存在");
            }
            user.setUpdateBy(String.valueOf(SecurityUtils.getLoginUser().getSysUser().getUserId()));

            // 修改leave_apply中的org_id

            return toAjax(userService.updateUser(user));
        } catch (Exception e) {
            logger.error(e.toString(),e);
            return AjaxResult.error("修改失败");
        }
    }

    /**
     * 删除用户
     */
    @RequiresPermissions("system:user:del")
    @Log(title = "系统管理->人员信息->删除人员", businessType = BusinessType.DELETE)
    @PostMapping("/delUser")
    public AjaxResult remove(@Validated @RequestBody SysUser user) {
        long userId = SecurityUtils.getLoginUser().getSysUser().getUserId();
        if (user.getUserId().equals(userId)) {
            return error("当前用户不能删除");
        }
        return toAjax(userService.deleteUserByIds(user.getUserId()));
    }

    @PostMapping("excelUpload")
    @RequiresPermissions("system:user:excelUpload")
    @Log(title = "系统管理->人员信息->导入Excel", businessType = BusinessType.IMPORT)
    public AjaxResult excelUpload(MultipartFile file, HttpServletRequest request, HttpServletResponse response) {
        try{
            String result = UploadCheckUtils.uploadExcelVerify(file);
            if (StringUtils.isNotBlank(result)) {
                return AjaxResult.error(result);
            }
            return userService.excelUpload(file, request, response);
        }catch (Exception e){
            logger.error(e.toString(),e);
            return AjaxResult.error();
        }
    }

    @RequiresPermissions("system:user:export")
    @GetMapping("/export")
    @Log(title = "系统管理->人员信息->导出excel", businessType = BusinessType.EXPORT)
    public void export(HttpServletResponse response, SysUser user) {
        try{
            SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
            List<String> roleId = sysUser.getRoleList();
            //管理员与人资角色可以看到所有
            if (roleId != null && !roleId.isEmpty()) {
                if (Collections.frequency(roleId, "1") == 0 && Collections.frequency(roleId, "16") == 0) {
                    // 根据用户id查询是否是管理员或帮忙负责人
                    Long userId = SecurityUtils.getUserId();
                    List<MapVo> orgList = sysOrgDao.getOrgIdList(userId);
                    if (!orgList.isEmpty()) {
                        // 使用 LinkedHashSet 来保证顺序并自动去重
                        Set<String> idsSet = new LinkedHashSet<>();
                        for (MapVo mapVo : orgList) {
                            String id = proDeptRoleDao.getOrgChildById(mapVo.getId());
                            if (id != null && !id.trim().isEmpty()) { // 防止空或仅含空白字符的字符串
                                // 将分割后的数组添加到 Set 中，自动去重
                                Collections.addAll(idsSet, id.split(","));
                            }
                        }
                        // 如果需要转换回 List 类型
                        List<String> uniqueIds = new ArrayList<>(idsSet);
                        user.setOrgIdList(uniqueIds);
                    }else{
                        user.setUserId(userId);
                    }
                }
            }
            List<SysUser> list = userService.selectUserList(user);
            ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
            util.exportExcel(response, list, "人员数据");
        }catch (Exception e){
            logger.error(e.toString(),e);
        }

    }

    /**
     * 根据用户Id获取用户信息
     */
    @PostMapping("/getUsersById")
    public AjaxResult getUsersById(@Validated @RequestBody SysUser user) {
        return AjaxResult.success(userService.selectUserList(user));
    }



    /**
     * 获取当前用户信息
     */
    @InnerAuth
    @GetMapping("/info/{username}")
    public R<LoginUser> info(@PathVariable("username") String username) {
        return userService.selectUserByUserName(username);
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo() {
        try {
            SysUser user = userService.selectUserById(SecurityUtils.getUserId());
            // 组织集合
            List<MapVo> orgList = userService.getOrgByUserId(user);
            user.setOrgList(orgList);
            // 获取考勤组
            List<MapVo> attGroupList = userService.getAttGroupByUserId(user);
            if(!attGroupList.isEmpty()){
                user.setAttGroupId(attGroupList.get(0).getId());
                user.setAttGroupName(attGroupList.get(0).getName());
            }
            // 角色集合
            Set<String> roles = sysMenuService.getRolePermission(user);
            List<String> roleList =  userService.getRoleList(user);
            user.setRoleList(roleList);
            // 权限集合
            Set<String> permissions = sysMenuService.getMenuPermission(user);
            AjaxResult ajax = AjaxResult.success();
            ajax.put("user", user);
            ajax.put("roles", roles);
            ajax.put("permissions", permissions);
            return ajax;
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        return error("系统异常,请联系管理员");
    }


    /**
     * 查询所有角色
     */
    @GetMapping("getSelectRole")
    public AjaxResult getSelectRole() {
        return userService.getSelectRole();
    }

    /**
     * 查询所有岗位
     */
    @GetMapping("getSelectPost")
    public AjaxResult getSelectPost() {
        return userService.getSelectPost();
    }


    /**
     * 查询所有人员
     */
    @GetMapping("getSelectUser")
    public AjaxResult getSelectUser() {
        return userService.getSelectUser();
    }


    /**
     * 查询所有人员-除了当前用户
     */
    @GetMapping("getSelectUserCurrent")
    public AjaxResult getSelectUserCurrent() {
        return userService.getSelectUserCurrent();
    }

    /**
     * 配置
     */
    @PostMapping("checkPersonAssignment")
    @Log(title = "人员管理->人员管理->人脸审批", businessType = BusinessType.UPDATE)
    public AjaxResult checkPersonAssignment(@RequestBody SysUser bean) {
        try{
            wechatTasks.checkWechatIsFace(bean);
            if(!"1".equals(bean.getIsCheck())){
                //没通过重新授权一下
                bean.setIsFace("1");
                wechatTasks.updateWechatIsFace(bean);
            }
            return toAjax(userService.checkPersonAssignment(bean));
        }catch (Exception e){
            logger.error(e.toString(),e);
        }
        return error("系统异常");
    }


    /**
     * 权限分配
     */
    @Log(title = "系统管理->人员信息->修改人员-权限分配", businessType = BusinessType.UPDATE)
    @PostMapping("updatePermission")
    public AjaxResult updatePermission(@Validated @RequestBody SysUser user) {
        try{
            return toAjax(userService.updatePermission(user));
        } catch (Exception e) {
            logger.error(e.toString(),e);
            return AjaxResult.error("修改失败");
        }
    }

    /**
     * 用户模板-下载模板
     * @param request
     * @param response
     */
    @PostMapping("userFile")
    public void userFile(HttpServletRequest request, HttpServletResponse response) {
        InputStream inputStream = null;
        ServletOutputStream servletOutputStream = null;
        try {
            String path = "download/" + "user_model.xlsx";
            inputStream = this.getClass().getClassLoader().getResourceAsStream(path);
            response.setContentType("application/vnd.ms-excel");
            response.addHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.addHeader("charset", "utf-8");
            response.addHeader("Pragma", "no-cache");
            String encodeName = URLEncoder.encode("user_model.xlsx", StandardCharsets.UTF_8.toString());
            response.setHeader("Content-Disposition", "attachment; filename=\"" + encodeName + "\"; filename*=utf-8''" + encodeName);
            servletOutputStream = response.getOutputStream();
            IOUtils.copy(inputStream, servletOutputStream);
            response.flushBuffer();
        } catch (Exception e) {
            logger.error("用户模板-下载失败", e);
        }
    }
}
