package com.platform.api;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.platform.annotation.IgnoreAuth;
import com.platform.entity.*;
import com.platform.service.ApiUserService;
import com.platform.service.TokenService;
import com.platform.service.custom.MyApiTmBrandAdminService;
import com.platform.service.custom.MySysUserBrandService;
import com.platform.service.impl.ZhiHouseService;
import com.platform.util.ApiBaseAction;
import com.platform.util.ApiUserUtils;
import com.platform.util.CommonUtil;
import com.platform.utils.*;
import com.platform.validator.Assert;
import com.platform.vos.ReturnDTO;
import com.platform.vos.TbUser;
import com.qiniu.util.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * API登录授权
 *
 * @author lipengjun
 * @email 939961241@qq.com
 * @gitee https://gitee.com/fuyang_lipengjun/platform
 * @date 2017-03-23 15:31
 */
@Api(tags = "API登录授权接口")
@RestController
@RequestMapping("/api/auth")
@Slf4j
public class ApiAuthController extends ApiBaseAction {
    private static Logger logger = LoggerFactory.getLogger(CommonUtil.class);
    @Autowired
    private ApiUserService userService;
    @Autowired
    private TokenService tokenService;

    @Autowired
    private MyApiTmBrandAdminService myApiTmBrandAdminService;
    @Autowired
    private MySysUserBrandService mySysUserBrandService;

    @Autowired
    private ZhiHouseService zhiHouseService;

    /**
     * 登录
     */
    @IgnoreAuth
    @PostMapping("login")
    @ApiOperation(value = "登录接口")
    public Result login(String mobile, String password) {
        Assert.isBlank(mobile, "手机号不能为空");
        Assert.isBlank(password, "密码不能为空");

        //用户登录
        long userId = userService.login(mobile, password);

        //生成token
        Map<String, Object> map = tokenService.createToken(userId);

        return Result.success(map);
    }
    /**
     * 解析用户的手机号
     */
    @ApiOperation(value = "解密用户的手机号")
    @IgnoreAuth
    @PostMapping("decryptedPhoneNum")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "encryptedData", value = "手机号密文", dataType = "String"),
            @ApiImplicitParam(name = "iv", value = "盐", dataType = "String"),
            @ApiImplicitParam(name = "sessionKey", value = "sessionKey", dataType = "String")
    })
    public Object decryptedPhoneNum(
                                     @RequestParam(name = "encryptedData") String encryptedData,
                                     @RequestParam(name = "iv") String iv,
                                     @RequestParam(name = "sessionKey") String sessionKey
                                    ) {

        if(StringUtils.isNullOrEmpty(encryptedData) || StringUtils.isNullOrEmpty(iv)||
        StringUtils.isNullOrEmpty(sessionKey)){
            return Result.failure("密文、iv、sessionKey三者都不能为空");
        }
        String decryptPhoneNum = "";
        try {
            JSONObject resultJson = WXCore.decrypt("", encryptedData, sessionKey, iv);
            decryptPhoneNum = (null != resultJson ? resultJson.getString("phoneNumber") : "");
            log.info("解密出来的手机号码为:{}", decryptPhoneNum);
        }catch (Exception e){
            log.error("解密手机号出现异常:{}", e);
            return Result.failure("解密手机号出现异常");
        }
        Map<String , Object> map = new HashMap<>();
        map.put("phoneNum" , decryptPhoneNum);
        return Result.success(map);

    }

    /**
     * 微信登录
     */
    @ApiOperation(value = "微信登录")
    @IgnoreAuth
    @PostMapping("login_by_weixin")
    public Object loginByWeixin() {
        JSONObject jsonParam = this.getJsonRequest();
        logger.info("login_by_weixin 登录参数：{}",JSONObject.toJSONString(jsonParam));
        FullUserInfo fullUserInfo = null;
        String code = "";
        if (!StringUtils.isNullOrEmpty(jsonParam.getString("code"))) {
            code = jsonParam.getString("code");
        }
        if (null != jsonParam.get("userInfo")) {
            fullUserInfo = jsonParam.getObject("userInfo", FullUserInfo.class);
        }
        if (null == fullUserInfo) {
            logger.error("登录失败");
            return toResponsFail("登录失败");
        }

        Map<String, Object> resultObj = new HashMap<String, Object>();
        //
        UserInfo userInfo = fullUserInfo.getUserInfo();

        //获取openid
        String requestUrl = ApiUserUtils.getWebAccess(code);//通过自定义工具类组合出小程序需要的登录凭证 code
        logger.info("》》》组合token为：" + requestUrl);
        JSONObject sessionData = CommonUtil.httpsRequest(requestUrl, "GET", null);

        if (null == sessionData || StringUtils.isNullOrEmpty(sessionData.getString("openid"))) {
            logger.error("登录失败");
            return toResponsFail("登录失败");
        }
        Date nowTime = new Date();
        UserVo userVo = userService.queryByOpenId(sessionData.getString("openid"));
        if (null == userVo) {
            userVo = new UserVo();
            userVo.setUsername("微信用户" + CharUtil.getRandomString(12));
            userVo.setPassword(sessionData.getString("openid"));
            userVo.setRegister_time(nowTime);
            userVo.setRegister_ip(this.getClientIp());
            userVo.setLast_login_ip(userVo.getRegister_ip());
            userVo.setLast_login_time(userVo.getRegister_time());
            userVo.setWeixin_openid(sessionData.getString("openid"));
            userVo.setAvatar(userInfo.getAvatarUrl());
            //性别 0：未知、1：男、2：女
            userVo.setGender(userInfo.getGender());
            userVo.setNickname(userInfo.getNickName());
            userService.save(userVo);
        } else {
            userVo.setLast_login_ip(this.getClientIp());
            userVo.setLast_login_time(nowTime);
            userVo.setAvatar(userInfo.getAvatarUrl());
            userService.update(userVo);
            if(org.apache.commons.lang.StringUtils.isNotBlank(userVo.getMobile())){
                TbUser sysUserEntity = zhiHouseService.queryByUserMobile(userVo.getMobile());
                if(null == sysUserEntity){
                    userInfo.setIsAdmin(0);
                }else{
                    List<Long> brandIdList = mySysUserBrandService.queryBrandIdList(sysUserEntity.getId());
                    if(!CollectionUtils.isEmpty(brandIdList)){
                        userInfo.setIsAdmin(1);
                    }else{
                        userInfo.setIsAdmin(0);
                    }
                }

            }else{
                //默认用户为非管理员
                userInfo.setIsAdmin(0);
            }
        }

        // 调用zfb 登录
        ReturnDTO returnDTO = zhiHouseService.wcLogin(sessionData.getString("openid"),userVo.getMobile(),userInfo.getNickName(),userInfo.getAvatarUrl());
        String token = JSONObject.parseObject(JSONObject.toJSONString(returnDTO.getMessage())).getString("token");

        if (StringUtils.isNullOrEmpty(token)) {
            logger.error("登录失败");
            return toResponsFail("登录失败");
        }
        List<Map<String , Object>> brandList = myApiTmBrandAdminService.getUserBrand(userVo.getUserId());
        resultObj.put("token", token);
        resultObj.put("userInfo", userInfo);
        resultObj.put("brandList", brandList);
        resultObj.put("userId", userVo.getUserId());
        resultObj.put("sessionKey" , sessionData.getString("session_key"));
        logger.info("login_by_weixin 登录成功，结果：{}",JSONObject.toJSONString(resultObj));
        return toResponsSuccess(resultObj);
    }

    /**
     * 支付宝登录
     */
    @ApiOperation(value = "支付宝登录")
    @IgnoreAuth
    @PostMapping("login_by_ali")
    public Object login_by_ali() {
        JSONObject jsonParam = this.getJsonRequest();
        String code = "";
        if (!StringUtils.isNullOrEmpty(jsonParam.getString("code"))) {
            code = jsonParam.getString("code");
        }
        AlipayClient alipayClient = new DefaultAlipayClient(ResourceUtil.getConfigByName("ali.webAccessTokenhttps"), ResourceUtil.getConfigByName("ali.appId"), ResourceUtil.getConfigByName("ali.privateKey"),
                "json", "UTF-8", ResourceUtil.getConfigByName("ali.pubKey"), "RSA2");
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setCode(code);
        request.setGrantType("authorization_code");
        try {
            //code 换取token
            AlipaySystemOauthTokenResponse oauthTokenResponse = alipayClient.execute(request);
            String accessToken = oauthTokenResponse.getAccessToken();

            //根据token获取用户头像、昵称等信息
            AlipayUserInfoShareRequest userInfoShareRequest = new AlipayUserInfoShareRequest();
            AlipayUserInfoShareResponse userInfoResponse = alipayClient.execute(userInfoShareRequest, accessToken);

            Date nowTime = new Date();
            UserVo userVo = userService.queryByOpenId(userInfoResponse.getUserId());
            if (null == userVo) {
                userVo = new UserVo();
                userVo.setUsername("支付宝用户" + CharUtil.getRandomString(12));
                userVo.setPassword(userInfoResponse.getUserId());
                userVo.setRegister_time(nowTime);
                userVo.setRegister_ip(this.getClientIp());
                userVo.setLast_login_ip(userVo.getRegister_ip());
                userVo.setLast_login_time(nowTime);
                userVo.setWeixin_openid(userInfoResponse.getUserId());
                userVo.setAvatar(userInfoResponse.getAvatar());
                //性别 0：未知、1：男、2：女
                //F：女性；M：男性
                userVo.setGender("m".equalsIgnoreCase(userInfoResponse.getGender()) ? 1 : 0);
                userVo.setNickname(userInfoResponse.getNickName());
                userService.save(userVo);
            } else {
                userVo.setLast_login_ip(this.getClientIp());
                userVo.setLast_login_time(nowTime);
                userService.update(userVo);
            }

            Map<String, Object> tokenMap = tokenService.createToken(userVo.getUserId());
            String token = MapUtils.getString(tokenMap, "token");

            if (StringUtils.isNullOrEmpty(token)) {
                return toResponsFail("登录失败");
            }

            Map<String, Object> resultObj = new HashMap<String, Object>();
            resultObj.put("token", token);
            resultObj.put("userInfo", userInfoResponse);
            resultObj.put("userId", userVo.getUserId());
            return toResponsSuccess(resultObj);
        } catch (AlipayApiException e) {
            return toResponsFail("登录失败");
        }
    }
}
