package com.fdkankan.ucenter.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.fdkankan.common.constant.AppConstant;
import com.fdkankan.common.constant.CameraConstant;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.util.JwtUtil;
import com.fdkankan.common.util.RandomUtil;
import com.fdkankan.common.util.SecurityUtil;
import com.fdkankan.redis.constant.RedisKey;
import com.fdkankan.redis.util.RedisUtil;
import com.fdkankan.sign.AesUtil;
import com.fdkankan.ucenter.common.RedisKeyUtil;
import com.fdkankan.ucenter.constant.LoginConstant;
import com.fdkankan.ucenter.entity.Camera;
import com.fdkankan.ucenter.entity.CameraDetail;
import com.fdkankan.ucenter.entity.User;
import com.fdkankan.ucenter.service.*;
import com.fdkankan.ucenter.vo.request.AppLoginParam;
import com.fdkankan.ucenter.vo.request.LoginParam;
import com.fdkankan.ucenter.vo.response.LoginVo;
import com.fdkankan.ucenter.vo.response.UserVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Service
public class AppService {

    @Autowired
    private IUserService userService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ICameraDetailService cameraDetailService;
    @Autowired
    ISceneProService sceneProService;
    @Autowired
    IScenePlusService scenePlusService;
    @Autowired
    ICameraService cameraService;
    @Autowired
    LoginService loginService;


    public LoginVo login(LoginParam param) {
        if (StringUtils.isEmpty(param.getPassword()) || StringUtils.isEmpty(param.getPhoneNum())){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3001, LoginConstant.FAILURE_MSG_3001);
        }
        String passwordCode = null;
        try {
            passwordCode = SecurityUtil.MD5(AesUtil.desEncrypt(param.getPassword()));
        } catch (Exception e) {
            throw new BusinessException(LoginConstant.FAILURE_CODE_3014, LoginConstant.FAILURE_MSG_3014);
        }
        User user = userService.getByUserName(param.getPhoneNum());
        if(user == null){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3015, LoginConstant.FAILURE_MSG_3015);
        }
        if(!user.getPassword().equals(passwordCode)){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3014, LoginConstant.FAILURE_MSG_3014);
        }
        String token = this.redisLogin(user.getUserName(), JSONObject.toJSONString(user),21800L);
        LoginVo loginVo = commonLogin(user, param, token);
        loginVo.getUser().setPassword(param.getPassword());
        return loginVo;
    }


    private LoginVo commonLogin(User user,LoginParam param,String token){
        Long count = cameraDetailService.getCountByUserId(user.getId(),null);
        if(param.getCameraType() == null){
            param.setCameraType(  4);
        }
        List<Integer> resourceList = new ArrayList<>();
        if(param.getCameraType() == 4){
            resourceList = Arrays.asList(1,2,12,13,14);
        }else {
            resourceList = Collections.singletonList(3);
        }
        Long sceneProCount = sceneProService.getCountByUserId(user.getId(),resourceList);
        Long scenePlusCount = scenePlusService.getCountByUserId(user.getId(),resourceList);
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user,userVo);
        userVo.setCameraCount(count);
        userVo.setSceneCount(sceneProCount + scenePlusCount);
        try {
            userVo.setPassword(AesUtil.encrypt(SecurityUtil.MD5(user.getPassword())));
        } catch (Exception e) {
            throw new  BusinessException(ErrorCode.PASSWORD_ERROR);
        }
        LoginVo vo = new LoginVo();
        vo.setToken(token);
        vo.setUser(userVo);
        return vo;
    }

    public String redisLogin(String userName,String value,Long time){
        String token = JwtUtil.createJWT(-1,userName,"app");
        String redisKey = RedisKeyUtil.PREFIX_CACHE_CAMERA+ userName;
        redisUtil.set(redisKey, token,time);

        //设置官网token
        String redisKey2 =  String.format(RedisKey.TOKEN_V3 , token );
        redisUtil.set(redisKey2, value,time);
        return token;
    }

    public void appLogin(AppLoginParam param) {
        if(StringUtils.isEmpty(param.getAppUserName()) || StringUtils.isEmpty(param.getAppPassword())
                || StringUtils.isEmpty(param.getUuid())){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3001, LoginConstant.FAILURE_MSG_3001);
        }
        commonCheckCamera(param);
        redisUtil.set(param.getUuid(),param.getAppUserName(),60 * 5);
    }

    private Long commonCheckCamera(AppLoginParam param){
        Camera camera = cameraService.getBySnCodeAndPassword(param.getAppUserName(),param.getAppPassword());
        if(camera == null){
            throw new BusinessException(CameraConstant.FAILURE_6003);
        }
        CameraDetail detail = cameraDetailService.getByCameraId(camera.getId());
        if (detail == null ){
            throw new BusinessException(AppConstant.FAILURE_CODE_4012, AppConstant.FAILURE_MSG_4012);
        }
        return detail.getUserId();
    }

    public JSONObject login2(AppLoginParam param) {
        if(StringUtils.isEmpty(param.getAppUserName()) || StringUtils.isEmpty(param.getAppPassword())){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3001, LoginConstant.FAILURE_MSG_3001);
        }
        Long userId = commonCheckCamera(param);
        String redisValue = "";
        if(userId!= null){
            User user = userService.getById(userId);
            redisValue = JSONObject.toJSONString(user);
        }
        String token = redisLogin(param.getAppUserName(),redisValue, 604800L);
        JSONObject obj = new JSONObject();
        obj.put("token", token);
        return obj;
    }

    public LoginVo quickLogin(LoginParam param) {
        if(StringUtils.isEmpty(param.getPhoneNum()) || StringUtils.isEmpty(param.getMsgAuthCode())){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3001, LoginConstant.FAILURE_MSG_3001);
        }
        loginService.checkSms(param.getMsgAuthCode(),param.getPhoneNum(),true);

        User user = userService.getByUserName(param.getPhoneNum());
        if(user == null){
            throw new BusinessException(LoginConstant.FAILURE_CODE_3015, LoginConstant.FAILURE_MSG_3015);
        }
        String token = redisLogin(param.getPhoneNum(), JSONObject.toJSONString(user),21600L);
        return commonLogin(user,param,token);
    }

    public void logout(String token) {
        String username = JwtUtil.getUsername(token);
        String redisKey = RedisKeyUtil.PREFIX_CACHE_CAMERA+ username;
        if(redisUtil.hasKey(redisKey)){
            redisUtil.del(redisKey);
        }
    }

    public JSONObject getNickName() {
        String nickName = null;
        Long count = 0L;
        do {
            nickName = "mob" + RandomUtil.generateShortUuid();
            count = userService.getCountByNickName(nickName);
        } while (count > 0);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("nickName",nickName);
        return jsonObject;
    }

}
