package com.user.controller;

import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import com.alibaba.fastjson.JSONObject;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.security.UserCenter;
import com.hfkj.common.utils.*;
import com.hfkj.config.WxMaConfig;
import com.hfkj.entity.BsUser;
import com.hfkj.entity.BsUserComplaint;
import com.hfkj.model.ResponseData;
import com.hfkj.model.SecUserSessionObject;
import com.hfkj.model.UserSessionObject;
import com.hfkj.service.user.BsUserComplaintService;
import com.hfkj.service.user.BsUserService;
import com.hfkj.service.user.impl.BsUserServiceImpl;
import com.hfkj.sysenum.SecUserStatusEnum;
import com.hfkj.sysenum.UserLoginPlatform;
import com.hfkj.sysenum.UserLoginType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @className: secUser
 * @author: HuRui
 * @date: 2024/3/28
 **/
@Controller
@RequestMapping(value="/client")
@Api(value="客户端")
public class BsUserController {

    Logger log = LoggerFactory.getLogger(BsUserController.class);

    @Resource
    private BsUserService userService;
    @Resource
    private UserCenter userCenter;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private BsUserComplaintService userComplaintService;

    @RequestMapping(value = "/phone", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "手机号登录")
    public ResponseData phone(@RequestBody JSONObject body) {
        try {
            if (body == null
                    || StringUtils.isBlank(body.getString("platform"))
                    || StringUtils.isBlank(body.getString("type"))
                    || StringUtils.isBlank(body.getString("phone"))
            ) {
                log.error("LoginController --> phone() error!", "请求参数校验失败");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            String phone = body.getString("phone");
            String password = body.getString("password");

            // 客户端
            UserLoginPlatform platform = UserLoginPlatform.getDataByType(body.getString("platform"));
            if (platform == null) {
                log.error("LoginController --> phone() error!", "未知客户端");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知客户端");
            }
            // 校验手机号格式
            if (!MemberValidateUtil.validatePhone(phone)) {
                log.error("LoginController --> phone() error!", "请输入正确的手机号");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "请输入正确的手机号");
            }
            // 登录类型
            UserLoginType loginType = UserLoginType.getDataByType(body.getString("type"));
            if (loginType == null) {
                log.error("LoginController --> phone() error!", "未知登录类型；" + body.getString("type"));
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知登录类型");
            }

            // 账户密码登录
            if (body.getString("type").equals(UserLoginType.SMS.getCode())) {
                if (StringUtils.isBlank(body.getString("smsCode"))) {
                    log.error("LoginController --> phone() error!", "请输入短信验证码");
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "请输入短信验证码");
                }
                // 手机号的验证码
                Object phoneCodeObject = redisUtil.get("SMS_CODE:" + phone);
                if (phoneCodeObject == null) {
                    log.error("LoginController --> phone() error!", "短信验证码错误");
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "短信验证码错误");
                }
                if (!body.getString("smsCode").equals(phoneCodeObject.toString())) {
                    log.error("LoginController --> phone() error!", "短信验证码错误");
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "短信验证码错误");
                }
                redisUtil.del("SMS_CODE:" + phone);

                Map<String, Object> other = new HashMap<>();
                return ResponseMsgUtil.success(userService.login(platform, loginType, phone, password, other));
            }
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "登录失败");

        } catch (Exception e) {
            log.error("LoginController --> phone() error!", e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/outsideOpenid", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "外部openid登录")
    public ResponseData outsideOpenid(@RequestBody JSONObject body) {
        try {
            if (body == null
                    || StringUtils.isBlank(body.getString("platform"))
                    || StringUtils.isBlank(body.getString("type"))
                    || StringUtils.isBlank(body.getString("outsideOpenid"))
            ) {
                log.error("LoginController --> phone() error!", "请求参数校验失败");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            String outsideOpenid = body.getString("outsideOpenid");

            // 客户端
            UserLoginPlatform platform = UserLoginPlatform.getDataByType(body.getString("platform"));
            if (platform == null) {
                log.error("LoginController --> phone() error!", "未知客户端");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知客户端");
            }
            //
            UserLoginType loginType = UserLoginType.getDataByType(body.getString("type"));
            if (loginType == null) {
                log.error("LoginController --> phone() error!", "未知登录类型；" + body.getString("type"));
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知登录类型");
            }

            // 账户密码登录
            Map<String, Object> other = new HashMap<>();
            return ResponseMsgUtil.success(userService.login(platform, loginType, outsideOpenid, other));

        } catch (Exception e) {
            log.error("LoginController --> phone() error!", e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/phoneTest", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "手机号登录")
    public ResponseData phoneTest() {
        try {

            Map<String, Object> other = new HashMap<>();
            return ResponseMsgUtil.success(userService.login(UserLoginPlatform.H5, UserLoginType.SMS, "18090580471", "123456", other));

        } catch (Exception e) {
            log.error("LoginController --> phone() error!", e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/wechatMaHandleCode", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "微信小程序code解析")
    public ResponseData wechatMaHandleCode(@RequestBody JSONObject body) {
        try {
            if (body == null|| StringUtils.isBlank(body.getString("code"))) {
                log.error("LoginController --> wxMiniHandleCode() error!", "请求参数校验失败");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            WxMaJscode2SessionResult session = WxMaConfig.getMaService().jsCode2SessionInfo(body.getString("code"));
            //保存小程序用户登录的openId及sessionKey信息
            redisUtil.hset("WX_MA_OPENID_SESSION", session.getOpenid(), session);
            JSONObject jo = new JSONObject();
            jo.put("openId", session.getOpenid());
            return ResponseMsgUtil.success(jo);
        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/getH5AccessToken", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "【H5】获取AccessToken")
    public ResponseData getH5AccessToken(@RequestParam(value = "code", required = true) String code) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("appid", "wxa075e8509802f826");
            params.put("secret", "0e606fc1378d35e359fcf3f15570b2c5");
            params.put("code", code);
            params.put("grant_type", "authorization_code");
            return ResponseMsgUtil.success(HttpsUtils.doGet("https://api.weixin.qq.com/sns/oauth2/access_token", params));

        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/wechatMaPhone", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "微信小程序手机号登录")
    public ResponseData wechatMaPhone(@RequestBody JSONObject body) {
        try {
            if (body == null
                    || StringUtils.isBlank(body.getString("encryptedData"))
                    || StringUtils.isBlank(body.getString("iv"))
                    || StringUtils.isBlank(body.getString("openId"))) {
                log.error("LoginController --> wechatMaPhone() error!", "请求参数校验失败");
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }

            String encryptedData = body.getString("encryptedData").replace(" ", "+");
            String iv = body.getString("iv").replace(" ", "+");

            //请求微信api，获取用户session_key以及openId
            Object skObject = redisUtil.hget("WX_MA_OPENID_SESSION", body.getString("openId"));
            if (skObject == null) {
                throw ErrorHelp.genException(SysCode.MiniProgram, ErrorCode.COMMON_ERROR, "微信登录失败");
            }
            WxMaJscode2SessionResult session = (WxMaJscode2SessionResult) skObject;
            WxMaPhoneNumberInfo phoneNoInfo = WxMaConfig.getMaService()
                    .getUserService()
                    .getPhoneNoInfo(session.getSessionKey(), encryptedData, iv);

            if (phoneNoInfo == null || StringUtils.isEmpty(phoneNoInfo.getPurePhoneNumber())) {
                log.error("LoginController --> wechatMaPhone() error!", "登录失败! 用户手机号解析失败");
                throw ErrorHelp.genException(SysCode.MiniProgram, ErrorCode.COMMON_ERROR, "登录失败! 用户手机号解析失败");
            }
            Map<String, Object> other = new HashMap<>();
            other.put("maOpenId", session.getOpenid());
            return ResponseMsgUtil.success(userService.login(UserLoginPlatform.WXAPPLETS, UserLoginType.WECHAT_MA_PHONE, phoneNoInfo.getPurePhoneNumber(),null, other));

        } catch (Exception e) {
            log.error("LoginController --> wechatMaPhone() error!", e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/queryUser", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "查询用户信息")
    public ResponseData queryUser() {
        try {

            return ResponseMsgUtil.success(userCenter.getSessionModel(UserSessionObject.class));

        } catch (Exception e) {
            log.error("LoginController --> wechatMaPhone() error!", e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/editUser", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "编辑用户信息")
    public ResponseData editUser(@RequestBody BsUser body) {
        try {

            UserSessionObject userSession = userCenter.getSessionModel(UserSessionObject.class);
            BsUser bsUser = userSession.getUser();

            bsUser.setHeadImg(body.getHeadImg());
            bsUser.setName(body.getName());
            bsUser.setPhone(body.getPhone());

            userService.editData(bsUser);
            // 更新登录信息
            return ResponseMsgUtil.success(userService.updateSession(bsUser.getId()));

        } catch (Exception e) {
            log.error("LoginController --> wechatMaPhone() error!", e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/disable",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "禁用")
    public ResponseData disable() {
        try {
            UserSessionObject userSession = userCenter.getSessionModel(UserSessionObject.class);
            // 查询用户详情
            BsUser user = userSession.getUser();
            if (user == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            user.setStatus(SecUserStatusEnum.status2.getCode());
            userService.editData(user);

            // 退出当前登录信息
            userService.loginOut(new BsUserServiceImpl().token(user));

            return ResponseMsgUtil.success("操作成功");

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }


    @RequestMapping(value="/loginOut",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "退出登录")
    public ResponseData loginOut(HttpServletRequest request) {
        try {
            SecUserSessionObject session = userCenter.getSessionModel(SecUserSessionObject.class);
            if (session != null) {
                userCenter.remove(request);
            }
            return ResponseMsgUtil.success("退出成功");

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/postComplaint", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "提交意见")
    public ResponseData postComplaint(@RequestBody BsUserComplaint body) {
        try {

            UserSessionObject userSession = userCenter.getSessionModel(UserSessionObject.class);
            BsUser bsUser = userSession.getUser();

            BsUserComplaint bsUserComplaint = new BsUserComplaint();
            bsUserComplaint.setUserId(bsUser.getId());
            bsUserComplaint.setContent(body.getContent());
            bsUserComplaint.setCreateTime(new Date());
            bsUserComplaint.setUpdateTime(new Date());
            bsUserComplaint.setPhone(bsUser.getPhone());
            bsUserComplaint.setName(bsUser.getName());

            userComplaintService.create(bsUserComplaint);

            return ResponseMsgUtil.success("成功");

        } catch (Exception e) {
            log.error("LoginController --> wechatMaPhone() error!", e);
            return ResponseMsgUtil.exception(e);
        }
    }



}
