package com.keao.edu.auth.web.controller;

import com.keao.edu.auth.api.dto.AuthUser;
import com.keao.edu.auth.api.entity.SysUser;
import com.keao.edu.auth.api.util.SecurityConstants;
import com.keao.edu.auth.api.util.SecurityUtils;
import com.keao.edu.auth.service.SysRoleService;
import com.keao.edu.auth.service.SysUserRoleService;
import com.keao.edu.auth.service.SysUserService;
import com.keao.edu.auth.web.controller.queryInfo.SysUserQueryInfo;
import com.keao.edu.common.controller.BaseController;
import com.keao.edu.common.exception.BizException;
import com.keao.edu.common.service.IdGeneratorService;
import com.keao.edu.im.api.client.ImFeignService;
import com.keao.edu.im.api.entity.ImResult;
import com.keao.edu.im.api.entity.ImUserModel;
import com.keao.edu.util.date.DateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.Date;

@RestController()
@RequestMapping("user")
@Api(tags = "会员服务")
public class UserController extends BaseController {

	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private SysRoleService sysRoleService;
	@Autowired
	private ImFeignService imFeignService;
	@Autowired
	private SysUserRoleService sysUserRoleService;
	@Autowired
	private IdGeneratorService smsCodeService;

	@ApiOperation(value = "分页查询用户信息")
	@ApiImplicitParams({ @ApiImplicitParam(name = "userType", value = "用户类型", required = false, dataType = "String"),
			@ApiImplicitParam(name = "createStartDate", value = "开始注册时间", required = true, dataType = "String"),
			@ApiImplicitParam(name = "createEndDate", value = "结束注册时间", required = true, dataType = "String") })
	@GetMapping(value = "/queryPage")
	@PreAuthorize("@pcs.hasPermissions('user/queryPage')")
	public Object queryPage(SysUserQueryInfo queryInfo) {
		return succeed(sysUserService.queryPage(queryInfo));
	}

	@ApiOperation(value = "查询用户信息接口")
	@GetMapping("/query")
	@PreAuthorize("@pcs.hasPermissions('user/query')")
	public Object query() {
		AuthUser user = SecurityUtils.getUser();
		if (user != null) {
			return succeed(sysUserService.get(user.getUserId()));
		}
		return failed();
	}

	@ApiOperation(value = "根据用户编号获取用户基本信息")
	@GetMapping("/getBasic")
	public Object getBasic(Integer userId) {
		if (userId == null) {
			return failed("参数校验异常");
		}
		return succeed(sysUserService.getBasic(userId));
	}

	@GetMapping(value = "/queryUserByPhone")
	public SysUser queryUserByPhone(String mobile) {
		return sysUserService.queryByPhone(mobile);
	}

	@GetMapping(value = "/noAuth/queryUserByPhone")
	public Object noAuthQueryUserByPhone(String mobile,String clientId) {
		String toUpperCase = clientId.toUpperCase();
		SysUser sysUser = sysUserService.queryByPhoneAndClient(mobile,toUpperCase);
		if(sysUser == null){
			return succeed(0);
		}
		return succeed(1);
	}

	@GetMapping(value = "/queryUserById/{userId}")
	public SysUser queryUserById(@PathVariable("userId") Integer userId) {
		return sysUserService.get(userId);
	}

	@PostMapping(value = "/updateSysUser", consumes = MediaType.APPLICATION_JSON_VALUE)
	public boolean updateSysUser(@RequestBody SysUser user) {
		user.setUpdateTime(new Date());
		sysUserService.update(user);
		return true;
	}

	@ApiOperation(value = "新增用户")
	@PreAuthorize("@pcs.hasPermissions('user/add')")
	@PostMapping(value = "/add", consumes = MediaType.APPLICATION_JSON_VALUE)
	public Object add(@RequestBody SysUser sysUser) {
		return succeed(sysUserService.add(sysUser));
	}

	@ApiOperation(value = "设置密码")
	@PostMapping(value = "/setPassword", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	@ApiImplicitParams({@ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String"),
			@ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String") })
	public Object setPassword(String password, String username) {
		if (StringUtils.isEmpty(password)) {
			return failed("参数校验失败");
		}
		AuthUser authUser = SecurityUtils.getUser();
		if (authUser == null) {
			return failed("获取用户信息失败");
		}
		SysUser sysUser = sysUserService.get(authUser.getUserId());
		if (sysUser == null) {
			return failed("用户不存在");
		}
		if(sysUser.getUserType().contains("TEACHER") || sysUser.getUserType().contains("SYSTEM")){
			sysUser.setRealName(username);
		}else {
			sysUser.setUsername(username);
		}
		if(StringUtils.isEmpty(sysUser.getImToken())){
			ImResult register = imFeignService.register(new ImUserModel(sysUser.getId().toString(), username, sysUser.getAvatar()));
			sysUser.setImToken(register.getToken());
		}
		password = new BCryptPasswordEncoder().encode(password);
		sysUser.setPassword(password);
		sysUser.setUpdateTime(new Date());
		sysUserService.update(sysUser);
		return succeed();
	}

	@ApiOperation(value = "修改密码")
	@PostMapping(value = "/updatePassword", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	@ApiImplicitParams({ @ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String"),
			@ApiImplicitParam(name = "authCode", value = "验证码", required = true, dataType = "String"),
			@ApiImplicitParam(name = "newPassword", value = "新密码", required = true, dataType = "String") })
	public Object updatePassword(String mobile, String authCode, String newPassword) {
		if (StringUtils.isEmpty(mobile) || StringUtils.isEmpty(authCode) || StringUtils.isEmpty(newPassword)) {
			return failed("参数校验异常");
		}
		SysUser sysUser = sysUserService.queryByPhone(mobile);
		if (sysUser == null) {
			return failed("用户不存在");
		}
		if (smsCodeService.verifyValidCode(mobile, authCode)) {
			String password = new BCryptPasswordEncoder().encode(newPassword);
			sysUser.setPassword(password);
			sysUser.setUpdateTime(new Date());
			sysUserService.update(sysUser);
			return succeed();
		} else {
			return failed("验证码错误");
		}
	}


	@ApiOperation(value = "修改手机号")
	@PostMapping(value = "/updatePhone")
	public Object updatePhone(String oldPhone, String authCode, String newPhone) {
		if (StringUtils.isEmpty(oldPhone) || StringUtils.isEmpty(authCode) || StringUtils.isEmpty(newPhone)) {
			return failed("参数校验异常");
		}
		if(oldPhone.equals(newPhone)){
			return failed("新旧手机号一致");
		}
		SysUser sysUser = sysUserService.queryByPhone(oldPhone);
		if (sysUser == null) {
			return failed("用户不存在");
		}
		SysUser newSysUser = sysUserService.queryByPhone(newPhone);
		if (newSysUser != null) {
			return failed("手机号被占用");
		}
		if (smsCodeService.verifyValidCode(newPhone, authCode)) {
			sysUser.setPhone(newPhone);
			sysUser.setUpdateTime(new Date());
			sysUserService.update(sysUser);
			return succeed();
		} else {
			return failed("验证码错误");
		}
	}

	@ApiOperation(value = "修改密码")
	@PostMapping(value = "/updatePassword2", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	@ApiImplicitParams({ @ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String"),
			@ApiImplicitParam(name = "userId", value = "用户编号", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "newPassword", value = "新密码", required = true, dataType = "String") })
	public Object updatePassword2(Integer userId, String mobile, String newPassword) {
		if (StringUtils.isEmpty(mobile) || userId == null || StringUtils.isEmpty(newPassword)) {
			return failed("参数校验异常");
		}
		SysUser sysUser = sysUserService.queryByPhone(mobile);
		if (sysUser == null) {
			return failed("用户不存在");
		}
		if (sysUser.getId().intValue() != userId) {
			return failed("非法操作");
		}
		String password = new BCryptPasswordEncoder().encode(newPassword);
		sysUser.setPassword(password);
		sysUser.setUpdateTime(new Date());
		sysUserService.update(sysUser);
		return succeed();
	}

	@ApiOperation(value = "修改用户")
	@PostMapping(value = "/update")
	public Object update(SysUser sysUser) {
		AuthUser user = SecurityUtils.getUser();
		if (user != null) {
			Date date = new Date();
			sysUser.setId(user.getUserId());
			sysUser.setUpdateTime(date);
			if(sysUser.getBirthdate() != null && DateUtil.daysBetween(sysUser.getBirthdate(),date) <= 0){
				throw new BizException("出生日期不可超过当前时间");
			}
			sysUserService.updateBaseInfo(sysUser);
			return succeed();
		}
		return failed();
	}

	@ApiOperation(value = "刷新token")
	@PostMapping(value = "/refreshImToken")
	public Object refreshImToken() {
		AuthUser user = SecurityUtils.getUser();
		if (user != null) {
			SysUser sysUser = sysUserService.get(user.getUserId());
			String username;
			if(sysUser.getUserType().contains("TEACHER") || sysUser.getUserType().contains("SYSTEM")){
				username = sysUser.getRealName();
			}else {
				username = sysUser.getUsername();
			}
			if(StringUtils.isEmpty(username)){
				return failed("获取Token失败: 用户名为空");
			}else {
				ImResult register = imFeignService.register(new ImUserModel(sysUser.getId().toString(), username, sysUser.getAvatar()));
				if(StringUtils.isEmpty(register.getToken())){
					return failed("获取Token失败: 请联系教务老师");
				}
				sysUser.setImToken(register.getToken());
				sysUserService.refreshImToken(sysUser);
				return succeed(register.getToken());
			}
		}
		return failed();
	}

	@ApiOperation(value = "校验用户手机号和密码")
	@GetMapping(value = "/checkUser")
	public Object checkUser(String phone,String password) {
		if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(password)){
			throw new BizException("请录入用户名和密码");
		}
		AuthUser user = SecurityUtils.getUser();
		if (user != null) {
			SysUser sysUser = sysUserService.get(user.getUserId());
			if(!sysUser.getPhone().equals(phone)){
				return failed("手机号校验失败");
			}
			if(new BCryptPasswordEncoder().matches(password,sysUser.getPassword())){
				return succeed();
			}else {
				return failed("密码校验失败");
			}
		}
		return failed();
	}

	@ApiOperation(value = "获取用户角色列表")
	@GetMapping("/getRole")
	@PreAuthorize("@pcs.hasPermissions('user/getRole')")
	public Object getRole() {
		AuthUser user = SecurityUtils.getUser();
		if (user != null) {
			return succeed(sysRoleService.findRoleByUserId(user.getUserId()));
		}
		return failed();
	}

	@ApiOperation(value = "用户角色新增")
	@ApiImplicitParams({ @ApiImplicitParam(name = "userId", value = "用户编号", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "roleIds", value = "角色id,逗号分隔", required = true, dataType = "String") })
	@PostMapping(value = "/addRole", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
	@PreAuthorize("@pcs.hasPermissions('user/addRole')")
	public Object getRole(String userId, String roleIds) {
		if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(roleIds)) {
			return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
		}
		sysUserRoleService.batchInsert(Integer.parseInt(userId), roleIds);
		return succeed();
	}

	@ApiOperation(value = "用户角色删除")
	@ApiImplicitParams({ @ApiImplicitParam(name = "userId", value = "用户编号", required = true, dataType = "Integer"),
			@ApiImplicitParam(name = "roleIds", value = "角色id,逗号分隔", required = true, dataType = "String") })
	@PostMapping(value = "/delRole", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
	@PreAuthorize("@pcs.hasPermissions('user/delRole')")
	public Object delRole(String userId, String roleIds) {
		if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(roleIds)) {
			return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
		}
		sysUserRoleService.batchDel(Integer.parseInt(userId), roleIds);
		return succeed();
	}
}
