package com.ff.base.utils.domain;

import com.ff.base.enums.DomainType;
import com.ff.base.exception.base.BaseException;
import com.ff.base.utils.JsonUtil;
import com.ff.base.utils.MessageUtils;
import com.ff.base.utils.StringUtils;
import com.ff.base.utils.http.HttpClientSslUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 域有用
 *
 * @author shi
 * @date 2025/01/02
 */
@Slf4j
public class DomainUtils {


    /**
     * 查询域信息
     *
     * @param domainName 域名
     * @return {@link DomainInfo }
     */
    public static DomainInfo queryDomainInfo(String domainName) {
        try {
            String result = HttpClientSslUtils.doGet("https://api.whois.vu/?q="+domainName+"&output=json");
            DomainInfo domainInfo = JsonUtil.stringToObj(result, DomainInfo.class);
            if (ObjectUtils.isEmpty(domainInfo)|| ObjectUtils.isEmpty(domainInfo.getExpires())) {
                throw new BaseException(MessageUtils.message("operation.domain.resolve.failed", domainName));
            }
            return domainInfo;
        } catch (Exception e) {
            throw new BaseException(MessageUtils.message("operation.domain.resolve.failed", domainName));
        }

    }

    /**
     * 生成一个随机域名
     *
     * @return 随机生成的域名
     */
    public static String getRandomDomain() {
        // 生成随机字符串（UUID 去掉 `-`）
        String randomString = UUID.randomUUID().toString().replace("-", "");
        // 限制域名主体长度（如前 10 个字符）
        randomString = randomString.substring(0, 10);
        // 拼接顶级域名
        String domain = randomString + ".example.com";
        return domain;
    }

    /**
     * 判断域名类型
     *
     * @param domain 域名字符串
     * @return 域名类型："根域名"、"子域名"、"泛解析域名" 或 "无效域名"
     */
    public static Integer determineDomainType(String domain) {
        if (domain == null || domain.isEmpty()) {
            return null;
        }

        // 验证是否是泛解析域名
        if (isWildcardDomain(domain)) {
            return DomainType.WILDCARD_DOMAIN.getValue();
        }

        // 验证是否是根域名
        if (isRootDomain(domain)) {
            return DomainType.ROOT_DOMAIN.getValue();
        }

        // 验证是否是子域名
        if (isSubDomain(domain)) {
            return DomainType.SUB_DOMAIN.getValue();
        }

        return null;
    }

    /**
     * 验证是否是泛解析域名（如 *.example.com）
     */
    private static boolean isWildcardDomain(String domain) {
        String wildcardRegex = "^\\*\\.([a-zA-Z0-9-]+\\.[a-zA-Z]{2,})$";
        return domain.matches(wildcardRegex);
    }

    /**
     * 验证是否是根域名（如 example.com）
     */
    private static boolean isRootDomain(String domain) {
        String rootDomainRegex = "^[a-zA-Z0-9-]+\\.[a-zA-Z]{2,}$";
        return domain.matches(rootDomainRegex);
    }

    /**
     * 验证是否是子域名（如 sub.example.com）
     */
    private static boolean isSubDomain(String domain) {
        String subDomainRegex = "^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+\\.[a-zA-Z]{2,}$";
        if (!domain.matches(subDomainRegex)) {
            return false;
        }

        // 确保根域名有效
        String rootDomain = extractRootDomain(domain);
        return rootDomain != null && !domain.equals(rootDomain);
    }

    /**
     * 提取根域名（如从 sub.example.com 提取 example.com）
     */
    private static String extractRootDomain(String domain) {
        String rootDomainRegex = "([a-zA-Z0-9-]+\\.[a-zA-Z]{2,})$";
        Matcher matcher = Pattern.compile(rootDomainRegex).matcher(domain);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return null;
    }

    /**
     * 自动向域名拼接参数
     *
     * @param baseUrl 域名（基础 URL）
     * @param params  参数集合（Map 类型）
     * @return 拼接后的完整 URL
     */
    public static String buildUrlWithParams(String baseUrl, Map<String, Object> params) {
        if (StringUtils.isEmpty(baseUrl)) {
            return null;
        }
        StringBuilder urlBuilder = new StringBuilder(baseUrl);

        // 检查是否已有查询参数，如果没有则添加 "?"
        if (baseUrl.contains("?")) {
            urlBuilder.append("&");
        } else {
            urlBuilder.append("?");
        }

        // 遍历参数 Map，逐一添加到 URL 中
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            try {
                // 使用 URL 编码确保特殊字符处理
                String encodedKey = URLEncoder.encode(entry.getKey(), "UTF-8");
                String encodedValue = URLEncoder.encode(String.valueOf(entry.getValue()), "UTF-8");
                urlBuilder.append(encodedKey)
                        .append("=")
                        .append(encodedValue)
                        .append("&");
            } catch (UnsupportedEncodingException e) {
                log.error("URL 编码失败：{}", e.getMessage());
            }
        }

        // 删除最后一个多余的 "&"
        if (urlBuilder.charAt(urlBuilder.length() - 1) == '&') {
            urlBuilder.deleteCharAt(urlBuilder.length() - 1);
        }

        return urlBuilder.toString();
    }

}
