package cn.com.countrygarden.bi.main.repository;

import java.util.*;

import cn.com.countrygarden.bi.main.exception.ServiceException;
import cn.com.countrygarden.bi.main.model.AccessToken;
import cn.com.countrygarden.bi.main.model.twerp.hm.TbSysUser;
import cn.com.countrygarden.bi.main.service.AccessTokenService;
import cn.com.countrygarden.bi.main.service.twerp.hm.TbSysUserService;
import cn.com.countrygarden.bi.main.util.MD5;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.sunshine.common.repository.DataRepositoryJDBC;

@Repository("userRepository")
public class UserRepository extends DataRepositoryJDBC {


    @Autowired
    private UserRoleRepository userRoleRepository;
    @Autowired
    private SysOrgRepository sysOrgRepository;

    protected AccessToken currentAccessToken;
    protected Map<String, Object> currentUser;

    @Autowired
    protected AccessTokenService accessTokenService;

    @Autowired
    private TbSysUserService tbSysUserService;


    public UserRepository() {
        this.masterTable = "[HM_wygl_new_1853].[dbo].[Tb_Sys_User]";
    }

    /**
     * 用户登录
     *
     * @param loginCode
     * @param password
     * @return
     */
    public Map<String, Object> login(String loginCode, String password) {
        Map<String, Object> user = new HashMap<>();
        TbSysUser tbSysUser = tbSysUserService.findByLogin(loginCode, password);
        log.info("userCode: " + tbSysUser);
        if (tbSysUser.getUserCode() == null) {
            throw new ServiceException("用户不存在！");
        }

        String salt = genSalt();
        String userCode = user.get("UserCode").toString();
        loginCode = user.get("LoginCode").toString();
        // 生成身份令牌
        String accessToken = genAccessToken(
                userCode,
                loginCode,
                user.get("PassWord").toString(),
                salt
        );

        // 更新身份令牌 SQL Server，弃用
        //updateAccessToken(userCode, accessToken, salt);
        // 更新身份令牌 MySQL
        /*accessTokenMapper.insertOrUpdate(new HashMap<String, String>() {{
            put("userCode", userCode);
            put("accessToken", accessToken);
            put("salt", salt);
        }});*/
        accessTokenService.insertOrUpdate(new HashMap<String, String>() {{
            put("userCode", userCode);
            put("accessToken", accessToken);
            put("salt", salt);
        }});

        user.put("assessToken", accessToken);
        user.put("accessToken", accessToken);
        user.remove("PassWord");

        // 用户角色
        user.put("userRole", userRoleRepository.findByUserCode(userCode));
        user.put("sysOrgan", sysOrgRepository.findByOrganCode(user.get("OrganId").toString()));

        return user;
    }

    /**
     * 退出登录
     *
     * @return
     */
    public void logout() {
        accessTokenService.updateAccessToken(new HashMap<String, String>() {{
            put("userCode", currentUser.get("UserCode").toString());
            put("accessToken", currentAccessToken.getAccessToken().toString());
        }});
    }

    /**
     * 校验身份令牌
     *
     * @param accessToken
     * @return
     */
    public boolean validateAccessToken(String accessToken) {
        if (accessToken == null || "null".equals(accessToken) || "".equals(accessToken)) {
            throw new ServiceException("缺少身份令牌");
        }

        AccessToken userAccessToken = accessTokenService.getAccessToken(new HashMap<String, String>() {{
            put("accessToken", accessToken);
        }});
        if (userAccessToken == null) {
            throw new ServiceException("无效的身份令牌");
        }

        Map<String, Object> user = findByPK(userAccessToken.getUserCode());
        if (user.isEmpty()) {
            throw new ServiceException("用户不存在");
        }

        String sign = genAccessToken(
                userAccessToken.getUserCode(),
                user.get("LoginCode").toString(),
                user.get("PassWord").toString(),
                userAccessToken.getSalt()
        );

        if (!sign.equals(accessToken)) {
            throw new ServiceException("身份令牌校验失败");
        }

        // TODO 失效时间检查

        this.currentAccessToken = userAccessToken;
        this.currentUser = user;

        return true;
    }

    /**
     * 获取当前用户 access_token
     *
     * @return
     */
    public String getCurrentUserAccessToken() {
        return currentAccessToken.getAccessToken();
    }

    /**
     * 获取登录用户记录
     *
     * @param userCode
     * @return
     */
    public Map<String, Object> findByPK(String userCode) {
        List paramList = new ArrayList();
        paramList.add(userCode);

        String sql = "SELECT u.UserCode, u.UserName, u.LoginCode, u.PassWord, u.CommID, u.DepCode, u.Memo, u.OrganId " +
                "FROM " + this.masterTable + " AS u " +
                "WHERE u.IsDelete = 0 AND u.UserCode = ?";
        return this.jdbcTemp.queryForMap(sql, paramList.toArray());
    }

    /**
     * 获取登录用户记录
     *
     * @param loginCode
     * @param password
     * @return
     */
    public TbSysUser findByLogin(String loginCode, String password) {
        TbSysUser tbSysUser = tbSysUserService.findByLogin(loginCode, password);

        return tbSysUser;
        /*Map<String, Object> user = new HashMap<>();
        try {
            List paramList = new ArrayList();
            paramList.add(loginCode);
            paramList.add(password);

            String sql = "SELECT u.UserCode, u.UserName, u.LoginCode, u.PassWord, u.CommID, u.DepCode, u.Memo, u.OrganId " +
                    "FROM " + this.masterTable + " AS u " +
                    "WHERE u.IsDelete = 0 AND u.LoginCode = ? AND u.PassWord = ?";
            user = this.jdbcTemp.queryForMap(sql, paramList.toArray());
        } catch (Exception e) {
            log.info(e.getClass() + " User: " + loginCode + " not found");
            e.printStackTrace();
        }

        return user;*/
    }

    /**
     * 生成盐值
     *
     * @return
     */
    private String genSalt() {
        return UUID.randomUUID().toString().replace("-", "").substring(0, 16).toUpperCase();
    }

    /**
     * 生成身份令牌 accessToken
     *
     * @param userCode
     * @param loginCode
     * @param password
     * @param salt
     * @return
     */
    private String genAccessToken(String userCode, String loginCode, String password, String salt) {
        String accessToken = "" + userCode + loginCode + password + salt;
        String hashAccessToken = MD5.GetMD5Code(accessToken).toUpperCase();
        return hashAccessToken;
    }
}
