package cn.palmte.work.controller.backend;

import cn.palmte.work.bean.ResponseMsg;
import cn.palmte.work.config.Constant;
import cn.palmte.work.model.Admin;
import cn.palmte.work.model.DeptRepository;
import cn.palmte.work.model.UserPositionRepository;
import cn.palmte.work.pojo.ModifyPasswordRequest;
import cn.palmte.work.service.AccountService;
import cn.palmte.work.service.AdminService;
import cn.palmte.work.service.SysRoleService;
import cn.palmte.work.utils.InterfaceUtil;
import cn.palmte.work.utils.Utils;
import cn.palmte.work.utils.excel.ExcelLogs;
import cn.palmte.work.utils.excel.ExcelUtil;
import cn.palmte.work.utils.excel.ExportUtils;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import top.jfunc.common.crypto.symmetric.DESAS;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Controller
@RequestMapping("/account")
public class AccountController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(AccountController.class);

    @Autowired
    private AccountService accountService;

    @Autowired
    private AdminService adminService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private DeptRepository deptRepository;

    @Autowired
    private UserPositionRepository userPositionRepository;

    @RequestMapping(value = "/updatePassword")
    @ResponseBody
    public ResponseMsg updatePassword(HttpServletRequest request, ModifyPasswordRequest modifyPasswordRequest) {
        ResponseMsg responseMsg = new ResponseMsg();
        try {
            String privateKey = (String) request.getSession().getAttribute(Constant.PRIVATEKEY);
            adminService.updatePassword(modifyPasswordRequest.getId(), modifyPasswordRequest.getPassword(),
                    modifyPasswordRequest.getNewPassword(), privateKey);
            responseMsg.setStatus(0);
            responseMsg.setMsg("密码修改成功");
        } catch (Exception e) {
            responseMsg.setStatus(1);
            responseMsg.setMsg("密码修改失败：" + e.getMessage());
        }
        return responseMsg;
    }

    @RequestMapping("/list")
    public String list(@RequestParam(value = KEYWORDS, required = false) String keywords,
                       @RequestParam(value = PAGE_NUMBER, defaultValue = DEFAULT_PAGE_NUMBER) int pageNumber,
                       @RequestParam(value = PAGE_SIZE, defaultValue = DEFAULT_PAGE_SIZE) int pageSize,
                       Map<String, Object> model) {
        // 初始化参数
        setModel(keywords, model);
        ConcurrentHashMap<String, String> searchInfo = getSearchInfo(keywords, model);
        model.put("roleList", sysRoleService.getAllEnableSysRole());
        model.put("deptList", deptRepository.findAll());
        model.put("positionList", userPositionRepository.findAll());
        model.put("pager", accountService.list(searchInfo, pageNumber, pageSize));
        return "/admin/account_list";
    }

    /**
     * 跳转到新增页面
     */
    @RequestMapping("/add")
    public String add(HttpServletRequest request, Map<String, Object> model) {
        genRSAKeyPair(request, model);
        model.put("userId", -1);
        model.put("account", new Admin());
        model.put("roleList", sysRoleService.getAllEnableSysRole());
        model.put("deptList", deptRepository.findAll());
        model.put("positionList", userPositionRepository.findAll());
        return "/admin/account_input";
    }

    /**
     * 跳转编辑页面
     */
    @RequestMapping("/edit")
    public String edit(@RequestParam("userId") int userId, Map<String, Object> model) {
        Admin admin = accountService.findUserById(userId);
        model.put("account", admin);
        model.put("userId", userId);
        model.put("roleList", sysRoleService.getAllEnableSysRole());
        model.put("deptList", deptRepository.findAll());
        model.put("positionList", userPositionRepository.findAll());
        return "/admin/account_input";
    }

    /**
     * 保存或更新用户
     */
    @RequestMapping("/save")
    public String save(@RequestParam("userId") int userId, Admin admin, HttpServletRequest request, Map<String, Object> model) throws IOException {
        if (admin.getRoleId() <= 0) {
            model.put("errorMessage", "角色不能为空！");
            return "/common/error";
        }
        //获取验证用户信息
        String message = accountService.validateUserExistInfo(userId, admin);
        if (StringUtils.isNotEmpty(message)) {
            model.put("errorMessage", message);
            return "/common/error";
        }

        try {
            HttpSession session = request.getSession();
            String privateKey = (String) session.getAttribute(Constant.PRIVATEKEY);

            accountService.saveOrUpdateAccount(userId, admin.getRoleId(), admin, privateKey);
        } catch (Exception e) {
            model.put("errorMessage", "保存账号出错！请联系管理员处理");
            return "/common/error";
        }
        return "redirect:/account/list";
    }

    /**
     * 启用、禁用用户
     */
    @RequestMapping("/changeStatus")
    public ResponseMsg changeStatus(Admin admin) {
        boolean locked = accountService.changeStatus(admin.getId(), admin.getEnabled());
        if (locked) {
            return ResponseMsg.buildSuccessMsg("操作成功");
        } else {
            return ResponseMsg.buildFailedMsg("操作失败");
        }
    }

    /**
     * 根据删除用户
     */
    @RequestMapping("/delete")
    @ResponseBody
    public ResponseMsg delete(@RequestParam("userId") int userId) {
        ResponseMsg responseMsg = new ResponseMsg();
        boolean deleted = accountService.deleteAccount(userId);

        if (deleted) {
            responseMsg.setStatus(0);
            responseMsg.setMsg("删除成功");
        } else {
            responseMsg.setStatus(1);
            responseMsg.setMsg("删除失败");
        }
        return responseMsg;
    }

    /**
     * 根据ID重置用户密码
     */
    @RequestMapping("/resetPassword")
    @ResponseBody
    public ResponseMsg resetPassword(@RequestParam("userId") int userId, HttpServletRequest request) {
        HttpSession session = request.getSession();
        String privateKey = (String) session.getAttribute(Constant.PRIVATEKEY);
        boolean flag = accountService.resetPassword(userId, privateKey);
        ResponseMsg responseMsg = new ResponseMsg();
        if (flag) {
            responseMsg.setStatus(0);
            responseMsg.setMsg("重置密码成功");
        } else {
            responseMsg.setStatus(1);
            responseMsg.setMsg("重置密码失败");
        }
        return responseMsg;
    }

    /**
     * 修改密码请求
     */
    @RequestMapping("/password")
    public String password(HttpServletRequest request, Map<String, Object> model) {
        Admin admin = adminService.getAdminById(InterfaceUtil.getAdminId());
        try {
            String id = new DESAS().encrypt(admin.getId().toString());
            model.put("userId", id);
        } catch (Exception e) {
            e.printStackTrace();
        }
        model.put("SysUser", admin);
        genRSAKeyPair(request, model);
        return "/admin/account_password";
    }

    private void setModel(@RequestParam(value = "keywords", required = false) String keywords, Map<String, Object> model) {
        model.put("roleType", "-1");
        model.put("keywords", keywords);
    }

    @RequestMapping("/export")
    public void export(@RequestParam(value = "keywords", required = false) String keywords, HttpServletResponse httpServletResponse) throws IOException {
        Map<String, String> searchInfo = getSearchInfo(keywords);
        downloadHeader(httpServletResponse, Utils.generateExcelName("人员信息"), "application/octet-stream");
        String[] headers = {"工号", "手机号码", "姓名", "常驻地", "一级部门", "直接主管", "职位", "角色名称", "公司邮件地址"};
        String[] exportColumns = {"userName", "telephone", "realName", "workLocation", "deptName", "directManager", "positionName", "roleName", "companyEmail"};
        ExportUtils.exportToExcel(headers, exportColumns, 1, 10000,
                httpServletResponse.getOutputStream(), (pN, pS) -> accountService.list(searchInfo, pN, pS).getList());
    }

    /**
     * 模板下载
     */
    @RequestMapping("/template")
    public void template(HttpServletResponse response) throws Exception {

        String[] headers = new String[]{"工号", "手机号码", "姓名", "常驻地", "一级部门", "直接主管", "职位", "角色名称", "公司邮件地址"};
        downloadHeader(response, Utils.generateExcelName("人员信息批量导入模板"));
        ExportUtils exportUtils = new ExportUtils(headers);
        exportUtils.write(response.getOutputStream());
    }

    /**
     * 批量导入
     */
    @RequestMapping("/batchImport")
    @ResponseBody
    public String batchImport(MultipartFile file) {
        try {
            ExcelLogs logs = new ExcelLogs();
            Collection<Map> maps = ExcelUtil.importExcel(Map.class, file.getInputStream(),
                    "yyyy/MM/dd HH:mm:ss", logs, 0);
            synchronized (this) {
                return JSON.toJSONString(accountService.check(maps));
            }
        } catch (OfficeXmlFileException | EncryptedDocumentException | InvalidFormatException e) {
            return JSON.toJSONString(ResponseMsg.buildFailedMsg("格式错误，请上传excel 2003/2007格式文件"));
        } catch (Exception e) {
            return JSON.toJSONString(ResponseMsg.buildFailedMsg("导入数据失败,请联系管理员"));
        }
    }

}
