package com.ylcm.sys.controller;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.alibaba.excel.EasyExcel;
import com.ylcm.sys.common.Constants;
import com.ylcm.sys.common.ExcelUtil;
import com.ylcm.sys.common.LoginUtil;
import com.ylcm.sys.common.Util;
import com.ylcm.sys.domain.Role;
import com.ylcm.sys.domain.User;
import com.ylcm.sys.excel.listener.BaseExcelListener;
import com.ylcm.sys.excel.model.UserExportDTO;
import com.ylcm.sys.excel.model.UserImportDTO;
import com.ylcm.sys.service.RoleService;
import com.ylcm.sys.service.UserService;

import net.sf.json.JSONObject;

/**
 * 用户
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
@Controller
public class UserController extends BaseController {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private UserService userService;

	@Autowired
	private RoleService roleService;
	
	/**
	 * 跳转-用户列表
	 * 
	 * @return 用户列表页面
	 */
	@RequestMapping(value = "/userlist.do")
	public String userList(ModelMap model) {
		model.put("menu", "user");
		model.put("parentMenu", "admin");
		/**
		 * 1.初始化角色下拉框
		 */
		List<Role> roleList = roleService.getRoleList();
		model.put("roleList", roleList);
		/**
		 * 2.跳转到列表页面
		 */
		return "user/user_list";
	}

	/**
	 * ajax检索列表
	 * 
	 * @param response
	 *            请求返回参数
	 * @param loginName
	 *            登录名
	 * @param nickName
	 *            昵称
	 * @param userType
	 *            用户类型
	 * @param status
	 *            状态
	 * @param pageNo
	 *            页码
	 * @param pageSize
	 *            页面大小
	 */
	@RequestMapping(value = "/ajaxSearchUserList.do")
	public void ajaxSearchList(HttpServletRequest request,HttpServletResponse response, String loginName,
			String nickName,String telephone,String email, Integer userSex 
			,Integer userRole, Integer pageNo, Integer pageSize) {

		try {
			/**
			 * 1、组装查询条件map
			 */
			Map map = new HashMap();
			map.put("loginName", loginName);
			map.put("nickName", nickName);
			map.put("telephone", telephone);
			map.put("email", email);
			map.put("sex", userSex);
			map.put("userRole", userRole);
			/**
			 * 1.获取信息列表总数
			 */
			int count = userService.getRowCount(map);
			List<User> userList = new ArrayList<User>();
			
			if(count > 0){
				/**
				 * 保存查询条件，用于导出EXCEL
				 */
				request.getSession().setAttribute(Constants.USER_SEARCH_PARAMETERS, map);
				
				pageSize = Util.isNull(pageSize) ? 10 : pageSize;
		        pageNo = Util.isNull(pageNo) ? 1 : pageNo;
		        map.put("pageIndex", (pageNo - 1) * pageSize);
		        map.put("pageSize", pageSize);
				/**
				 * 2.获取信息列表
				 */
				userList = userService.getUserList(map);
			}
			
			/**
			 * 3.返回结果
			 */
			JSONObject jsonobj = new JSONObject();
			jsonobj.put("count", count);
			jsonobj.put("code", 1);
			jsonobj.put("list", userList);
			ajaxJson(jsonobj.toString(), response);
		} catch (Exception e) {

			/**
			 * 4.获取信息列表失败，返回结果
			 */
			logger.error(e.getMessage());
			ajaxJson("{\"code\":\"0\",\"msg\":\"获取用户信息列表失败\"}", response);
		}

	}

	/**
	 * 添加用户-页面跳转
	 * 
	 * @param model
	 * @return 添加用户页面
	 */
	@RequestMapping(value = "/adduser.do")
	public String addUser(ModelMap model) {

		/**
		 * 1.初始化角色下拉框、跳转到添加页面
		 */
		List<Role> roleList = roleService.getRoleList();
		model.put("roleList", roleList);
		return "user/add_user";
	}

	/**
	 * 保存用户
	 * 
	 * @param response
	 *            请求返回参数
	 * @param loginName
	 *            登录名
	 * @param loginPwd
	 *            登录密码
	 * @param nickName
	 *            昵称
	 * @param roleId
	 *            角色id
	 * @param remark
	 *            备注
	 */
	@RequestMapping(value = "/saveuser.do")
	public void saveUser(HttpServletResponse response, String loginName,
			String loginPwd, String nickName,Integer sex,String telephone,String email, int roleId) {

		try {

			if (userService.getCheckUser(loginName) >= 1) {

				/**
				 * 1.如果登录名已存在,返回结果
				 */
				ajaxJson("{\"code\":\"0\",\"msg\":\"登录名已存在\"}", response);
			} else {

				/**
				 * 2.登录名不存在时,创建实体
				 */
				User user = new User();
				user.setLoginName(loginName);

				/**
				 * 密码加密
				 */
				user.setLoginPwd(LoginUtil.generatePassword(loginPwd));
				user.setNickName(nickName);
				user.setEmail(email);
				user.setTelephone(telephone);
				user.setSex(sex);

				/**
				 * 设置用户类型：系统用户
				 */
				user.setStatus(Constants.STATUS_USER_NORMAL);
				Timestamp timestamp = new Timestamp(new Date().getTime());
				user.setCrtTime(timestamp);
				user.setUpdTime(timestamp);

				/**
				 * 3.调用保存接口
				 */
				userService.addUser(user, null);

				/**
				 * 4.增加用户角色关联
				 */
				if (user.getUid() > 0) {
					roleService.delUserRolesByUserId(user.getUid());
					roleService.addUserRole(user.getUid(), roleId);
				}

				/**
				 * 5.添加成功，返回结果
				 */
				ajaxJson("{\"code\":\"1\",\"msg\":\"添加用户成功\"}", response);
			}
		} catch (Exception e) {

			/**
			 * 6.添加失败，返回结果
			 */
			logger.error(e.getMessage());
			ajaxJson("{\"code\":\"0\",\"msg\":\"添加用户失败\"}", response);
		}

	}

	/**
	 * 修改用户-页面跳转
	 * 
	 * @param uid
	 *            用户id
	 * @param model
	 * @return 修改用户页面
	 */
	@RequestMapping(value = "/edituser.do")
	public String editUser(int uid, ModelMap model) {

		/**
		 * 1.初始化角色下拉框
		 */
		List<Role> roleList = roleService.getRoleList();

		/**
		 * 2.查寻用户信息
		 */
		User user = new User();
		user = userService.getUserById(uid);

		/**
		 * 3.返回页面
		 */
		model.put("roleList", roleList);
		model.put("user", user);
		return "user/update_user";
	}

	/**
	 * 更新用户
	 * 
	 * @param response
	 *            请求返回参数
	 * @param uid
	 *            用户id
	 * @param loginName
	 *            登录名
	 * @param nickName
	 *            昵称
	 * @param roleId
	 *            角色id
	 * @param remark
	 *            备注
	 */
	@RequestMapping(value = "/updateuser.do")
	public void updateUser(HttpServletResponse response, int uid,
			String loginName, String nickName,String telephone,String loginPwd,String email,Integer sex, int roleId) {

		try {

			if (userService.getUserByLoginNameNeId(uid, loginName) >= 1) {

				/**
				 * 1.如果登录名已存在,返回结果
				 */
				ajaxJson("{\"code\":\"0\",\"msg\":\"登录名已存在\"}", response);
			} else {

				/**
				 * 2.根据uid获取用户对象
				 */
				User user = userService.getUserById(uid);

				if (user == null) {
					ajaxJson("{\"code\":\"0\",\"msg\":\"用户不存在\"}", response);
				}

				/**
				 * 3.修改实体
				 */
				user.setLoginName(loginName);
				user.setNickName(nickName);
				user.setEmail(email);
				user.setTelephone(telephone);
				if(Util.isNotNull(loginPwd)){
					user.setLoginPwd(LoginUtil.generatePassword(loginPwd));
				}
				user.setSex(sex);
				user.setUpdTime(new Timestamp(new Date().getTime()));

				/**
				 * 4.调用修改接口
				 */
				userService.updUser(user);

				/**
				 * 5.增加用户角色关联
				 */
				if (user.getUid() > 0) {
					roleService.delUserRolesByUserId(user.getUid());
					roleService.addUserRole(user.getUid(), roleId);
				}

				/**
				 * 6.返回结果
				 */
				ajaxJson("{\"code\":\"1\",\"msg\":\"修改用户成功\"}", response);
			}
		} catch (Exception e) {
			e.printStackTrace();
			/**
			 * 7.修改失败，返回结果
			 */
			ajaxJson("{\"code\":\"0\",\"msg\":\"修改用户失败\"}", response);
		}

	}

	/**
	 * 删除用户
	 * 
	 * @param response
	 *            请求返回参数
	 * @param uids
	 *            用户id
	 */
	@RequestMapping(value = "/deleteuser.do")
	public void deleteUser(HttpServletResponse response, String uids) {

		try {
			if(Util.isNotNull(uids)){
				/**
				 * 1.调用修改状态接口（假删）
				 */
				userService.delUsersByIds(uids.split(","));
			}else{
				ajaxJson("{\"code\":\"0\",\"msg\":\"参数异常\"}", response);
			}
			/**
			 * 2.返回结果
			 */
			ajaxJson("{\"code\":\"1\",\"msg\":\"删除用户成功\"}", response);
		} catch (Exception e) {

			/**
			 * 3、删除失败，返回结果
			 */
			logger.error(e.getMessage());
			ajaxJson("{\"code\":\"0\",\"msg\":\"删除用户失败\"}", response);
		}

	}

	/**
	 * 密码修改-跳转
	 * 
	 * @return 修改密码页面
	 */
	@RequestMapping(value = "/pwdupdate.do")
	public String pwdUpdate() {

		/**
		 * 1.跳转到密码修改页面
		 */
		return "user/password";
	}

	/**
	 * 密码修改
	 * 
	 * @param request
	 *            请求参数
	 * @param response
	 *            返回请求参数
	 * @param password
	 *            旧密码
	 * @param new_password
	 *            新密码
	 */
	@RequestMapping(value = "/updpassword.do")
	public void pwdUpdate(HttpServletRequest request,
			HttpServletResponse response, String password, String new_password) {

		/**
		 * 1、从session中获取用户对象
		 */
		User user = (User) request.getSession().getAttribute("manager");

		if (!LoginUtil.generatePassword(password).equals(user.getLoginPwd())) {

			/**
			 * 2、当前登录密码错误时，返回修改页面
			 */
			ajaxJson("{\"code\":\"0\",\"msg\":\"当前登录密码错误\"}", response);
		} else {

			try {

				/**
				 * 3、调用修改密码接口
				 */
				userService.updatePwd(user.getUid(),
						LoginUtil.generatePassword(new_password));

				/**
				 * 4.修改成功,跳转到密码修改页面
				 */
				ajaxJson("{\"code\":\"1\",\"msg\":\"密码修改成功\"}", response);

			} catch (Exception e) {

				/**
				 * 5、删除失败，返回结果
				 */
				logger.error(e.getMessage());
				ajaxJson("{\"code\":\"0\",\"msg\":\"密码修改失败\"}", response);
			}

		}
	}

	/**
	 * 修改状态
	 * 
	 * @param response
	 *            请求返回参数
	 * @param uid
	 *            用户id
	 * @param status
	 *            状态
	 */
	@RequestMapping(value = "/updUserStatus.do")
	public void updUserStatus(HttpServletResponse response, int uid, int status) {

		try {

			/**
			 * 1.调用修改状态接口
			 */
			userService.updUserStatus(uid, status);

			/**
			 * 2.返回结果
			 */
			ajaxJson("{\"code\":\"1\",\"msg\":\"修改用户状态成功\"}", response);
		} catch (Exception e) {

			/**
			 * 3、修改用户状态失败，返回结果
			 */
			logger.error(e.getMessage());
			ajaxJson("{\"code\":\"0\",\"msg\":\"修改用户状态失败\"}", response);
		}

	}
	
	
	/**
	 * 导入用户数据
	 * @author liushiming
	 * @param uploadfile 文件名
	 * @return
	 */
	@RequestMapping(value = "uploadExcelForUser.do")
	public String uploadExcelForRatingTime(HttpServletRequest request, HttpServletResponse response, MultipartFile uploadfile) {
		int status = 0;
		String msg = Constants.MSG_FAIL;
		try {
			MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
			MultipartFile excelFile = multipartRequest.getFile("uploadfile");
			String fileType = excelFile.getContentType();
			if (fileType == null || !Constants.EXCEL_TYPES.contains(fileType)) {
				status = Constants.CODE_FAIL;
				msg = Constants.MSG_EXCEL_TYPE_ERROR;
			}else {
				BaseExcelListener<UserImportDTO> listener = new BaseExcelListener<>();
	            EasyExcel.read(uploadfile.getInputStream(), UserImportDTO.class,listener).sheet().doRead();
	            List<UserImportDTO> dtos = listener.getDataList();
	            if(CollectionUtils.isEmpty(dtos)) {
                    request.setAttribute("code", status);
	                request.setAttribute("msg", "表格数据为空！");
	                return "common/import_callback";
	            }
	            dtos.stream().forEach(x -> x.check());
	        	int index = 2; //表格从第二行开始
	            for(UserImportDTO dto: dtos) {
                    index ++;
	            	if (StringUtils.isNotBlank(dto.getMsg())) {
	            		request.setAttribute("code", status);
	            		request.setAttribute("msg", "第"+ index + "行" + dto.getMsg());
	            		return "ajax/excel_upload_callback";
	            	}
	            }
	            msg = userService.importUserBatch(dtos);
	            // 判断执行结果
	            if("ok".equals(msg)) {
	                request.setAttribute("code", Constants.CODE_SUCCESS);
	                request.setAttribute("msg", "上传成功");
	                return "common/import_callback";
	            }
			}
		} catch (Exception e) {
			logger.error("uploadExcelForUser.do error:"+ e.getMessage(), e);
		    if(e.getMessage().contains("行，")) {
            	msg = e.getMessage();
            }
		}
		request.setAttribute("code", status);
		request.setAttribute("msg", msg);
		return "ajax/excel_upload_callback";
	}
	
	/**
	 * to 当前用户的信息页
	 * @author liuyu
	 * */
    @RequestMapping(value = "current_account.do")
	public String toCurrentAccount(HttpServletRequest request, HttpServletResponse response) {
	    return "user/current_account";
	}
    
    @RequestMapping(value = "/user_export.do")
    public void export(String loginName,
			String nickName,String telephone,String email, Integer userSex, Integer userRole, 
			HttpServletRequest request, HttpServletResponse response) {
    	
		Map map = new HashMap();
		map.put("loginName", loginName);
		map.put("nickName", nickName);
		map.put("telephone", telephone);
		map.put("email", email);
		map.put("sex", userSex);
		map.put("userRole", userRole);
		
		
		ExcelUtil.exportExcelToWebsite(response,"用户列表",new UserExportDTO(),(currentPage, pageSize) -> {
	        map.put("pageIndex", (currentPage - 1) * pageSize);
	        map.put("pageSize", pageSize);
			return toExport(userService.getUserList(map));
		});
    }
    
    private List<UserExportDTO> toExport(List<User> users) {
    	if (CollectionUtils.isEmpty(users)) {
			return new ArrayList<UserExportDTO>();
		}
    	List<UserExportDTO> exportDTOs = new ArrayList<UserExportDTO>();
    	
    	for (User user : users) {
    		UserExportDTO userExportDTO = new UserExportDTO();
    		BeanUtils.copyProperties(user, userExportDTO);
    		userExportDTO.setRole(user.getRoleName());
    		
    		if (user.getSex() == 0) {
    			userExportDTO.setSex("男");
			} else if (user.getSex() == 1) {
				userExportDTO.setSex("女");
			}
    		
    		exportDTOs.add(userExportDTO);
		}
    	
    	return exportDTOs;
    }
	
}
