package cn.com.ty.lift.system.user.controller;

import cn.com.ty.lift.common.aliservice.aliyunsms.AliyunSmsUtil;
import cn.com.ty.lift.common.aliservice.constants.AliConstants;
import cn.com.ty.lift.common.constants.ApiConstants;
import cn.com.ty.lift.common.utils.DateUtils;
import cn.com.ty.lift.system.user.dao.entity.UserAccount;
import cn.com.ty.lift.system.user.dao.entity.model.UserRequest;
import cn.com.ty.lift.system.user.service.ILoginService;
import cn.com.ty.lift.system.user.service.IUserAccountService;
import cn.com.ty.lift.system.utils.RandomValidateCodeUtil;
import cn.com.ty.lift.system.wechat.constants.WxConstants;
import cn.com.ty.lift.system.wechat.utils.WxUtil;
import cn.com.xwy.boot.web.dto.RestResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author huangyuan
 * @date 2019-11-29
 * @description 用户登录
 */
@Controller
@RequestMapping("/login")
public class LoginController {

    @Resource
    RedisTemplate redisTemplate;

    @Resource
    private ILoginService loginService;

    @Resource
    private IUserAccountService userAccountService;

    /**
     * @param userRequest 用户参数对象
     * @return
     * @description 用户注册
     * @date 2019/11/27 10:03 AM
     */
    @PostMapping("/register")
    @ResponseBody
    public RestResponse register(HttpServletRequest request, @RequestBody UserRequest userRequest) {
        return loginService.register(request, userRequest);
    }

    /**
     * @param
     * @return
     * @description 微信登录注册
     * @date 2019-12-30 14:18
     */
    @PostMapping("/wxRegister")
    @ResponseBody
    public RestResponse wxRegister(HttpServletRequest request, @RequestBody UserRequest userRequest) {
        return loginService.register(request, userRequest);
    }

    /**
     * @param userRequest mobile 用户手机号
     * @return
     * @description app 卫星登录绑定用户手机号
     * @date 2020/5/7 10:43 上午
     */
    @PostMapping("/appBindMobile")
    @ResponseBody
    public RestResponse appBindMobile(@RequestBody UserRequest userRequest) {
        RestResponse restResponse = judgeAuthCode(userRequest, WxConstants.APP_LOGIN);
        if (restResponse == null) {
            //校验通过，用户绑定手机号
            return loginService.appBindMobile(userRequest);
        }
        return restResponse;
    }

    /**
     * @param
     * @return
     * @description 切换团队
     * @date 2020-01-02 15:06
     */
    @RequestMapping("/changeTeam")
    @ResponseBody
    public RestResponse changeTeam(HttpServletRequest request, @RequestBody UserRequest userRequest) {
        return loginService.changeTeam(request, userRequest);
    }

    /**
     * @param request     请求对象
     * @param userRequest 用户参数对象
     * @return RestResponse
     * @description 登录
     * @date 2019/11/27 10:03 AM
     */
    @PostMapping("/login")
    @ResponseBody
    public RestResponse login(HttpServletRequest request, @RequestBody UserRequest userRequest) {
        return loginService.login(request, userRequest);
    }

    /**
     * @param
     * @return
     * @description 微信登录
     * @date 2019-12-30 10:50
     */
    @RequestMapping("/wxLogin")
    @ResponseBody
    public RestResponse wxLogin(HttpServletRequest request, @RequestBody UserRequest userRequest) {
        RestResponse restResponse = judgeAuthCode(userRequest, WxConstants.APP_LOGIN);
        if (restResponse == null) {
            //校验通过 用户微信登录
            return loginService.wxLogin(request, userRequest);
        }
        return restResponse;
    }

    /**
     * @param request     请求数据
     * @param userRequest 授权码
     * @return 登录信息
     * @description
     * @date 2020/4/27 10:07 上午
     */
    @RequestMapping("/appletLogin")
    @ResponseBody
    public RestResponse appletLogin(HttpServletRequest request, @RequestBody UserRequest userRequest) {
        RestResponse restResponse = judgeAuthCode(userRequest, WxConstants.APPLET_LOGIN);
        if (restResponse == null) {
            //校验通过 登录小程序
            return loginService.appletLogin(request, userRequest);
        }
        return restResponse;
    }

    /**
     * @param
     * @return
     * @description 通过授权码获取微信openId
     * @date 2020/5/11 4:06 下午
     */
    @RequestMapping("/getOpenId")
    @ResponseBody
    public RestResponse getOpenId(@RequestBody UserRequest userRequest) {
        RestResponse restResponse = judgeAuthCode(userRequest, WxConstants.APPLET_SCAN_LOGIN);
        if (restResponse == null) {
            Map<String, String> openIdMap = new HashMap<>();
            openIdMap.put("appletOpenId", userRequest.getWeChatOpenId());
            return RestResponse.success(openIdMap, ApiConstants.RESULT_SUCCESS, "获取openId成功");
        }
        return restResponse;
    }

    /**
     * @param userRequest 手机号 验证码
     * @return 是否成功
     * @description 绑定用户手机号
     * @date 2020/4/30 9:47 上午
     */
    @RequestMapping("/bindMobile")
    @ResponseBody
    public RestResponse bindMobile(HttpServletRequest request, @RequestBody UserRequest userRequest) {
        return loginService.bindMobile(request, userRequest);
    }

    /**
     * @param response http相应类
     * @param request  http请求类
     * @return
     * @description 获取图片验证码
     * @date 2019/11/27 10:03 AM
     */
    @RequestMapping("/getImagCode")
    public void getImageCode(HttpServletResponse response, HttpServletRequest request) {
        try {
            response.setContentType("image/jpeg");//设置相应类型,告诉浏览器输出的内容为图片
            response.setHeader("Pragma", "No-cache");//设置响应头信息，告诉浏览器不要缓存此内容
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expire", 0);
            RandomValidateCodeUtil randomValidateCode = new RandomValidateCodeUtil();
            randomValidateCode.getRandcode(request, response);//输出验证码图片方法
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param request  http请求对象
     * @param inputStr 输入字符串
     * @return
     * @description 图形验证码校验
     * @date 2019/11/27 10:03 AM
     */
    @RequestMapping("/checkImagCode")
    @ResponseBody
    public RestResponse checkVerify(HttpServletRequest request, String inputStr) {
        String random = (String) request.getSession().getAttribute(RandomValidateCodeUtil.RANDOMCODEKEY);
        if (StringUtils.isBlank(inputStr)) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "验证码为空");
        }
        if (random != null && random.toLowerCase().equals(inputStr.toLowerCase())) {
            //校验成功
            return RestResponse.success(null, ApiConstants.RESULT_SUCCESS, "验证码校验成功");
        }
        //校验失败
        return RestResponse.fail(ApiConstants.RESULT_ERROR, "验证码校验失败");
    }

    /**
     * @param mobile 手机号
     * @return
     * @description 验证用户手机号是否注册过
     * @date 2019/11/27 10:03 AM
     */
    @RequestMapping("/checkMobile")
    @ResponseBody
    public RestResponse checkMobile(String mobile) {
        UserAccount userAccount = userAccountService.getByMobile(mobile);
        if (userAccount != null) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "手机号已经被注册过了");
        }
        return RestResponse.success(null, ApiConstants.RESULT_SUCCESS, "验证通过");
    }

    /**
     * @param request
     * @param mobile  手机号
     * @return
     * @description
     * @date 2019/11/27 10:03 AM
     */
    @RequestMapping("/smsCode")
    @ResponseBody
    public RestResponse smsCode(HttpServletRequest request, String mobile) {
        if (StringUtils.isNotBlank(mobile)) {
            //校验同一号码两次获取间隔是否有一分钟
            Object timeStampCode = redisTemplate.opsForValue().get(mobile + ApiConstants.UserConstants.SMS_CODE_MOBILE);
            if (timeStampCode != null) {
                return RestResponse.fail(ApiConstants.RESULT_ERROR, "请一分钟后重新获取");
            }
            //校验通过获取短信验证码
            String smsCode = AliyunSmsUtil.sendSmsCode(mobile, AliConstants.SmsConstants.TEMPLATE_CODE);
            if (StringUtils.isNotBlank(smsCode)) {
                //将手机号放入session中
                request.getSession().setAttribute(AliConstants.SmsConstants.MOBILE, mobile);
                //将短信验证码放入session中设置过期时间为5分钟
                redisTemplate.opsForValue().set(mobile + AliConstants.SmsConstants.SMS_CODE_FIELD,
                        smsCode, 5L, TimeUnit.MINUTES);
                //将手机号存到redis中，并设置一分钟后过期
                redisTemplate.opsForValue().set(mobile + ApiConstants.UserConstants.SMS_CODE_MOBILE,
                        DateUtils.generateCode(), 1L, TimeUnit.MINUTES);
                return RestResponse.success(null, ApiConstants.RESULT_SUCCESS, "发送验证码成功");
            }
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "手机号不存在，发送验证码失败");
        }
        return RestResponse.fail(ApiConstants.RESULT_ERROR, "手机号为空");
    }

    /**
     * @param request
     * @param inputSmsCode 输入的短信验证码
     * @return
     * @description 校验短信验证码
     * @date 2019/11/27 10:03 AM
     */
    @RequestMapping("/checkSmsCode")
    @ResponseBody
    public RestResponse checkSmsCode(HttpServletRequest request, String inputSmsCode) {
        //从session中获取手机号
        String mobile = (String) request.getSession().getAttribute(AliConstants.SmsConstants.MOBILE);
        //从redis中获取短信验证码
        Object smsCode = redisTemplate.opsForValue().get(mobile + AliConstants.SmsConstants.SMS_CODE_FIELD);
        if (smsCode != null) {
            if (StringUtils.isNotBlank(inputSmsCode) && inputSmsCode.equals(smsCode)) {
                return RestResponse.success(null, ApiConstants.RESULT_SUCCESS, "短信验证码校验成功");
            } else {
                return RestResponse.fail(ApiConstants.RESULT_ERROR, "短信验证码输入有误");
            }
        }
        return RestResponse.fail(ApiConstants.RESULT_ERROR, "短信验证码已经过期，请重新获取");
    }

    /**
     * @param userRequest
     * @return
     * @description 找回密码
     * @date 2019-12-10
     */
    @PostMapping("/resetPassword")
    @ResponseBody
    public RestResponse resetPassword(@RequestBody UserRequest userRequest, HttpSession session) {
        return loginService.resetPassword(userRequest, session);
    }

    /**
     * @param
     * @return
     * @description 微信授权码校验
     * @date 2019-12-30 15:40
     */
    private RestResponse judgeAuthCode(UserRequest userRequest, String loginStyle) {
        String authCode = userRequest.getAuthCode();
        //判断授权码
        if (StringUtils.isBlank(authCode)) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "授权码为空无法进行操作");
        }
        //通过授权码获取用户openId
        String openId = "";
        switch (loginStyle) {
            case WxConstants.APPLET_LOGIN:
                openId = WxUtil.getAppletOpenIdByAuthCode(authCode);
                break;
            case WxConstants.APP_LOGIN:
                openId = WxUtil.getAppOpenIdByAuthCode(authCode);
                break;
            case WxConstants.APPLET_SCAN_LOGIN:
                openId = WxUtil.getAppletScanOpenIdByAuthCode(authCode);
                break;
        }
        if (StringUtils.isBlank(openId)) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "授权码无效无法进行操作");
        }
        userRequest.setWeChatOpenId(openId);
        return null;
    }

}
