package com.zhiqiyun.open.manager.controller;

import com.zhiqiyun.open.annotation.Permission;
import com.zhiqiyun.open.enmus.AccountType;
import com.zhiqiyun.open.enmus.PasswordType;
import com.zhiqiyun.open.enmus.UserState;
import com.zhiqiyun.open.manager.Result;
import com.zhiqiyun.open.manager.params.QueryUserParam;
import com.zhiqiyun.open.manager.params.SaveUserParam;
import com.zhiqiyun.open.models.RoleInfo;
import com.zhiqiyun.open.models.UserBaseInfo;
import com.zhiqiyun.open.models.UserLoginAccount;
import com.zhiqiyun.open.mybatis.paginator.domain.PageResult;
import com.zhiqiyun.open.service.OauthService;
import com.zhiqiyun.open.service.UserBaseInfoService;
import com.zhiqiyun.open.utils.RandomUtil;
import com.zhiqiyun.open.utils.ServletContext;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author jtoms
 */
@RestController
@RequestMapping("/user")
public class UserInfoController {

	@Autowired
	private UserBaseInfoService userBaseInfoService;

	@Autowired
	private OauthService oauthService;

	@Permission(value = "oauth.user.find", tags = "查询系统所有用户")
	@PostMapping("/findPage")
	public Result findRolePage(@RequestBody QueryUserParam params) {
		PageResult<UserBaseInfo> resultData = this.userBaseInfoService.findPage(params.getPageBounds(), params.getQueryWrapper());

		List<Map<String, Object>> listData = new ArrayList<>();
		for (UserBaseInfo info : resultData.getData()) {
			Map<String, Object> dataMap = new HashMap<>();
			dataMap.put("id", info.getId());
			dataMap.put("nickName", info.getNickName());
			dataMap.put("registerTime", info.getRegisterTime());
			dataMap.put("registerIp", info.getRegisterIp());
			dataMap.put("avatar", info.getAvatar());
			dataMap.put("state", info.getState());
			dataMap.put("gender", info.getGender());
			List<UserLoginAccount> loginAccounts = this.userBaseInfoService.findLoginAccounts(info.getId());
			for (UserLoginAccount account : loginAccounts) {
				dataMap.put(account.getAccountType().name(), account.getLoginAccount());
			}
			List<RoleInfo> listRoles = this.userBaseInfoService.findRoles(info.getId());
			dataMap.put("listRoles", listRoles);

			listData.add(dataMap);
		}

		Map<String, Object> dataMap = new HashMap<>();
		dataMap.put("data", listData);
		dataMap.put("total", resultData.getTotal());
		dataMap.put("pageSize", resultData.getPageSize());
		dataMap.put("current", resultData.getCurrent());
		return Result.instance(Result.Code.SUCCESS).setData(dataMap);
	}

	@Permission(value = "oauth.user.add", tags = "添加用户")
	@PostMapping("/save")
	public Result save(@Valid @RequestBody SaveUserParam param) throws Exception {
		return this.insertOrUpdate(null, param);
	}

	@Permission(value = "oauth.user.edit", tags = "修改用户")
	@PostMapping("/updateById")
	public Result updateById(Long id, @Valid @RequestBody SaveUserParam param) throws Exception {
		if (id == null || id <= 0) {
			return Result.instance("数据异常，请刷新页面后再试");
		}
		return this.insertOrUpdate(id, param);
	}

	private Result insertOrUpdate(Long uid, SaveUserParam param) throws Exception {
		List<UserLoginAccount> loginAccounts = new ArrayList<>();
		UserLoginAccount userNameAccount = this.userBaseInfoService.findLoginAccount(param.getUserName(), AccountType.userName);
		if (userNameAccount != null && !userNameAccount.getUid().equals(uid)) {
			return Result.instance("登录账号已被其他用户使用，请使更换登录账号");
		}
		loginAccounts.add(new UserLoginAccount(param.getUserName(), AccountType.userName));

		if (StringUtils.isNotBlank(param.getMp())) {
			UserLoginAccount mpAccount = this.userBaseInfoService.findLoginAccount(param.getMp(), AccountType.mp);
			if (mpAccount != null && !mpAccount.getUid().equals(uid)) {
				return Result.instance("手机号已被其他用户使用，请使更换手机号");
			}
			loginAccounts.add(new UserLoginAccount(param.getMp(), AccountType.mp));
		}

		if (StringUtils.isNotBlank(param.getEmail())) {
			UserLoginAccount emailAccount = this.userBaseInfoService.findLoginAccount(param.getEmail(), AccountType.email);
			if (emailAccount != null && !emailAccount.getUid().equals(uid)) {
				return Result.instance("邮箱已被其他用户使用，请使更换邮箱");
			}
			loginAccounts.add(new UserLoginAccount(param.getEmail(), AccountType.email));
		}

		UserBaseInfo userInfo = new UserBaseInfo();
		BeanUtils.copyProperties(param, userInfo);
		userInfo.setId(uid);
		userInfo.setRegisterIp(ServletContext.getRemoteIPAddress());
		String loginPassword = this.userBaseInfoService.insertOrUpdate(userInfo, loginAccounts);
		return Result.instance(Result.Code.MESSAGE_SUCCESS).setData(loginPassword);
	}


	@Permission(value = "oauth.user.disable", tags = "禁用用户")
	@PostMapping("/disable")
	public Result disable(@RequestBody List<Long> ids) {
		if (ids.contains(1000L)) {
			return Result.instance(Result.Code.MESSAGE_ERROR, "系统管理员不能禁用");
		}
		if (ids.isEmpty()) {
			return Result.instance(Result.Code.MESSAGE_ERROR, "请选择要禁用的用户");
		}
		for (Long uid : ids) {
			UserBaseInfo userInfo = new UserBaseInfo();
			userInfo.setId(uid);
			userInfo.setState(UserState.disable);
			this.userBaseInfoService.updateById(userInfo);
		}
		return Result.instance(Result.Code.MESSAGE_SUCCESS);
	}

	@Permission(value = "oauth.user.enable", tags = "启用用户")
	@PostMapping("/enabled")
	public Result enabled(@RequestBody List<Long> ids) {
		if (ids.isEmpty()) {
			return Result.instance(Result.Code.MESSAGE_ERROR, "请选择要启用的用户");
		}
		for (Long uid : ids) {
			UserBaseInfo userInfo = new UserBaseInfo();
			userInfo.setId(uid);
			userInfo.setState(UserState.normal);
			this.userBaseInfoService.updateById(userInfo);
		}
		return Result.instance(Result.Code.MESSAGE_SUCCESS);
	}

	@Permission(value = "oauth.user.reset.login.password", tags = "重置用户密码")
	@PostMapping("/resetLoginPassword")
	public Result resetPasswd(@RequestBody Long[] ids) {
		String password = RandomUtil.get(6);
		for (Long uid : ids) {
			String salt = RandomUtil.getSalt();
			String hashPassword = this.oauthService.generatePassword(password, salt);
			this.userBaseInfoService.updatePassword(uid, hashPassword, salt, PasswordType.login);
		}
		return Result.instance(Result.Code.MESSAGE_SUCCESS).setData(password);
	}


	@Permission(value = "oauth.user.set.role", tags = "设置用户角色")
	@PostMapping("/saveRoles")
	public Result saveRoles(Long uid, @RequestBody Long[] roles) throws Exception {
		if (uid.equals(1000L)) {
			return Result.instance(Result.Code.MESSAGE_ERROR, "默认的用户不能修改角色");
		}
		this.userBaseInfoService.saveRoles(uid, roles);
		return Result.instance(Result.Code.MESSAGE_SUCCESS);
	}

	@Permission(tags = "搜索用户信息")
	@PostMapping(value = "/findSelectAccounts")
	public Result findSelectAccounts(String searchKey) {
		List<Map<String, Object>> listData = this.userBaseInfoService.findSelectAccounts(searchKey);
		return Result.instance(Result.Code.SUCCESS).setData(listData);
	}
}
