package cn.hanghui.outapi.platform.alipay.controller;

import cn.hanghui.outapi.platform.alipay.entity.dto.AlipayUserInfoReqDto;
import cn.hanghui.outapi.platform.alipay.entity.param.AlipayUserInfo;
import cn.hanghui.outapi.platform.alipay.service.AlipayFaceAuthService;
import cn.hanghui.outapi.platform.common.entity.rest.RestResult;
import cn.hanghui.outapi.platform.common.entity.rest.Result;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

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

@Slf4j
@Validated
@Api(tags = "支付宝人脸认证服务")
@RestController
@RequestMapping("alipayApi/faceAuth")
public class AlipayFaceAuthController {

    @Autowired
    private AlipayFaceAuthService alipayFaceAuthService;

    /**
     * 获取支付宝用户信息
     *
     * @param alipayUserInfoReqDto AlipayUserInfoReqDto
     * @return Result<AlipayUserInfo>
     */
    @ApiOperation("获取支付宝用户信息")
    @PostMapping("getAlipayUserInfo")
    public Result<AlipayUserInfo> getAlipayUserInfo(@RequestBody @Validated AlipayUserInfoReqDto alipayUserInfoReqDto) {
        log.info("--->获取支付宝用户信息原始入参:{}", JSONObject.toJSONString(alipayUserInfoReqDto));
        if (alipayUserInfoReqDto.getAuthCode() == null
                && alipayUserInfoReqDto.getSn() == null
                && alipayUserInfoReqDto.getFtoken() == null
                && alipayUserInfoReqDto.getAlipayUid() == null) {
            log.error("--->参数有误");
            return Result.ok(new AlipayUserInfo());
        }
        return Result.ok(alipayFaceAuthService.getAlipayUserInfo(alipayUserInfoReqDto));
    }

    /**
     * • appId为空时默认2188
     * • 会根据sn获取appId
     * • 然后选择对应网关sdk
     *
     * @param alipayUserInfoReqDto
     * @return
     */
    @ApiOperation("获取支付宝用户信息 (新版本 通用)")
    @PostMapping("/common/getAlipayUserInfo")
    public Result<AlipayUserInfo> getCommonAlipayUserInfo(@RequestBody @Validated AlipayUserInfoReqDto alipayUserInfoReqDto) {
        log.info("--->获取通用支付宝用户信息原始入参:{}", JSONObject.toJSONString(alipayUserInfoReqDto));
        if (alipayUserInfoReqDto.getAuthCode() == null
                && alipayUserInfoReqDto.getSn() == null
                && alipayUserInfoReqDto.getFtoken() == null
                && alipayUserInfoReqDto.getAlipayUid() == null) {
            log.error("--->参数有误");
            return Result.ok(new AlipayUserInfo());
        }
        return Result.ok(alipayFaceAuthService.getCommonAlipayUserInfo(alipayUserInfoReqDto));
    }

    @ApiOperation("获取支付宝用户信息(通用查询 一对多模型)")
    @PostMapping("/common/user/info/query")
    public Result<AlipayUserInfo> queryCommonUserInfo(@RequestBody @Validated AlipayUserInfoReqDto alipayUserInfoReqDto) {
        log.info("--->获取支付宝用户信息原始入参:{}", JSONObject.toJSONString(alipayUserInfoReqDto));
        if (alipayUserInfoReqDto.getAuthCode() == null
                && alipayUserInfoReqDto.getSn() == null
                && alipayUserInfoReqDto.getFtoken() == null
                && alipayUserInfoReqDto.getAlipayUid() == null) {
            log.error("--->获取用户信息原始入参参数有误");
            return Result.ok(new AlipayUserInfo());
        }
        return Result.ok(alipayFaceAuthService.queryCommonUserInfo(alipayUserInfoReqDto));
    }



    /**
     * 商家授权成功后，商家的页面跳转至服务商定义的回调地址（即 redirect_uri 参数对应的 URL），
     * 在回调页面请求中会带上当次授权的授权码 app_auth_code 和第三方应用的 APPID，示例如下。
     * http://example.com/doc/toAuthPage.html?app_id=2021000000000318&source=alipay_app_auth&application_type=TINYAPP,WEBAPP&app_auth_code=P1798b23682e34d96859afa000000003
     * 说明：应用授权回调请求包含 app_auth_code=xxx，source=alipay_app_auth 字段，可以区别于 C 端用户授权。
     * 使用 app_auth_code 换取 app_auth_token
     * <p>
     * 服务商通过回调请求，获取到 app_auth_code 参数，然后调用 alipay.open.auth.token.app（换取应用授权令牌）接口，换取 app_auth_token。
     * 说明：
     * • 应用授权的 app_auth_code 是唯一的。app_auth_code 使用一次后失效，单个授权的有效期为一天（从生成 app_auth_code 开始的 24 小时），未被使用自动过期。
     * 批量授权的有效期为 10 分钟。
     * • app_auth_token 在没有重新授权、取消授权或刷新授权的情况下，永久有效。
     * • 商家应用重新授权后，app_auth_token 会刷新（刷新后原 token 仍存在 5~10min 的缓存期），建议服务商通过系统链路将 app_auth_token 入库，可保障及时更新，
     * 发起代调用请求时从数据库读取该字段，以避免手动更新时影响存量线上业务。
     *
     * @return
     */
    @ApiOperation("isv三方授权回调接口")
    @GetMapping("/isv/callback")
    public RestResult callback(HttpServletRequest request,
                               @RequestParam(value = "app_id", required = true) String appId,
                               @RequestParam(value = "source", required = false) String source,
                               @RequestParam(value = "application_type", required = false) String applicationType,
                               @RequestParam(value = "app_auth_code", required = true) String appAuthCode) {
        log.info("---->ISV原始入参:{}", JSONObject.toJSONString(getParam(request)));
        log.info("---->ISV原始入参:{}", JSONObject.toJSONString(request.getParameterNames()));
        if (appId == null || appAuthCode == null) {
            return RestResult.error("参数有误，请检查后提交！");
        }
        alipayFaceAuthService.authIsvCallback(appId, appAuthCode);
        return RestResult.ok();
    }


    private Map<String, String> getParam(HttpServletRequest request) {
        Map<String, String> filterMap = new HashMap<>();
        try {
            request.setCharacterEncoding("utf-8");
            //遍历
            Map<String, String[]> map = request.getParameterMap();
            if (map.isEmpty()) {
                return filterMap;
            }
            for (String key : map.keySet()) {
                log.info(key + ":");
                // 获取值
                String[] values = map.get(key);
                if (values.length > 0) {
                    filterMap.put(key, values[0]);
                    for (String value : values) {
                        log.info(value + ":");
                    }
                }
            }

        } catch (Exception e) {
            log.error("--->获取get参数异常", e);
        }
        return filterMap;
    }


}
