package com.ximai.framework.web.service;


import com.ximai.common.constant.Constants;
import com.ximai.common.core.domain.AjaxResult;
import com.ximai.common.core.domain.AjaxResult2;
import com.ximai.common.core.domain.entity.SysUser;
import com.ximai.common.core.domain.model.LoginUser;
import com.ximai.common.core.redis.RedisCache;
import com.ximai.common.exception.ServiceException;
import com.ximai.common.exception.user.UserPasswordNotMatchException;
import com.ximai.common.utils.DictUtils;
import com.ximai.common.utils.MessageUtils;
import com.ximai.common.utils.data.StringUtils;
import com.ximai.framework.manager.AsyncManager;
import com.ximai.framework.manager.factory.AsyncFactory;
import com.ximai.system.domain.LoginParams;
import com.ximai.system.service.ISysRoleService;
import com.ximai.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * 移动端登录服务接口
 */
@Component
public class MobileLoginService {

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

    @Autowired(required = false)
    private TokenService tokenService;

    @Autowired(required = false)
    private SysLoginService sysLoginService;

    @Autowired(required = false)
    private ISysRoleService sysRoleService;

    @Autowired(required = false)
    private AuthenticationManager authenticationManager;

    @Autowired(required = false)
    private ISysUserService sysUserService;

    @Autowired(required = false)
    private PermissionService permissionService;

    /**
     * 注入redis服务
     */
    @Autowired(required = false)
    private RedisCache redisCache;

    /**
     * 请求时间戳过期时间5分钟
     */
    private static final int REQUEST_TIME_OUT = 1000 * 60 * 5;


    /**
     * jwt密钥
     */
    @Value("${token.secret}")
    private String jwtSecretKey;

    public AjaxResult2 login(LoginParams loginParams) {
        log.debug("login and loginParams:{}", loginParams);

        // 用户验证
        Authentication authentication = null;
        try {
            authentication = authenticationManager
                    .authenticate(new UsernamePasswordAuthenticationToken(loginParams.getUsername(), loginParams.getPassword()));
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginParams.getUsername(), Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            } else {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginParams.getUsername(), Constants.LOGIN_FAIL, e.getMessage()));
                throw new ServiceException(e.getMessage());
            }
        }
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        //loginUser.setSource("app");
        SysUser user = loginUser.getUser();
        // 生成token
        String token = tokenService.createToken(loginUser);
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginParams.getUsername(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        sysLoginService.recordLoginInfo(user.getUserId());
        //判断用户是否存在管理员角色
        // 角色集合
        AjaxResult2 ajax = AjaxResult2.success("");
        ajax.put("token", token);
        //token过期时间
        ajax.put("expired", loginUser.getExpireTime());
        ajax.put("user", loginUser.getUser());
        ajax.put("isAgent", String.valueOf(true));
        return ajax;
    }

    /**
     * 发送注册验证码
     *
     * @param loginParams
     * @return
     */
    public static AjaxResult sendCode(LoginParams loginParams) {
        if (Objects.isNull(loginParams)) {
            return AjaxResult.error(-6, "参数为空");
        }
        // 验证验证码
        if (StringUtils.isBlank(loginParams.getPhoneNo())) {
            return AjaxResult.error(-6, "发送手机号不能为空");
        }
        String validCodeType = "2";
        if (StringUtils.isNotBlank(loginParams.getValidCodeType())) {
            validCodeType = loginParams.getValidCodeType();
        }
        try {
            //SysSmsSend sysSmsSend = sysSmsSendService.sendMessage(loginParams.getPhoneNo(),validCodeType,true);
            //String resultFlag = sysSmsSend.getResultFlag();
            String resultFlag = "n";
            if (resultFlag.equals("f")) {
                return AjaxResult.error(-6, "对不起手机号【" + loginParams.getPhoneNo() + "】发送短信失败：失败原因:");
            }
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
        AjaxResult ajax = AjaxResult.success("验证码发送成功");
        return ajax;
    }

    /**
     * 手机号验证码注册用户
     *
     * @param loginParams
     * @return
     */
    @Transactional(readOnly = false)
    public AjaxResult2 registerUser(LoginParams loginParams) {
        try {
            if (Objects.isNull(loginParams)) {
                return AjaxResult2.error(-6, "参数为空");
            }
            String phoneNo = loginParams.getPhoneNo();
            if (StringUtils.isBlank(phoneNo)) {
                return AjaxResult2.error(-6, "发送手机号不能为空");
            }
            String validCode = loginParams.getValidCode();
            if (StringUtils.isBlank(validCode)) {
                return AjaxResult2.error(-6, "验证码不能为空");
            }
            loginParams.setUsername(phoneNo);
            loginParams.setPassword(phoneNo);
            loginParams.setLoginType("1");
            return this.login(loginParams);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }


}
