/**
 * Copyright (c) 2018 人人开源 All rights reserved.
 * 
 * https://www.renren.io
 * 
 * 版权所有,侵权必究!
 */
package com.zt.security.service;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zt.common.constant.Constant;
import com.zt.common.servlet.Result;
import com.zt.common.utils.CacheUtils;
import com.zt.core.context.User;
import com.zt.core.context.UserContext;
import com.zt.core.shiro.TokenGenerator;
import com.zt.core.sys.model.SysDept;
import com.zt.core.sys.model.SysUser;
import com.zt.modules.sys.service.SysDeptService;
import com.zt.modules.sys.service.SysUserService;
import com.zt.security.dao.SysUserTokenDao;
import com.zt.security.model.SysUserToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.*;
/**
 * 用户Token
 *
 * @author Mark sunlightcs@gmail.com
 */
@Service
public class SysUserTokenService extends ServiceImpl {
    @Autowired
    SysDeptService deptService;
    @Autowired
    SysUserService sysUserService;
    @Value("${data.test}")
    private Boolean test;
    @Autowired
    private RedisTemplate redisTemplate;
    @Value("${spring.cache.type}")
    private String type;
    @Value("${data.tokenTimeout}")
    private Long tokenTimeout;
    private final static int EXPIRE = 3600; //秒
    @Cacheable(value = Constant.Cache.TOKEN, key = "'token:' + #token")
    public SysUserToken getByToken(String token) {
        return baseMapper.getByToken(token);
    }
    /**
     * 生成token
     *
     * @param userId 用户ID
     */
    public Result createToken(Long userId, String systemMarker, String token) {
        // 用户token
        // String token;
        String roleNames = sysUserService.getRoleNames(userId);
        // 当前时间
        Date now = new Date();
        // 过期时间
        Date expireTime = new Date(now.getTime() + tokenTimeout * 60 * 1000);
        // 判断是否生成过token
        SysUserToken tokenEntity = baseMapper.getByUserId(userId);
        if (tokenEntity == null) {
            // 生成一个token
            if (token == null || "".equals(token)) {
                token = TokenGenerator.generateValue();
            }
            tokenEntity = new SysUserToken();
            tokenEntity.setUserId(userId);
            tokenEntity.setToken(token);
            tokenEntity.setUpdateDate(now);
            tokenEntity.setExpireDate(expireTime);
            tokenEntity.setSystemMarker(systemMarker);
            tokenEntity.setRoleName(roleNames);
/*            User user = new User();
            user.setRealName("zhangsan");
            user.setPassword("123");
            List roleIdList = new ArrayList<>();
            roleIdList.add(1L);
            roleIdList.add(2L);
            roleIdList.add(3L);
            user.setRoleIdList(roleIdList);
            user.setRoleName("444");
            tokenEntity.setUser(user);*/
            // 保存token
            if (!"redis".equals(type))
                baseMapper.insert(tokenEntity);
        } else {
            // 判断token是否过期
            if (token == null || "".equals(token)) {
/*                if (tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()) {
                    // token过期,重新生成token
                    token = TokenGenerator.generateValue();
                } else {*/
                    token = tokenEntity.getToken();
                //}
            }
            tokenEntity.setToken(token);
            tokenEntity.setUpdateDate(now);
            tokenEntity.setExpireDate(expireTime);
            tokenEntity.setSystemMarker(systemMarker);
            tokenEntity.setRoleName(roleNames);
/*            User user = new User();
            user.setRealName("zhangsan");
            user.setPassword("123");
            List roleIdList = new ArrayList<>();
            roleIdList.add(1L);
            roleIdList.add(2L);
            roleIdList.add(3L);
            user.setRoleIdList(roleIdList);
            user.setRoleName("444");
            tokenEntity.setUser(user);*/
            // 更新token
            if (!"redis".equals(type))
                this.updateById(tokenEntity);
        }
        if ("redis".equals(type)) {
            String jsonString = JSONObject.toJSONString(tokenEntity);
            redisTemplate.opsForValue().set(token, jsonString);
        }
        CacheUtils.removeAll(Constant.Cache.TOKEN);
        //CacheUtils.remove(Constant.Cache.TOKEN,token);
        //CacheUtils.put(Constant.Cache.TOKEN,token,tokenEntity);
        SysUser user = sysUserService.get(userId);
        Integer secretClass = user.getSecretClass();
        Map map = new HashMap<>();
        map.put(Constant.Sys.TOKEN_HEADER, token);
        map.put("expire", EXPIRE);
        map.put("test", test);
        map.put("roleName", roleNames);
        map.put("userSecretClass", secretClass);
        map.put("info", "OK");
        loginProcess();
        return Result.ok().ok(map);
        //return Result.ok();
    }
    /**
     * 退出,修改token值
     *
     * @param userId 用户ID
     */
    public void logout(Long userId) {
        // 生成一个token
        String token = TokenGenerator.generateValue();
        // 修改token
        baseMapper.updateToken(userId, token);
    }
    /**
     * 用户login成功后,依据用户的sysDept部门id来进行相关session设置。
     * 这些session设置值后面在字典过滤和业务数据查询时候会作为数据权限逻辑处理的依据。
     */
    public void loginProcess() {
        String arear = "";
        User user = UserContext.getUser();
        SysDept sysDept = deptService.get(user.getDeptId());
        SysDept parent = null;
        String[] pids = null;
        if (sysDept != null && sysDept.getPids() != null) {
            pids = sysDept.getPids().split(",");
        }
        if (pids != null && pids.length > 0) {
            for (String pid : pids) {
                parent = deptService.get(new Long(pid));
                if (parent != null && "qd".equals(parent.getCode())) {
                    arear = "qd";
                } else if (parent != null && "sy".equals(parent.getCode())) {
                    arear = "sy";
//                } else if (parent != null && (parent.getCode().equals("qdcj") || parent.getCode().equals("sycj"))) {
//                    factoryId = user.getCompanyId().toString();
//                } else if (parent != null && parent.getName().equals("T")) {
//                    shipId = user.getCompanyId().toString();
                }
            }
        }
        user.setArea(arear);
    }
}