package com.cyksj.service.authorization.impl;

import cn.hutool.core.util.URLUtil;
import com.cyksj.common.EnvCommonService;
import com.cyksj.common.util.Codec;
import com.cyksj.config.WeChatConfig;
import com.cyksj.enums.WeChatAuthRedirectUrl;
import com.cyksj.model.dto.JsSdkTicket;
import com.cyksj.service.authorization.AuthorizationService;
import com.cyksj.service.wechat.WeChatService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * @author chan
 * @className AuthorizationServiceImpl
 * @description 授权服务
 * @date 2021/10/8 1:58 下午
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class AuthorizationServiceImpl implements AuthorizationService {

    private final WeChatService weChatService;

    private final WeChatConfig weChatConfig;

    private final EnvCommonService envCommonService;


    // 提取获取Host的逻辑，避免重复创建URL对象
    private String getHostFromUrl(String url) throws MalformedURLException {
        return URLUtil.getHost(new URL(url)).getHost();
    }

    @Override
    public String createUrl(String url, String state, String authType) throws MalformedURLException {
        // 获取重定向URL的Host
        String redirectHost = getHostFromUrl(url);

        // 从配置中获取预设的回调URL，并获取其Host
        String preUrl = weChatConfig.getDomain();
        String authHost = getHostFromUrl(preUrl);

        // 记录回调URL日志
        log.info("回调url: {}", preUrl);

        // 构造最终的重定向URL
        String weChatRedirectUrl = weChatConfig.getDomain() + WeChatAuthRedirectUrl.get(authType).getUrl();

        // 如果重定向URL和授权域名不同，则追加 "/other"
        if (!redirectHost.equals(authHost)) {
            weChatRedirectUrl += "/other";
        }

        return weChatService.createUrl(
                state,
                weChatRedirectUrl,
                weChatConfig.getAppid(),
                WeChatAuthRedirectUrl.get(authType).getScope()
        );
    }

    @Override
    public JsSdkTicket getJsTicket(String appId, String url) throws Exception {

        // 获取js-ticket
        String ticket = weChatService.getJsTicket(appId);

        // 生成js-sdk权限验证 签名
        JsSdkTicket jsSdkTicket = new JsSdkTicket();
        jsSdkTicket.setAppid(appId);
        jsSdkTicket.setNonceStr("chan");
        jsSdkTicket.setTimestamp(System.currentTimeMillis());

        String str = "jsapi_ticket=" + ticket +
                "&noncestr=" + jsSdkTicket.getNonceStr() +
                "&timestamp=" + jsSdkTicket.getTimestamp() +
                "&url=" + url;

        String sha1Hex = Codec.DoDigest.custom()
                .setAlgorithm(Codec.DoDigest.Algorithm.SHA1).setStringData(str).toHexString();
        jsSdkTicket.setSignature(sha1Hex);
        return jsSdkTicket;
    }

    @Override
    public String createWxAuthLoginUrl(String state, String appId, String redirectUrl) {
        return weChatService.createWxAuthLoginUrl(state, appId, URLEncoder.encode(redirectUrl, StandardCharsets.UTF_8));
    }

}
