package com.slodon.b2b2c.controller.member.front.advich;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.slodon.b2b2c.core.config.DomainUrlUtil;
import com.slodon.b2b2c.core.constant.NumConstant;
import com.slodon.b2b2c.core.constant.RedisConst;
import com.slodon.b2b2c.core.constant.ResponseConst;
import com.slodon.b2b2c.core.controller.BaseController;
import com.slodon.b2b2c.core.response.JsonResult;
import com.slodon.b2b2c.core.response.SldResponse;
import com.slodon.b2b2c.core.util.AESUtil;
import com.slodon.b2b2c.core.util.AssertUtil;
import com.slodon.b2b2c.core.util.StringUtil;
import com.slodon.b2b2c.dao.read.member.MemberReadMapper;
import com.slodon.b2b2c.dao.read.seller.VendorReadMapper;
import com.slodon.b2b2c.dto.OauthTokenDto;
import com.slodon.b2b2c.member.pojo.Member;
import com.slodon.b2b2c.model.member.MemberModel;
import com.slodon.b2b2c.model.member.advich.OneClickLoginModel;
import com.slodon.b2b2c.seller.pojo.Vendor;
import com.slodon.b2b2c.vo.member.GpSystemVO;
import com.slodon.b2b2c.vo.member.SsoMemberOauthVO;
import com.slodon.b2b2c.vo.member.SsoOauthLinkVO;
import com.slodon.b2b2c.vo.seller.SsoVendorOauthVO;
import io.swagger.annotations.Api;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

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

/**
 * @author cyan
 */
@Api(tags = "front-一键登录管理")
@RestController
@RequestMapping("/v3/open/api/sso/login")
@Slf4j
public class OneClickLoginController extends BaseController {

    @Resource
    private OneClickLoginModel oneClickLoginModel;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private MemberReadMapper memberReadMapper;

    @Resource
    private VendorReadMapper vendorReadMapper;

    /**
     * 生成密文
     *
     * @param request
     * @return
     */
    @PostMapping("/pc/encrypt")
    @ResponseBody
    public JsonResult<Object> pcEncrypt(HttpServletRequest request, @RequestBody GpSystemVO gpSystemVO) {
        String gpVoStr = JSON.toJSONString(gpSystemVO);
        log.info("gpVoStr:{}", gpVoStr);
        String gpEncryptStr = null;
        try {
            gpEncryptStr = AESUtil.encrypt(gpVoStr, DomainUrlUtil.GP_SYSTEM_CUSTOMER_SSO_ASE_KEY);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SldResponse.success(ResponseConst.STATE_SUCCESS, gpEncryptStr, "成功");
    }

    /**
     * 密文解密
     *
     * @param request
     * @return
     */
    @PostMapping("/pc/decrypt")
    @ResponseBody
    public JsonResult<Object> pcDecrypt(HttpServletRequest request, String param) {
        log.info("param:{}", param);
        String gpEncryptStr = null;
        try {
            gpEncryptStr = AESUtil.decrypt(param, DomainUrlUtil.GP_SYSTEM_CUSTOMER_SSO_ASE_KEY);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SldResponse.success(ResponseConst.STATE_SUCCESS, gpEncryptStr, "成功");
    }

    /**
     * 获取pc商城单点登录链接
     *
     * @param request
     * @return
     */
    @PostMapping("/pc/link")
    @ResponseBody
    public JsonResult<Object> getOauthPcLink(HttpServletRequest request, @RequestBody GpSystemVO gpSystemVO) {
        log.info("********** getOauthPcLink - gpSystemVO.getParam():{} *************", gpSystemVO.getParam());
        OauthTokenDto oauthTokenDto = new OauthTokenDto();
        String url = DomainUrlUtil.SLD_PC_URL + "/404";
        if (!StringUtil.isEmpty(gpSystemVO.getParam())) {
            String decryptParam = null;
            try {
                decryptParam = AESUtil.decrypt(gpSystemVO.getParam(), DomainUrlUtil.GP_SYSTEM_CUSTOMER_SSO_ASE_KEY);
            } catch (Exception e) {
                e.printStackTrace();
            }

            AssertUtil.notEmpty(decryptParam, "密文不正确");
            log.info("decryptParam:{}", decryptParam);

            GpSystemVO systemVO = JSON.parseObject(decryptParam, GpSystemVO.class);
            log.info("gpSystemVO1:{}", JSON.toJSONString(systemVO));

            if (systemVO != null && !StringUtil.isEmpty(systemVO.getUsername()) && !StringUtil.isEmpty(systemVO.getUid()) && !StringUtil.isEmpty(systemVO.getSource())) {
                oauthTokenDto = oneClickLoginModel.getOauthPcToken(request, systemVO);
                log.info("oauthTokenDto:{}", JSON.toJSONString(oauthTokenDto));
                if (!StringUtil.isEmpty(oauthTokenDto.getKey()) && NumConstant.ONE.equals(oauthTokenDto.getState())) {
                    url = DomainUrlUtil.SLD_PC_URL + "/oauth/link?oauthKey=" + oauthTokenDto.getKey();
                }

                if (NumConstant.MINUSONE.equals(oauthTokenDto.getState()) || NumConstant.MINUSTHREE.equals(oauthTokenDto.getState())) {
                    return SldResponse.fail("用户信息获取失败");
                }

                if (NumConstant.MINUSTWO.equals(oauthTokenDto.getState())) {
                    return SldResponse.fail("token不正确");
                }

            } else {
                return SldResponse.fail("参数不能为空");
            }
        }

        Map<String, String> map = new HashMap<>();
        map.put("url", url);
        map.put("token", oauthTokenDto.getToken());
        String mapStr = JSON.toJSONString(map);
        log.info("mapStr:{}", mapStr);

        String mapEncryptStr = null;
        try {
            mapEncryptStr = AESUtil.encrypt(mapStr, DomainUrlUtil.GP_SYSTEM_CUSTOMER_SSO_ASE_KEY);
        } catch (Exception e) {
            e.printStackTrace();
        }
        AssertUtil.notEmpty(mapEncryptStr, "跳转链接生成失败");
        log.info("mapEncryptStr:{}", mapEncryptStr);
        return SldResponse.success(ResponseConst.STATE_SUCCESS, mapEncryptStr, "成功");
    }

    /**
     * 跳转pc商城
     *
     * @param request
     * @param oauthKey
     * @return
     */
    @PostMapping("/pc")
    public JsonResult<Object> getOauthPc(HttpServletRequest request, String oauthKey) {
        log.info("********** getOauthPc - oauthKey:{} *************", oauthKey);
        if (!StringUtil.isEmpty(oauthKey)) {
            String oauthInfo = oneClickLoginModel.getOauthPcTokenInfoByOauthId(oauthKey);
            log.info("oauthInfo:{}", oauthInfo);
            if (!StringUtil.isEmpty(oauthInfo)) {
                SsoMemberOauthVO ssoMemberOauthVO = JSON.parseObject(oauthInfo, SsoMemberOauthVO.class);
                if (ssoMemberOauthVO != null && ssoMemberOauthVO.getMemberId() != null && !StringUtil.isEmpty(ssoMemberOauthVO.getToken())) {
                    Member memberInfo = memberReadMapper.getByPrimaryKey(Integer.parseInt(ssoMemberOauthVO.getMemberId()));
                    log.info("getOauthPc ==> memberInfo:{}", JSON.toJSONString(memberInfo));
                    AssertUtil.notNull(memberInfo, "用户信息验证失败");
                    JsonResult jsonResult = oneClickLoginModel.createPcToken(memberInfo);
                    if (jsonResult.getState() == ResponseConst.STATE_SUCCESS) {
                        String key = RedisConst.SLD_PC_OAUTH_USER_KEY + oauthKey;
                        stringRedisTemplate.delete(key);
                    }
                    return jsonResult;
                }
            } else {
                return SldResponse.fail("oauthKey失效");
            }
        }
        return SldResponse.fail("参数不能为空");
    }

    /**
     * 获取Seller单点登录链接
     *
     * @param request
     * @param gpSystemVO
     * @return
     */
    @PostMapping("/seller/link")
    @ResponseBody
    public JsonResult<Object> getOauthSellerLink(HttpServletRequest request, @RequestBody GpSystemVO gpSystemVO) {
        log.info("********** getOauthSellerLink - gpSystemVO.getParam():{} *************", gpSystemVO.getParam());
        OauthTokenDto oauthTokenDto = new OauthTokenDto();
        String url = DomainUrlUtil.SLD_SELLER_URL + "/404";
        if (!StringUtil.isEmpty(gpSystemVO.getParam())) {
            String decryptParam = null;
            try {
                decryptParam = AESUtil.decrypt(gpSystemVO.getParam(), DomainUrlUtil.GP_SYSTEM_CUSTOMER_SSO_ASE_KEY);
            } catch (Exception e) {
                e.printStackTrace();
            }

            AssertUtil.notEmpty(decryptParam, "密文不正确");
            log.info("decryptParam:{}", decryptParam);

            GpSystemVO systemVO = JSON.parseObject(decryptParam, GpSystemVO.class);
            log.info("gpSystemVO1:{}", JSON.toJSONString(systemVO));

            if (systemVO != null && !StringUtil.isEmpty(systemVO.getUsername()) && !StringUtil.isEmpty(systemVO.getUid()) && !StringUtil.isEmpty(systemVO.getSource())) {
                oauthTokenDto = oneClickLoginModel.getOauthSellerToken(request, systemVO);
                log.info("oauthTokenDto:{}", JSON.toJSONString(oauthTokenDto));
                if (!StringUtil.isEmpty(oauthTokenDto.getKey()) && NumConstant.ONE.equals(oauthTokenDto.getState())) {
                    url = DomainUrlUtil.SLD_SELLER_URL + "/user/seller/link?oauthKey=" + oauthTokenDto.getKey();
                }

                if (NumConstant.MINUSONE.equals(oauthTokenDto.getState()) || NumConstant.MINUSTHREE.equals(oauthTokenDto.getState())) {
                    return SldResponse.fail("用户信息获取失败");
                }

                if (NumConstant.MINUSTWO.equals(oauthTokenDto.getState())) {
                    return SldResponse.fail("token不正确");
                }

                if (NumConstant.MINUSFOUR.equals(oauthTokenDto.getState())) {
                    return SldResponse.fail(oauthTokenDto.getStatusMsg());
                }

            } else {
                return SldResponse.fail("参数不能为空");
            }
        }

        Map<String, String> map = new HashMap<>();
        map.put("url", url);
        map.put("token", oauthTokenDto.getToken());
        String mapStr = JSON.toJSONString(map);
        log.info("mapStr:{}", mapStr);

        String mapEncryptStr = null;
        try {
            mapEncryptStr = AESUtil.encrypt(mapStr, DomainUrlUtil.GP_SYSTEM_CUSTOMER_SSO_ASE_KEY);
        } catch (Exception e) {
            e.printStackTrace();
        }
        AssertUtil.notEmpty(mapEncryptStr, "跳转链接生成失败");
        log.info("mapEncryptStr:{}", mapEncryptStr);
        return SldResponse.success(ResponseConst.STATE_SUCCESS, mapEncryptStr, "成功");


    }

    /**
     * 跳转Seller
     *
     * @param request
     * @param oauthKey
     * @return
     */
    @PostMapping("/seller")
    public JsonResult<Object> getOauthSeller(HttpServletRequest request, String oauthKey) {
        log.info("********** getOauthSeller - oauthKey:{} *************", oauthKey);
        String oauthSellerInfo = oneClickLoginModel.getOauthSellerTokenInfoByOauthId(oauthKey);
        log.info("oauthSellerInfo:{}", oauthSellerInfo);
        if (!StringUtil.isEmpty(oauthSellerInfo)) {
            SsoVendorOauthVO ssoVendorOauthVO = JSON.parseObject(oauthSellerInfo, SsoVendorOauthVO.class);
            if (ssoVendorOauthVO != null && ssoVendorOauthVO.getVendorId() != null && !StringUtil.isEmpty(ssoVendorOauthVO.getToken())) {
                Vendor vendor = vendorReadMapper.getByPrimaryKey(Integer.parseInt(ssoVendorOauthVO.getVendorId()));
                log.info("getOauthSeller ==> vendor:{}", JSON.toJSONString(vendor));
                AssertUtil.notNull(vendor, "用户信息验证失败");
                JsonResult jsonResult = oneClickLoginModel.createSellerToken(vendor);
                if (jsonResult.getState() == ResponseConst.STATE_SUCCESS) {
                    String oauthId = RedisConst.SLD_SELLER_OAUTH_USER_KEY + oauthKey;
                    stringRedisTemplate.delete(oauthId);
                }
                return jsonResult;
            } else {
                return SldResponse.fail("oauthKey失效");
            }
        }
        return SldResponse.fail("参数不能为空");
    }
}
