package com.dcit.authority.controller;

import com.dcit.authority.config.JwtConfig;
import com.dcit.authority.dto.SysUserBasicInfoDTO;
import com.dcit.authority.dto.UserRoleMenuInfoDTO;
import com.dcit.authority.dto.form.LoginForm;
import com.dcit.authority.exception.AuthException;
import com.dcit.authority.service.SysRoleService;
import com.dcit.authority.service.SysUserService;
import com.dcit.authority.utils.JsonWebTokenUtil;
import com.dcit.common.enums.ResultEnum;
import com.dcit.common.utils.ResultVOUtil;
import com.dcit.common.vo.ResultVO;
import io.jsonwebtoken.SignatureAlgorithm;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
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 java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 帐号登录API
 * 
 * @author zhangzhizhong
 *
 */
@Api(value="登录认证API")
@RestController
@RequestMapping("/account")
@Slf4j
public class AccountController {

	@Autowired
	private StringRedisTemplate stringRedisTemplate;

	@Autowired
	private RedisTemplate redisTemplate;
	
	@Autowired
	private SysUserService sysUserService;
	
	@Autowired
	private SysRoleService sysRoleService;
	
	@Autowired
	private JwtConfig jwtConfig;

	@ApiOperation(value = "用户登录")
	@PostMapping("/login")
	public ResultVO<Object> accountLogin(@RequestBody LoginForm loginForm) {
		
		ModelMap map = new ModelMap();
		
		try {
			// 根据account获取其对应所拥有的角色(这里设计为角色对应资源，没有权限对应资源)
			String roles = sysUserService.loadAccountRole(loginForm.getAccount());
			
			// 时间以秒计算,token有效刷新时间是token有效过期时间的2倍
			/*long refreshPeriodTime = 36000L;
			String jwt = JsonWebTokenUtil.issueJWT(UUID.randomUUID().toString(), loginForm.getAccount(), "token-server",
					refreshPeriodTime >> 1, roles, null, SignatureAlgorithm.HS512);*/
			// 将签发的JWT存储到Redis： {JWT-SESSION-{appID} , jwt}
			//redisTemplate.opsForValue().set("JWT-SESSION-" + loginForm.getAccount(), jwt, refreshPeriodTime, TimeUnit.SECONDS);
			
			SysUserBasicInfoDTO sysUserBasicInfoDTO = sysUserService.getUserByAccount(loginForm.getAccount());
			
			List<UserRoleMenuInfoDTO> resTree = new ArrayList<UserRoleMenuInfoDTO>();
			
			if(null != sysUserBasicInfoDTO && !StringUtils.isEmpty(sysUserBasicInfoDTO.getRoleId())){
				
				Map<String, Object> mapParam = new HashMap<String, Object>();
				mapParam.put("roleId", sysUserBasicInfoDTO.getRoleId());
				mapParam.put("resourceType", "MENU");
				
				List<UserRoleMenuInfoDTO> dtoList = sysRoleService.selectUserRoleMenuByRoleId(mapParam);
				
				for(UserRoleMenuInfoDTO dto : dtoList){
					if(!StringUtils.isEmpty(dto.getParentId()) && dto.getParentId().equals("0")){
						resTree.add(dto);
					}
				}
				
				for(UserRoleMenuInfoDTO pTree : resTree){
					List<UserRoleMenuInfoDTO> childTree = new ArrayList<UserRoleMenuInfoDTO>();
					for(UserRoleMenuInfoDTO dto : dtoList){
						if(!StringUtils.isEmpty(dto.getParentId()) && dto.getParentId().equals(pTree.getResourceId())){
							childTree.add(dto);
						}
					}
					pTree.setChildren(childTree);
				}
			}
			
			sysUserBasicInfoDTO.setRoleMenuList(resTree);
			
			// 时间以秒计算
			String jwt = JsonWebTokenUtil.issueJWT(UUID.randomUUID().toString(), sysUserBasicInfoDTO.getUid(), loginForm.getAccount(), jwtConfig.getIssuer(),
					jwtConfig.getPeriod(), roles, null, SignatureAlgorithm.HS256);
			
			// 将签发的JWT存储到Redis： {JWT-SESSION-{appID} , jwt}
			stringRedisTemplate.opsForValue().set(JsonWebTokenUtil.REDIS_PREFIX + loginForm.getAccount(), jwt, jwtConfig.getPeriod(), TimeUnit.HOURS);
			redisTemplate.opsForValue().set(loginForm.getAccount(),sysUserBasicInfoDTO,jwtConfig.getPeriod(), TimeUnit.HOURS);
			map.put("token", jwt);
			map.put("userInfo", sysUserBasicInfoDTO);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("【用户登录】操作出错,error={}",e.getMessage());
			throw new AuthException(ResultEnum.LOGIN_FAIL);
		}

		return ResultVOUtil.success(map);
		
	}

}
