package com.liang.controller;

import cn.hutool.crypto.digest.MD5;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liang.common.base.BaseResult;
import com.liang.common.JsonTool;
import com.liang.common.annotation.LogAround;
import com.liang.common.base.BaseController;
import com.liang.common.config.SFTYProperties;
import com.liang.common.utils.ExcelPoiUtil;
import com.liang.common.utils.SHA256Utils;
import com.liang.common.utils.StringUtils;
import com.liang.entity.BasePerson;
import com.liang.entity.SysDeptInfo;
import com.liang.entity.SysUserInfo;
import com.liang.entity.SysUserPost;
import com.liang.service.*;
//import com.liang.vo.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.bouncycastle.jce.provider.JDKMessageDigest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ResourceLoader;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

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

/**
 * (SysUserInfo)表控制层
 *
 * @author makejava
 * @since 2023-02-19 21:37:39
 */
@Controller
@RequestMapping("/userinfo")
@Api(value = "系统用户管理控制器", tags = "系统用户管理控制器")
public class SysUserInfoController extends BaseController {
    final static Logger logger = LoggerFactory.getLogger(SysUserInfoController.class);
    final static String salt = "323@#@$1234da";
    /**
     * 服务对象
     */
    @Resource
    private SysUserInfoService sysUserInfoService;
    @Resource
    private SysUserRoleService sysUserRoleService;
    @Resource
    private SysDeptInfoService sysDeptInfoService;
    @Resource
    private SysUserPostService sysUserPostService;
    @Resource
    private SysDictInfoService sysDictInfoService;
    @Resource
    private ResourceLoader resourceLoader;

    /**
     * 分页查询
     *
     * @param sysUserInfo 筛选条件
     * @param pageRequest 分页对象
     * @return 查询结果
     */
    @GetMapping
    public ResponseEntity<Page<SysUserInfo>> queryByPage(SysUserInfo sysUserInfo, PageRequest pageRequest) {
        return ResponseEntity.ok(this.sysUserInfoService.queryByPage(sysUserInfo, pageRequest));
    }

    /**
     * 查询页面初始化
     *
     * @return
     */
    @ApiOperation(value = "查询页面初始化", notes = "查询页面初始化")
    @RequestMapping(value = "/init", method = RequestMethod.GET)
    public String init(Model model) {
        // 获取下拉栏枚举值
        List<Map<String, String>> baseDictList = sysDictInfoService.queryByCode("user_status");
        model.addAttribute("baseDictList", baseDictList);
        return "userinfo/list";
    }

    //    @RequiresPermissions(value = {"system:user:add", "system:user:edit"}, logical = Logical.OR)
    @RequestMapping(value = "/listDeptForSelect", method = RequestMethod.GET)
    @ResponseBody
    public BaseResult listDeptForSelect() {
        List<SysDeptInfo> list = sysDeptInfoService.list();
        return BaseResult.success("修改获取部门树列表成功!", list);
    }

    /**
     * 账户管理页面分页查询
     *
     * @return
     */
    @LogAround("用户数据分页查询")
    @ApiOperation(value = "用户数据分页查询", notes = "用户数据分页查询")
    @ResponseBody
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    public BaseResult list(@RequestParam("page") Integer pageNum,
                           @RequestParam("limit") Integer pageSize,
                           @RequestParam(required = false, defaultValue = "", value = "account") String account,
                           @RequestParam(required = false, defaultValue = "", value = "name") String name,
                           @RequestParam(required = false, defaultValue = "", value = "deptName") String deptName,
                           @RequestParam(required = false, defaultValue = "", value = "status") String status,
                           @RequestParam(required = false, defaultValue = "", value = "sortName") String sortName,
                           @RequestParam(required = false, defaultValue = "", value = "sortOrder") String sortOrder,
                           @RequestParam(required = false, defaultValue = "", value = "userPostName")String userPostName) {
        //分页查询
        PageHelper.startPage(pageNum, pageSize);
        Map<String, String> paraMap = new HashMap<>();
        paraMap.put("sortName", sortName);
        paraMap.put("sortOrder", sortOrder);
        paraMap.put("account", account);
        paraMap.put("name", name);
        paraMap.put("deptName", deptName);
        paraMap.put("status", status);
        paraMap.put("postName",userPostName);
        List<SysUserInfo> accounts = sysUserInfoService.getSysUserInfoList(paraMap);

        PageInfo<SysUserInfo> pageinfo = new PageInfo<>(accounts);
        //取出查询结果
        List<SysUserInfo> rows = pageinfo.getList();

        // 动态构建头像url
//        rows.forEach(item-> {
//            item.setAvatar(storageService.getExpiryUrlById(item.getAvatar(), 24));
//        });

        int total = (int) pageinfo.getTotal();
        Map<String, Object> result = new HashMap<>();
        result.put(RESULT_ROWS, rows);
        result.put(RESULT_TOTAL, total);

        return BaseResult.success(result);
    }


    @ResponseBody
    @RequestMapping(value = "/rylist", method = RequestMethod.GET)
    public Object rylist(@RequestParam("page") Integer pageNum,
                         @RequestParam("limit") Integer pageSize,
                         @RequestParam(required = false, defaultValue = "", value = "name") String name,
                         @RequestParam(required = false, defaultValue = "", value = "dwmc") String dwmc,
                         @RequestParam(required = false, defaultValue = "", value = "bmmc") String bmmc) {
        PageHelper.startPage(pageNum, pageSize);

        Map<String, String> paraMap = new HashMap<>();
        paraMap.put("name", name);
        paraMap.put("dwmc", dwmc);
        paraMap.put("bmmc", bmmc);
        List<SysUserInfo> accounts = sysUserInfoService.getSysUserInfoList(paraMap);

        PageInfo<SysUserInfo> pageinfo = new PageInfo<>(accounts);
        // 取出查询结果
        int total = (int) pageinfo.getTotal();

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("code", 0);
        resultMap.put("msg", "");
        resultMap.put("count", total);
        resultMap.put("data", accounts);

        return resultMap;
    }



    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("{id}")
    public ResponseEntity<SysUserInfo> queryById(@PathVariable("id") Integer id) {
        return ResponseEntity.ok(this.sysUserInfoService.queryById(id));
    }

    /**
     * 新增页面初始化
     *
     * @return
     */
//    @RequiresPermissions("user:add")
    @ApiOperation(value = "用户新增页面初始化", notes = "用户新增页面初始化")
    @RequestMapping(value = "/forAdd", method = RequestMethod.GET)
    public String forAdd(Model model) {
        return "userinfo/add";
    }

    @Resource
    private SFTYProperties sftyProperties;

    /**
     * 新增
     *
     * @return
     */
//    @RequiresPermissions("system:user:add")
    @ApiOperation(value = "用户新增", notes = "用户新增")
    @RequestMapping(value = "/doAdd", method = RequestMethod.POST)
    @ResponseBody
    public BaseResult doAdd(SysUserInfo userInfo,
                            @RequestParam(required = false, defaultValue = "", value = "postStr") String postStr) {
        // 再进行加密两次，才是正确密码
        String digestHex = MD5.create().digestHex(salt + sftyProperties.getInitPassword());
        String password = SHA256Utils.SHA256Encode(digestHex);
        userInfo.setPassword(password);
        userInfo.setCreateUser(getSysUserId());
        int num = sysUserInfoService.insert(userInfo);
        if (num > 0) {
            //绑定岗位
            int num2 = sysUserPostService.userPostBind(userInfo.getUserId(), postStr);
            return BaseResult.success("新增用户成功!");
        } else if (num == -1) {
            return BaseResult.failure("该账号已存在!");
        } else {
            return BaseResult.failure("新增用户失败!");
        }
    }

    /**
     * 修改页面初始化
     *
     * @return
     */
//    @RequiresPermissions("system:user:edit")
    @ApiOperation(value = "用户修改页面初始化", notes = "用户修改页面初始化")
    @RequestMapping(value = "/forUpdate/{userId}", method = RequestMethod.GET)
    public String forUpdate(Model model, @PathVariable Integer userId) {
        // 获取下拉栏枚举值
        List<Map<String, String>> baseDictList = sysDictInfoService.queryByCode("user_status");
        SysUserInfo userInfo = sysUserInfoService.queryById(userId);
//        userInfo.setUserPost("2,3");
//        userInfo.setUserPostName("总经理,组长");

//        userInfo.setAvatarPreUrl(storageService.getExpiryUrlById(userInfo.getAvatar(), 24));

        model.addAttribute("baseDictList", baseDictList);
        model.addAttribute("userInfo", userInfo);
        return "userinfo/update";
    }

    /**
     * 查看页面
     *
     * @return
     */
//    @RequiresPermissions("system:user:edit")
    @ApiOperation(value = "用户修改页面初始化", notes = "用户修改页面初始化")
    @RequestMapping(value = "/forView/{userId}", method = RequestMethod.GET)
    public String forView(Model model, @PathVariable Integer userId) {
        SysUserInfo userInfo = sysUserInfoService.queryById(userId);
        String deptName = userInfo.getDeptName();
        if (userInfo.getDeptName1() != null)
            deptName = userInfo.getDeptName1() + " / " + deptName;
        if (userInfo.getDeptName2() != null)
            deptName = userInfo.getDeptName2() + " / " + deptName;
        userInfo.setDeptName(deptName);

        Map<String, String> paraMap = new HashMap<>();
        paraMap.put("userId", userId.toString());
        List<SysUserPost> listPost = sysUserPostService.getUserPostList(paraMap);

        String postName = "";
        for (int i = 0; i < listPost.size(); i++) {
            SysUserPost up = listPost.get(i);
            if (!postName.isEmpty())
                postName += "，";
            postName += up.getPostName();
        }
        userInfo.setUserPostName(postName);
        if (userInfo.getSex().equals("1"))
            userInfo.setSex("男");
        else if (userInfo.getSex().equals("2"))
            userInfo.setSex("女");
        userInfo.setStatus(userInfo.getStatus().equals("0") ? "正常" : "锁定");
        model.addAttribute("userInfo", userInfo);

        return "userinfo/view";
    }

    /**
     * 批量删除系统用户
     *
     * @return
     */
//    @RequiresPermissions("user:delete")
    @ApiOperation(value = "批量删除系统用户", notes = "批量删除系统用户")
    @RequestMapping(value = "/batchDelete", method = RequestMethod.POST)
    @ResponseBody
    public BaseResult batchDelete(@RequestBody String data) {
        if (logger.isInfoEnabled()) {
            logger.info("batchDelete -- data：" + data);
        }
        List<Integer> userIdList = JsonTool.parseArray(data, Integer.class);
        if (logger.isInfoEnabled()) {
            logger.info("batchDelete -- idList：{}", userIdList);
        }
        int a = 0;
        Map<Object,Object> map =new HashMap<>();
        // 批量判断 问题
        // 判断删除人员是否有部门信息
        if (userIdList.size() > 0){
            for (int i =0 ; i<userIdList.size();i++){
                // 查询当前人员岗位是非为空
                map.put("id",userIdList.get(i));
                List<SysUserInfo> sysUserInfos = sysUserInfoService.getSysUserInfoList(map);
                if (sysUserInfos.size()==1 && sysUserInfos.get(0).getUserPostName() == null){
                    int num = sysUserInfoService.batchDelete(userIdList, getSysUserId());
                    if (num > 0) {
                        a++;
                        continue;
                    }
                }
            }
        }
        if (a == 0){
            return BaseResult.failure(-1,"删除失败!请先删除当前人员岗位信息！");
        }
        return BaseResult.success("删除成功");
    }

    /**
     * 删除一个系统用户（这里后面可能会改为逻辑删除）
     *
     * @return
     */
//    @RequiresPermissions("user:delete")
    @ApiOperation(value = "删除一个系统用户", notes = "删除一个系统用户")
    @RequestMapping(value = "/delete/{userId}", method = RequestMethod.GET)
    @ResponseBody
    public BaseResult delete(@PathVariable Integer userId) {
        boolean flag = sysUserInfoService.deleteById(userId, getSysUserId());
        if (flag) {
            return BaseResult.success("删除用户成功!");
        } else {
            return BaseResult.failure("删除用户失败!");
        }
    }

    //    @RequiresPermissions(value = {"user:add", "user:edit"}, logical = Logical.OR)
    @ApiOperation(value = "根据用户id查询岗位信息", notes = "根据用户id查询岗位信息")
    @RequestMapping(value = "/listPostByUserId", method = RequestMethod.GET)
    @ResponseBody
    public Object listPostByUserId(@RequestParam(required = false, defaultValue = "", value = "userId") Integer userId) {
        return sysUserPostService.listPostByUserId(userId);
    }

    //    @RequiresPermissions("user:exportExcel")
    @ApiOperation(value = "导出全部用户数据到excel", notes = "导出全部用户数据到excel")
    @RequestMapping(value = "/exportExcel", method = RequestMethod.GET)
    @ResponseBody
    public void exportExcel(HttpServletResponse response) {
        if (logger.isInfoEnabled()) {
            logger.info("SysUserInfoController -- exportExcel -- start");
        }
        List<SysUserInfo> userInfoList = sysUserInfoService.getSysUserInfoList(new HashMap<>());
        Map<String, String> userStatus = sysDictInfoService.getDictMap("user_status");
        Map<String, String> userSex = sysDictInfoService.getDictMap("user_sex");
        for (SysUserInfo userInfo : userInfoList) {
            String sex = userInfo.getSex();
            sex = userSex.get(sex);
            userInfo.setSex(sex);
            String status = userInfo.getStatus();
            status = userStatus.get(status);
            userInfo.setStatus(status);
        }

        List<String> listName = Arrays.asList("账号", "姓名", "电话", "性别", "状态", "创建时间", "更新时间");
        List<Map<String, String>> list = new ArrayList<>();
        for (SysUserInfo userInfo : userInfoList) {
            Map<String, String> map = new HashMap<>();
            map.put("账号", userInfo.getAccount());
            map.put("姓名", userInfo.getName());
            map.put("电话", userInfo.getPhone());
            map.put("性别", userInfo.getSex());
            map.put("状态", userInfo.getStatus());
            map.put("创建时间", userInfo.getCreateTime().toString());
            map.put("更新时间", userInfo.getUpdateTime().toString());
            list.add(map);
        }

        ExcelPoiUtil.excelPort("系统用户信息", listName, list, null, response);
    }

    /**
     * 描述：下载用户导入excel模板
     *
     * @param response
     * @param req
     * @throws Exception
     */
    @ApiOperation(value = "下载用户导入excel模板", notes = "下载用户导入excel模板")
    @RequestMapping(value = "/downloadTemplate", method = RequestMethod.GET)
    @ResponseBody
    public void downloadTemplate(HttpServletResponse response, HttpServletRequest req) throws Exception {
        String filename = "sys_user_template.xlsx";
        InputStream inputStream = null;
        ServletOutputStream servletOutputStream = null;
        try {

            String path = "static/excel/";
            org.springframework.core.io.Resource resource = resourceLoader.getResource("classpath:" + path + filename);

            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(filename, StandardCharsets.UTF_8.toString());
            response.setHeader("Content-Disposition", "attachment; filename=\"" + encodeName + "\"; filename*=utf-8''" + encodeName);

            inputStream = resource.getInputStream();
            servletOutputStream = response.getOutputStream();
            IOUtils.copy(inputStream, servletOutputStream);
            response.flushBuffer();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (servletOutputStream != null) {
                    servletOutputStream.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 用户修改
     *
     * @return
     */
//    @RequiresPermissions("user:edit")
    @ApiOperation(value = "用户信息修改", notes = "用户信息修改")
    @RequestMapping(value = "/doUpdate", method = RequestMethod.POST)
    @ResponseBody
    public BaseResult doUpdate(SysUserInfo userInfo,
                               @RequestParam(required = false, defaultValue = "", value = "postStr") String postStr) {

        userInfo.setUpdateUser(getSysUserId());
        int num = sysUserInfoService.update(userInfo);
        if (num > 0) {
            //绑定岗位
            int num2 = sysUserPostService.userPostBind(userInfo.getUserId(), postStr);
            return BaseResult.success("修改用户成功!");
        } else {
            return BaseResult.failure("修改用户失败!");
        }
    }

    /**
     * 用户密码修改
     *
     * @return
     */
//    @RequiresPermissions("system:user:editpassword")
    @ApiOperation(value = "用户密码修改", notes = "用户密码修改")
    @RequestMapping(value = "/updatePassword/{userId}/{password}", method = RequestMethod.GET)
    @ResponseBody
    public BaseResult updatePassword(@PathVariable(value = "userId") Integer userId,
                                     @PathVariable(value = "password") String password) {
        SysUserInfo userInfo = new SysUserInfo();
        userInfo.setUserId(userId);
        // 再进行加密两次，才是正确密码
        password = SHA256Utils.SHA256Encode(password);
        userInfo.setPassword(password);
        int num = sysUserInfoService.resetPass(userInfo);
        if (num > 0) {
            return BaseResult.success("密码修改成功!");
        } else {
            return BaseResult.failure("密码修改失败!");
        }
    }

    @ApiOperation(value = "导入excel模板", notes = "导入excel模板")
    @RequestMapping(value = "/excelUpload", method = RequestMethod.POST)
    @ResponseBody
    public BaseResult excelUpload(@RequestParam("files") MultipartFile excelFile) throws IOException {
        if (excelFile.isEmpty()) {
            return BaseResult.failure("文件为空");
        } else {
            String fileSuffix = excelFile.getOriginalFilename();
            if (StringUtils.isNotBlank(fileSuffix) && fileSuffix.endsWith(".xlsx")) {
                String message = "";
                int errorNum = 0;
                int okNum = 0;
                StringBuilder errorMsg = new StringBuilder();

                /*根据文件格式解析文件*/
                List<SysUserInfo> list = new ArrayList<>();

                InputStream is = excelFile.getInputStream();
                XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);

                // 循环工作表Sheet
                // 循环行Row
                XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);
                for (int rowNum = 2; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
                    XSSFRow xssfRow = xssfSheet.getRow(rowNum);
                    if (xssfRow != null) {
                        SysUserInfo entity = new SysUserInfo();
                        XSSFCell accountCell = xssfRow.getCell(0);
                        if (accountCell == null) {
                            errorNum += 1;
                            errorMsg.append("第").append(rowNum + 1).append("行（数据）格式错误,不能为空&");
                            continue;
                        }
                        accountCell.setCellType(CellType.STRING);
                        if (StringUtils.isBlank(accountCell.getStringCellValue())) {
                            errorNum += 1;
                            errorMsg.append("第").append(rowNum + 1).append("行（数据）格式错误,不能为空&");
                            continue;
                        }
                        entity.setAccount(accountCell.getStringCellValue());


                        entity.setStatus("0");
                        entity.setDelFlag("0");
                        entity.setCreateUser(getSysUserId());
                        list.add(entity);
                        okNum += 1;
                    }
                }
                message = "导入结果:&成功导入" + okNum + "条数据 失败" + errorNum + "条&错误记录:&"
                        + errorMsg.toString();
                if (null != is) {
                    is.close();
                }
                // 后续待完善，先测试成功可以解析，暂不做插库处理

                if (logger.isInfoEnabled()) {
                    logger.info("excelUpload -- list：{}", list);
                }
                return BaseResult.success(message, list);
            } else {
                return BaseResult.failure("文件格式错误，请重试");
            }
        }
    }

    //    @RequiresPermissions("system:user:authorize")
    @ApiOperation(value = "用户角色授权页面初始化", notes = "用户角色授权页面初始化")
    @RequestMapping(value = "/authorize/{userId}", method = RequestMethod.GET)
    public String authorize(Model model, @PathVariable Integer userId) {
        SysUserInfo userInfo = sysUserInfoService.getOneById(userId);
        model.addAttribute("userInfo", userInfo);
        return "userinfo/auth";
    }

    //    @RequiresPermissions("system:user:authorize")
    @ApiOperation(value = "根据用户id赋予用户角色", notes = "根据用户id赋予用户角色")
    @RequestMapping(value = "/doAuthorize", method = RequestMethod.POST)
    @ResponseBody
    public BaseResult doAuthorize(@RequestParam("userId") Integer userId,
                                  @RequestParam("roles") String roles) {
        return sysUserRoleService.doAuthorize(userId, roles);
    }

    //    @RequiresPermissions("system:user:authorize")
    @ApiOperation(value = "根据用户id查询用户角色", notes = "根据用户id查询用户角色")
    @RequestMapping(value = "/listRoleByUserId/{userId}", method = RequestMethod.GET)
    @ResponseBody
    public Object listRoleByUserId(@PathVariable Integer userId) {
        return sysUserRoleService.listRoleByUserId(userId);
    }

    @ResponseBody
    @RequestMapping(value = "/userList", method = RequestMethod.POST)
    public Object userList(@RequestParam(required = false, defaultValue = "", value = "name") String name) {
        Map<String, String> paraMap = new HashMap<>();
        paraMap.put("name", name);
        List<SysUserInfo> accounts = sysUserInfoService.getSysUserInfoList(paraMap);

        PageInfo<SysUserInfo> pageinfo = new PageInfo<>(accounts);
        //取出查询结果
        List<SysUserInfo> rows = pageinfo.getList();
        int total = (int) pageinfo.getTotal();

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("code", 0);
        resultMap.put("msg", "");
        resultMap.put("count", rows);
        resultMap.put("data", total);

        return resultMap;
    }

}

