package com.fdkankan.platform.user.service.sso;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fdkankan.common.constant.ConstantFilePath;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.constant.ServerCode;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.user.SSOLoginHelper;
import com.fdkankan.common.user.SSOUser;
import com.fdkankan.common.util.*;
import com.fdkankan.platform.user.entity.User;
import com.fdkankan.platform.user.request.RequestUser;
import com.fdkankan.platform.user.service.IUserService;
import com.fdkankan.platform.user.vo.SSOUserVo;
import com.fdkankan.redis.util.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class LoginService {

    @Autowired
    RedisUtil redisUtil;
    @Autowired
    private IUserService userService;
    @Autowired
    private SSOLoginHelper ssoLoginHelper;
    @Autowired
    private MsgService msgService;
    @Value("${main.url}")
    private String mainUrl;


    public SSOUserVo login(RequestUser param) {
        if (StringUtils.isEmpty(param.getPassword()) || StringUtils.isEmpty(param.getPhoneNum())){
            throw new BusinessException(ErrorCode.MISSING_REQUIRED_PARAMETERS);
        }
        User dbUser = userService.getUserByUserName(param.getPhoneNum());
        SSOUser ssoUser = userService.getSsoUserByUserName(dbUser,param.getPhoneNum());
        if(ssoUser == null){
            throw new BusinessException(ErrorCode.USER_NOT_EXIST);
        }
        //对前端传的密码解密
        String password = Base64Converter.decode(Base64Converter.subText(param.getPassword()));
        String token = this.commonLogin(ssoUser,password);
        this.removeTimeOutToken(param.getPhoneNum(),token);
        return  userService.getUserInfoByUser(param.getCameraType(), dbUser,token);
    }


    public SSOUserVo quickLogin(RequestUser param) {
        User dbUser = msgService.checkMsgAuth(param);
        SSOUser ssoUser = userService.getSsoUserByUserName(dbUser,param.getPhoneNum());
        String token = ssoLoginHelper.login(ssoUser);
        removeTimeOutToken(param.getPhoneNum(),token);
        return  userService.getUserInfoByUser( param.getCameraType(), dbUser,token);
    }


    private void removeTimeOutToken(String phone,String token){
        JSONArray tokenArray = new JSONArray();
        JSONArray removeArray = new JSONArray();
        JSONObject tokenJson = new JSONObject();
        Long time = 0L;
        if(redisUtil.hasKey(SsoUtil.USER_TOKEN + phone)){
            tokenArray = JSONArray.parseArray(redisUtil.get(SsoUtil.USER_TOKEN + phone));
            for(int i = 0, len = tokenArray.size(); i < len; i++){
                JSONObject json = tokenArray.getJSONObject(i);
                time = json.getLong("time");
                if((System.currentTimeMillis() - time) / (1000 * 3600 * 24) > 2){
                    ssoLoginHelper.logout(json.getString("token"));
                    removeArray.add(json);
                }
            }
            if(removeArray.size() > 0){
                tokenArray.remove(removeArray);
            }
            tokenJson.put("token", token);
            tokenJson.put("time", System.currentTimeMillis());
            tokenArray.add(tokenJson);
            redisUtil.set(SsoUtil.USER_TOKEN + phone, tokenArray.toString());
        }else {
            tokenJson.put("token", token);
            tokenJson.put("time", System.currentTimeMillis());
            tokenArray.add(tokenJson);
            redisUtil.set(SsoUtil.USER_TOKEN + phone, tokenArray.toString());
        }
    }

    public String logout(String token) {
        ssoLoginHelper.logout(token);
        return ServerCode.SUCCESS.message();
    }


    public String loginCheck(String token) {
        SSOUser ssoUser = ssoLoginHelper.loginCheck(token);
        if (ssoUser == null){
            throw new BusinessException(ErrorCode.USER_NOT_LOGIN);
        }
        return  ServerCode.SUCCESS.message();
    }


    public String checkSms(String token, String msgAuthCode) {
        SSOUser ssoUser = ssoLoginHelper.loginCheck(token);
        if (ssoUser == null){
            throw new BusinessException(ErrorCode.USER_NOT_LOGIN);
        }
        String codeValue = redisUtil.get(SsoUtil.PREFIX_MSG_AUTH_CODE + ssoUser.getUserName());
        if (StringUtils.isEmpty(codeValue)){
            throw new BusinessException(ErrorCode.V_CODE_ERROR);
        }
        if (!codeValue.equals(msgAuthCode)){
            throw new BusinessException(ErrorCode.V_CODE_ERROR);
        }
        return ServerCode.SUCCESS.message();
    }

    public String getToken(String phoneNum, String password) {
        if (StringUtils.isEmpty(phoneNum) || StringUtils.isEmpty(password)){
            throw new BusinessException(ErrorCode.MISSING_REQUIRED_PARAMETERS);
        }
        User userByUserName = userService.getUserByUserName(phoneNum);
        if (userByUserName == null){
            throw new BusinessException(ErrorCode.USER_NOT_EXIST);
        }
        SSOUser ssoUser = userService.getSsoUserByUserName(userByUserName, phoneNum);

        return this.commonLogin(ssoUser,password);
    }


    public JSONObject createLoginQrCode() throws Exception{
        String uuid = NumberUtils.getUUID();
        String filePath = ConstantFilePath.LOGIN_QR_CODE_PATH + uuid + ".png";
        MatrixToImageWriterUtil.createQRCode(mainUrl + "app/index.html?m="+uuid, filePath, true, null);
        JSONObject json = new JSONObject();
        json.put("url", filePath.replace(ConstantFilePath.BASE_PATH, ""));
        json.put("uuid", uuid);
        return json;
    }

    public JSONObject loginQrCode(String uuid) {
        if (StringUtils.isEmpty(uuid)){
            throw new BusinessException(ErrorCode.MISSING_REQUIRED_PARAMETERS);
        }
        if (!redisUtil.hasKey(uuid)){
            throw new BusinessException(ErrorCode.USER_NOT_LOGIN);
        }
        String childName = redisUtil.get(uuid);
        SSOUser dbUser = new SSOUser();
        dbUser.setUserName(childName);
        String token = ssoLoginHelper.login(dbUser);
        JSONObject object = new JSONObject();
        object.put("token", token);
        object.put("childName", childName);
        object.put("to", 1);
        redisUtil.del(uuid);
        //删除二维码图片
        FileUtils.deleteFile(ConstantFilePath.LOGIN_QR_CODE_PATH + uuid + ".png");
        return object;
    }


    private String commonLogin(SSOUser ssoUser,String password){
        String passwordCode = SecurityUtil.MD5(password);
        if (!passwordCode.equals(ssoUser.getPassword())){
            throw new BusinessException(ErrorCode.PASSWORD_ERROR);
        }
        return ssoLoginHelper.login(ssoUser);
    }
}
