package com.storlead.centre.system;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.storlead.framework.auth.jwt.JwtUtil;
import com.storlead.framework.auth.vo.LoginUser;
import com.storlead.framework.common.constant.CommonConstant;
import com.storlead.framework.common.constant.RedisKeySaltConstant;
import com.storlead.framework.common.ecode.BCryptPasswordEncoder;
import com.storlead.framework.common.util.RsaUtils;
import com.storlead.framework.redis.RedisService;
import com.storlead.framework.util.LoginUserUtil;
import com.storlead.framework.web.assemble.Result;
import com.storlead.framework.web.enums.ErrorMsgCode;
import com.storlead.sms.pojo.entity.SmsLogEntity;
import com.storlead.sms.service.SmsLogService;
import com.storlead.user.pojo.dto.UserLoginDTO;
import com.storlead.user.pojo.entity.DeptEntity;
import com.storlead.user.pojo.entity.JobEntity;
import com.storlead.user.pojo.entity.UserEntity;
import com.storlead.user.service.IDepartService;
import com.storlead.user.service.IJobService;
import com.storlead.user.service.IUserRoleService;
import com.storlead.user.service.IUserService;
import com.storlead.wx.service.CorpWeChatService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @program: sp-sales
 * @description:
 * @author: chenkq
 * @create: 2022-07-15 10:11
 */
@RestController
@RequestMapping("/sys/auth")
@Api(tags="1.认证接口")
@Slf4j
public class LoginApiController {

    @Resource
    private IUserService sysUserService;

    @Resource
    private RedisService redisService;

    @Resource
    private SmsLogService smsLogService;

    @Resource
    private IDepartService departService;

    @Value("${environment}")
    private  String environment;

    @Resource
    private IUserRoleService userRoleService;

    @Resource
    private IJobService jobService;

    @Resource
    private CorpWeChatService corpWeChatService;

    @RequestMapping(value = "/redirect")
    @ResponseBody
    public Object redirect(HttpServletRequest request, HttpServletResponse response)  throws IOException {
        response.sendRedirect("http://www.baidu.com");
        return Result.ok("");
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ApiOperation(value = "用户登录接口", notes = "用户登录接口")
    public Result login(@RequestBody UserLoginDTO loginDTO) {

        if (Objects.isNull(loginDTO)) {
            return Result.error("参数错误");
        }
        UserEntity userInfo;
        JSONObject obj = new JSONObject();
        if (StrUtil.isNotBlank(loginDTO.getWxCode())) {
            String code = corpWeChatService.login(loginDTO.getWxCode());
            userInfo = sysUserService.getOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getXworkUserId,code));
        } else if (StrUtil.isNotBlank(loginDTO.getSmsCode())) {
            if (StrUtil.isBlank(loginDTO.getAccount())) {
                return Result.error("参数错误");
            }
            Object var1 = redisService.getCacheObject(RedisKeySaltConstant.REDIS_LOGIN_VALID_CODE_KEY+loginDTO.getAccount());
            if (Objects.isNull(var1)) {
                return Result.error(ErrorMsgCode.D_400005);
            } else {
                SmsLogEntity smsLog = (SmsLogEntity) var1;
                if (!loginDTO.getSmsCode().equals(smsLog.getVerifyCode())){
                    return Result.error(ErrorMsgCode.D_400008);
                }
                Long currentTime = System.currentTimeMillis();
                Long sendTime = smsLog.getSendTime().getTime();
                if ((currentTime - sendTime) / 1000 > smsLog.getValidTime()) {
                    return Result.error(ErrorMsgCode.D_400007);
                }
            }
            userInfo = sysUserService.getOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getMobile,loginDTO.getAccount()));
            redisService.deleteObject(RedisKeySaltConstant.REDIS_LOGIN_VALID_CODE_KEY+loginDTO.getAccount());
        } else {
            if (StrUtil.isBlank(loginDTO.getAccount()) || StrUtil.isBlank(loginDTO.getPassword())) {
                return Result.error("用户名或密码为空");
            }
            userInfo = sysUserService.getOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getMobile,loginDTO.getAccount()).eq(UserEntity::getIsDelete, CommonConstant.DEL_FLAG_0));
            if (Objects.isNull(userInfo)) {
                return Result.error("账号不存在");
            }

            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            String password = "";
            if((!environment.equals("prod") && !loginDTO.getPassword().equals("qq123456")) || environment.equals("prod")){
                try {
                    password = RsaUtils.decryptByPrivateKey(RsaUtils.PRIVATE_KEY, loginDTO.getPassword());
                }catch (Exception e) {
                    return Result.error("用户名或密码错误");
                }
            }
            if(environment.equals("prod") || (environment.equals("test")
                    && !loginDTO.getPassword().equals("qq123456") &&
                    !password.equals("qq123456"))) {
                if (!bCryptPasswordEncoder.matches(password, userInfo.getPassword())) {
                    return Result.error("用户名或密码错误");
                }
            }
            String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z\\W]{8,}$";
            String defaultPassWord = "storlead123456";// SystemConfigItemCacheUtil.getDefaultPassWord();

            if(password !=null && (!password.matches(regex) || password.equals(defaultPassWord))){
                obj.put("status",1);
            }else {
                obj.put("status",2);
            }

        }
        if (Objects.isNull(userInfo)) {
            return Result.error("登录失败,未获取到用户信息");
        }
        if (!userInfo.getEnabled()) {
            return Result.error("该账号用户暂无登录权限");
        }

//        Integer possessMenuCount = menuService.checkUserMenuAccess(userInfo.getId());
//        if (possessMenuCount == 0) {
//            return Result.error("暂未获取到菜单权限,请联系管理员分配权限!");
//        }

        LoginUser loginUser = new LoginUser();
        BeanUtils.copyProperties(userInfo,loginUser);

        if (Objects.nonNull(userInfo.getJobId())) {
            JobEntity job = jobService.getById(userInfo.getJobId());
            if (Objects.nonNull(job)) {
                loginUser.setJobName(job.getName());
            }
        }

        loginUser.setRoleIds(userRoleService.selectUserRoleByUserId(userInfo.getId()));
        if (Objects.nonNull(userInfo.getDeptId())) {
            DeptEntity dept = departService.getById(userInfo.getDeptId());
            if (Objects.nonNull(dept)) {
                loginUser.setDeptName(dept.getName());
                loginUser.setDeptJobDes(dept.getDeptJobDes());
            }
        }

        //用户登录信息
        String jwtToken = JwtUtil.createJWT(JSONObject.toJSONString(loginUser),loginUser.getMobile());
        String token = SecureUtil.md5(jwtToken);

        String json = JSONObject.toJSONString(loginUser);
        redisService.setCacheObject(token, json, 60 * 60 * 24L * 7, TimeUnit.SECONDS);

        obj.put("token", token);
        return Result.ok(obj);
    }


    @ApiOperation("获取当前用户信息")
    @PostMapping("/getCurrentUserInfo")
    public Object getCurrentUserInfo() {
        LoginUser loginUser = LoginUserUtil.getLoginUser();
        if (Objects.isNull(loginUser)) {
            return Result.error("获取失败，请重新登录");
        }
        DeptEntity dept = departService.getById(loginUser.getDeptId());
        UserEntity sysUser = sysUserService.getById(loginUser.getId());
        loginUser.setJobDes(sysUser.getJobDes())
                 .setBirthday(sysUser.getBirthday())
                 .setEmail(sysUser.getEmail())
                 .setMobile(sysUser.getMobile())
                 .setSex(sysUser.getSex())
                 .setUserName(sysUser.getUserName())
                 .setNickName(sysUser.getNickName());
        if (Objects.nonNull(dept)) {
            loginUser.setDeptJobDes(dept.getDeptJobDes());
        }
        if (Objects.nonNull(dept)) {
            if (StrUtil.isNotBlank(dept.getRouteCode())) {
                List<String> codes = Arrays.asList(dept.getRouteCode().split(","));
                loginUser.setSubCompanyCode(codes.get(1));
                loginUser.setCompanyCode(codes.get(0));
            }
            loginUser.setDeptCode(dept.getRouteCode());
            loginUser.setDeptName(dept.getName());
        }

//        List<MenuEntity> userMenuList = menuService.getUserMenuList(loginUser.getId(),Arrays.asList(0),Arrays.asList(3));
//        if (!CollectionUtils.isEmpty(userMenuList)) {
//            loginUser.setBtnRes(userMenuList.stream().map(MenuEntity::getPerms).collect(Collectors.toSet()));
//        }
        return Result.ok(loginUser);
    }

    @ApiOperation("获取当前用户信息")
    @PostMapping("/getH5CurrentUserInfo")
    public Object getH5CurrentUserInfo() {
        LoginUser loginUser = LoginUserUtil.getLoginUser();
        if (Objects.isNull(loginUser)) {
            return Result.error("获取失败，请重新登录");
        }
        DeptEntity dept = departService.getById(loginUser.getDeptId());
        UserEntity sysUser = sysUserService.getById(loginUser.getId());
        loginUser.setJobDes(sysUser.getJobDes())
                .setBirthday(sysUser.getBirthday())
                .setEmail(sysUser.getEmail())
                .setMobile(sysUser.getMobile())
                .setSex(sysUser.getSex())
                .setUserName(sysUser.getUserName())
                .setNickName(sysUser.getNickName());
        if (Objects.nonNull(dept)) {
            loginUser.setDeptJobDes(dept.getDeptJobDes());
        }
        if (Objects.nonNull(dept)) {
            if (StrUtil.isNotBlank(dept.getRouteCode())) {
                List<String> codes = Arrays.asList(dept.getRouteCode().split(","));
                loginUser.setSubCompanyCode(codes.get(1));
                loginUser.setCompanyCode(codes.get(0));
            }
            loginUser.setDeptCode(dept.getRouteCode());
            loginUser.setDeptName(dept.getName());
        }

//        List<MenuEntity> userMenuList = menuService.getUserMenuList(loginUser.getId(),Arrays.asList(1),Arrays.asList(1,2,3));
//        if (!CollectionUtils.isEmpty(userMenuList)) {
//            List<MenuPermis> permis = userMenuList.stream()
//                    .map(menu -> {
//                        MenuPermis mp = new MenuPermis();
//                        mp.setId(menu.getId());
//                        mp.setPerm(menu.getPerms());
//                        mp.setType(menu.getMenuType());
//                        return mp;
//                    })
//                    .collect(Collectors.toList());
//            loginUser.setPermis(permis);
//        }
        return Result.ok(loginUser);
    }

    @ApiOperation("获取当前用户信息")
    @RequestMapping("/getCurrentUser")
    public Object getCurrentUser() {
        LoginUser loginUser = LoginUserUtil.getLoginUser();
        if (Objects.isNull(loginUser)) {
            return Result.error("获取失败，请重新登录");
        }
//        DeptEntity dept = departService.getById(loginUser.getDeptId());
        UserEntity sysUser = sysUserService.getById(loginUser.getId());
        loginUser.setJobDes(sysUser.getJobDes())
                .setBirthday(sysUser.getBirthday())
                .setEmail(sysUser.getEmail())
                .setMobile(sysUser.getMobile())
                .setSex(sysUser.getSex())
                .setUserName(sysUser.getUserName())
                .setNickName(sysUser.getNickName());
//        if (Objects.nonNull(dept)) {
//            loginUser.setDeptJobDes(dept.getDeptJobDes());
//        }
//        if (Objects.nonNull(dept)) {
//            if (StrUtil.isNotBlank(dept.getRouteCode())) {
//                List<String> codes = Arrays.asList(dept.getRouteCode().split(","));
//                loginUser.setSubCompanyCode(codes.get(1));
//                loginUser.setCompanyCode(codes.get(0));
//            }
//            loginUser.setDeptCode(dept.getRouteCode());
//            loginUser.setDeptName(dept.getName());
//        }
        return Result.ok(loginUser);
    }

    @ApiOperation("获取AccessToken")
    @PostMapping("/sendVerifyCode")
    public Result sendLoginVerifyCode(String mobile) {
        if (StrUtil.isBlank(mobile)) {
            return Result.error("参数错误");
        }
        UserEntity userAccount = sysUserService.getOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getMobile,mobile));
        if (userAccount == null) {
            return Result.error("手机号错误,该手机号用户不存在");
        }
        try {
            return  smsLogService.sendLoginSmsCode(mobile);
        }catch (Exception e) {
            return  Result.error(e.getMessage());
        }
    }



//    public static void main(String[] args) {
//
//        String baseUrl = "https://openapi.liblibai.cloud";
//
//        String secretKey = "MyJwnqGd1h_W__ENlx_ywK-RpkHTeJd7";
//        // 请求API接口的uri地址
//        String uri = "/api/generate/webui/status";
//        // 当前毫秒时间戳
//        Long timestamp = System.currentTimeMillis();
//        // 随机字符串
//        String signatureNonce = RandomStringUtils.randomAlphanumeric(10);
//        // 拼接请求数据
//        String content = uri + "&" + timestamp + "&" + signatureNonce;
//
//        try {
//            // 生成签名
//            SecretKeySpec secret = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
//            Mac mac = Mac.getInstance("HmacSHA1");
//            mac.init(secret);
//            String signature =  Base64.encodeBase64URLSafeString(mac.doFinal(content.getBytes()));
//            String url = baseUrl+uri+"?AccessKey=kaB5IBReZKiU9LiIJPbl6g&Signature="+signature+"&Timestamp="+timestamp+"&SignatureNonce="+signatureNonce;
//            System.out.println("url :"+url);
//        } catch (NoSuchAlgorithmException e) {
//           log.error("NoSuchAlgorithmException -- error--",e);
//        } catch (InvalidKeyException e) {
//            log.error("InvalidKeyException -- error--",e);
//        }
//    }
}
