package com.corewing.app.util;

import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.InputStream;

/**
 * IP 归属地查询工具类
 */
@Slf4j
@Component
public class Ip2RegionUtil {

    private Searcher searcher;
    private byte[] vIndex;

    /**
     * 初始化 IP2Region 搜索器
     */
    @PostConstruct
    public void init() {
        try {
            // 从 classpath 加载 xdb 文件
            ClassPathResource resource = new ClassPathResource("ipdb/ip2region.xdb");
            InputStream inputStream = resource.getInputStream();

            // 将 InputStream 转换为 byte[]
            vIndex = new byte[inputStream.available()];
            inputStream.read(vIndex);
            inputStream.close();

            // 创建 searcher 对象
            searcher = Searcher.newWithBuffer(vIndex);
            log.info("IP2Region 初始化成功");
        } catch (Exception e) {
            log.error("IP2Region 初始化失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 根据 IP 地址查询归属地
     *
     * @param ip IP 地址
     * @return 归属地信息，格式：国家|区域|省份|城市|ISP
     */
    public String getRegion(String ip) {
        if (ip == null || ip.trim().isEmpty()) {
            return "未知";
        }

        // 过滤本地 IP
        if (isLocalIp(ip)) {
            return "局域网";
        }

        try {
            if (searcher == null) {
                log.warn("IP2Region 搜索器未初始化");
                return "未知";
            }

            String region = searcher.search(ip);
            return formatRegion(region);
        } catch (Exception e) {
            log.error("查询 IP 归属地失败, IP: {}, 异常: {}", ip, e.getMessage());
            return "未知";
        }
    }

    /**
     * 格式化归属地信息
     * 原始格式：国家|区域|省份|城市|ISP
     * 格式化后：省份-城市
     *
     * @param region 原始归属地信息
     * @return 格式化后的归属地
     */
    private String formatRegion(String region) {
        if (region == null || region.trim().isEmpty()) {
            return "未知";
        }

        try {
            String[] parts = region.split("\\|");
            if (parts.length < 5) {
                return region;
            }

            String country = parts[0];
            String province = parts[2];
            String city = parts[3];

            // 处理国内 IP
            if ("中国".equals(country)) {
                // 如果省份和城市相同，只返回省份
                if (province.equals(city)) {
                    return province;
                }
                // 如果省份或城市为 0，说明数据不完整
                if ("0".equals(province) || "0".equals(city)) {
                    return "中国";
                }
                return province + "-" + city;
            }

            // 处理国外 IP
            if (!"0".equals(country) && !country.isEmpty()) {
                return country;
            }

            return "未知";
        } catch (Exception e) {
            log.error("格式化归属地信息失败: {}", region, e);
            return region;
        }
    }

    /**
     * 判断是否为本地 IP
     *
     * @param ip IP 地址
     * @return 是否为本地 IP
     */
    private boolean isLocalIp(String ip) {
        return ip.startsWith("127.") ||
               ip.startsWith("192.168.") ||
               ip.startsWith("10.") ||
               ip.startsWith("172.16.") ||
               ip.startsWith("172.17.") ||
               ip.startsWith("172.18.") ||
               ip.startsWith("172.19.") ||
               ip.startsWith("172.20.") ||
               ip.startsWith("172.21.") ||
               ip.startsWith("172.22.") ||
               ip.startsWith("172.23.") ||
               ip.startsWith("172.24.") ||
               ip.startsWith("172.25.") ||
               ip.startsWith("172.26.") ||
               ip.startsWith("172.27.") ||
               ip.startsWith("172.28.") ||
               ip.startsWith("172.29.") ||
               ip.startsWith("172.30.") ||
               ip.startsWith("172.31.") ||
               "localhost".equalsIgnoreCase(ip) ||
               "0:0:0:0:0:0:0:1".equals(ip);
    }

    /**
     * 获取完整的归属地信息（用于调试）
     *
     * @param ip IP 地址
     * @return 完整的归属地信息
     */
    public String getFullRegion(String ip) {
        if (ip == null || ip.trim().isEmpty()) {
            return "未知";
        }

        if (isLocalIp(ip)) {
            return "局域网";
        }

        try {
            if (searcher == null) {
                log.warn("IP2Region 搜索器未初始化");
                return "未知";
            }

            return searcher.search(ip);
        } catch (Exception e) {
            log.error("查询 IP 归属地失败, IP: {}, 异常: {}", ip, e.getMessage());
            return "未知";
        }
    }
}
