package com.winsun.utils;



import java.io.Serializable;

import java.util.HashMap;

import java.util.Queue;
import java.util.concurrent.TimeUnit;

import com.winsun.auth.core.base.tips.ErrorTip;


import com.winsun.auth.core.shiro.ShiroUser;
import com.winsun.auth.model.user.User;
import com.winsun.item.core.shiro.ShiroKit;

import org.apache.commons.collections4.map.PassiveExpiringMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import com.winsun.item.core.common.constant.cache.RedisCacheKey;

import com.winsun.item.core.common.exception.PasswordErrorException;
import com.winsun.item.core.log.LogManager;
import com.winsun.item.core.log.factory.LogTaskFactory;
import com.winsun.item.core.shiro.CustomToken;


import static com.winsun.auth.core.support.HttpKit.getIp;


public class AccLoginUtil {

	private static final int MAX_SESSION_SIZE = 5;

	private static Logger log = LoggerFactory.getLogger(AccLoginUtil.class);

	public  static String msg = "账号或密码或验证码错误，若重复多次错误请联系管理员。";
	
	/**
	 * 普通登录
	 * @param subStaffId
	 * @param staffPwd
	 * @param user
	 * @return
	 * @throws Exception 
	 */
	public static Object normalLogin(String subStaffId,String staffPwd,User user,String ipAddr,RedisTemplate<String, Object> redisTemplate,String exprie){
		try {
			
			Integer ipValue = (Integer) redisTemplate.opsForValue().get(RedisCacheKey.PASSWORD_ERROR_KEY + subStaffId);
			if(ipValue != null && ipValue >= 4) {
				throw new PasswordErrorException();
			}
			
	        if (!user.getPassword().equals(ShiroKit.md5(staffPwd, user.getSalt()))) {
	        	Long ipProhibition = ipProhibition(subStaffId, redisTemplate, exprie);
	        	//return new ErrorTip(500, "账号密码错误"+ ipProhibition +"次！连续输入错误5次，将被冻结！");
	        	return new ErrorTip(500, msg);
	        }
			
			CustomToken adminPasswordToken = new CustomToken(subStaffId, staffPwd);
			return subjectLogin(adminPasswordToken,ipAddr);
	        
		} 
		catch (PasswordErrorException e) {
			//return new ErrorTip(500, "账号密码连续输入错误5次，已被冻结！");
			return new ErrorTip(500, msg);
		}
		catch (Exception e) {
			//return new ErrorTip(500, e.getMessage());
			return new ErrorTip(500, msg);
		}
		
	}

	/**
	 * 登录操作
	 * @param token
	 * @return
	 * @throws Exception
	 */
	public static HashMap<String, Object> subjectLogin(CustomToken token,String ipAddr) throws Exception{
		Subject currentUser = ShiroKit.getSubject();
        currentUser.login(token);
        Serializable sessionId = ShiroKit.getSession().getId();

        ShiroUser shiroUser = ShiroKit.getUser();
        if(StringUtils.isNoneBlank(ipAddr)) {
        	LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), ipAddr));
        }else {
        	LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp()));
        }
        //LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp()));
        ShiroKit.getSession().setAttribute("sessionFlag", true);
        
        HashMap<String, Object> result = new HashMap<>();
/*
		String account = shiroUser.getAccount();
		Queue<Session> queue = sessionMapQueue.get(account);
		if (queue == null) {
			queue = new LinkedList<>();
			queue.offer(ShiroKit.getSession());
			sessionMapQueue.put(account,queue);
		} else {
			if (queue.size() == MAX_SESSION_SIZE) {
				Session pollSession = queue.poll();
				pollSession.setTimeout(1);
			}
			queue.offer(ShiroKit.getSession());
		}
*/
        result.put("sessionId", sessionId.toString());
        result.put("currentUser", shiroUser.getName());
        result.put("phone", shiroUser.getPhone());
        result.put("account", shiroUser.getAccount());
        result.put("dept", shiroUser.getDeptName());
        result.put("deptId", shiroUser.getDeptId());
        result.put("substName",shiroUser.getSubstName());
        result.put("role", shiroUser.getRoleNames());
        result.put("subType", shiroUser.getSubTypeList());
		result.put("salestaffId", shiroUser.getSalestaffId());
        if (shiroUser.getXfyfJson() != null) {
			result.put("xfyf", shiroUser.getXfyfJson());
		}
		if (shiroUser.getYfpqJson() != null) {
			result.put("yfpq", shiroUser.getYfpqJson());
		}

		if (shiroUser.getOperatorsList()!= null && shiroUser.getOperatorsList().size()!=0) {
			result.put("operators",shiroUser.getOperatorsList());
		}
        result.put("code", 200);
        result.put("message", "登陆成功！");
        return result;
	}
	
	
	public static Long ipProhibition(String account,RedisTemplate<String, Object> redisTemplate,String exprie) throws PasswordErrorException,Exception {
		synchronized (account) {
			Integer ipValue = (Integer) redisTemplate.opsForValue().get(RedisCacheKey.PASSWORD_ERROR_KEY + account);
			if(ipValue == null) {
				redisTemplate.opsForValue().set(RedisCacheKey.PASSWORD_ERROR_KEY + account, 1, Long.valueOf(exprie), TimeUnit.SECONDS);
				return (long) 1;
			}else {
				Long increment = redisTemplate.opsForValue().increment(RedisCacheKey.PASSWORD_ERROR_KEY + account, 1);
				if(ipValue.intValue() >= 5) {
					throw new PasswordErrorException();
				}
				return increment;
			}
		}
	}
	
	public static Long imageProhibition(String account,RedisTemplate<String, Object> redisTemplate) throws PasswordErrorException,Exception {
		synchronized (account) {
			Integer ipValue = (Integer) redisTemplate.opsForValue().get(RedisCacheKey.VALID_IMAGE_ERROR_KEY + account);
			if(ipValue == null) {
				redisTemplate.opsForValue().set(RedisCacheKey.VALID_IMAGE_ERROR_KEY + account, 1, Long.valueOf(60), TimeUnit.SECONDS);
				return (long) 1;
			}else {
				Long increment = redisTemplate.opsForValue().increment(RedisCacheKey.VALID_IMAGE_ERROR_KEY + account, 1);
				if(ipValue.intValue() >= 3) {
					throw new PasswordErrorException();
				}
				return increment;
			}
		}
	}

}
