package com.ruoyi.common.utils.ip;

import java.io.InputStream;
import org.lionsoul.ip2region.service.Config;
import org.lionsoul.ip2region.service.Ip2Region;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.utils.StringUtils;

/**
 * ip2region 离线 IP 归属地查询工具。
 */
public final class Ip2RegionUtils
{
    private static final Logger log = LoggerFactory.getLogger(Ip2RegionUtils.class);

    private static final String XDB_CLASSPATH = "/ip2region/ip2region_v4.xdb";

    private static volatile Ip2Region ip2Region;

    private static volatile boolean initAttempted;

    private Ip2RegionUtils()
    {
    }

    /**
     * 查询 IP 归属地原始字符串，格式：Country|Province|City|ISP|Code。
     */
    public static String searchRegion(String ip)
    {
        if (StringUtils.isEmpty(ip))
        {
            return null;
        }
        Ip2Region service = getIp2Region();
        if (service == null)
        {
            return null;
        }
        try
        {
            return service.search(ip.trim());
        }
        catch (Exception ex)
        {
            log.warn("ip2region 查询失败 ip={}: {}", ip, ex.getMessage());
            return null;
        }
    }

    /**
     * 从 ip2region 结果中提取可用于区县展示的名称。
     */
    public static String extractDistrictName(String region)
    {
        if (StringUtils.isEmpty(region))
        {
            return null;
        }
        String[] parts = region.split("\\|");
        String city = parts.length > 2 ? nullIfZero(parts[2]) : null;
        String province = parts.length > 1 ? nullIfZero(parts[1]) : null;
        String country = parts.length > 0 ? nullIfZero(parts[0]) : null;
        return firstNonEmpty(city, province, country);
    }

    private static Ip2Region getIp2Region()
    {
        if (!initAttempted)
        {
            synchronized (Ip2RegionUtils.class)
            {
                if (!initAttempted)
                {
                    initAttempted = true;
                    ip2Region = createIp2Region();
                }
            }
        }
        return ip2Region;
    }

    private static Ip2Region createIp2Region()
    {
        try (InputStream inputStream = Ip2RegionUtils.class.getResourceAsStream(XDB_CLASSPATH))
        {
            if (inputStream == null)
            {
                log.warn("ip2region 数据库未找到: {}", XDB_CLASSPATH);
                return null;
            }
            Config v4Config = Config.custom()
                    .setCachePolicy(Config.BufferCache)
                    .setXdbInputStream(inputStream)
                    .asV4();
            return Ip2Region.create(v4Config, null);
        }
        catch (Exception ex)
        {
            log.error("ip2region 初始化失败", ex);
            return null;
        }
    }

    private static String nullIfZero(String value)
    {
        if (StringUtils.isEmpty(value) || "0".equals(value.trim()))
        {
            return null;
        }
        return value.trim();
    }

    private static String firstNonEmpty(String... values)
    {
        if (values == null)
        {
            return null;
        }
        for (String value : values)
        {
            if (StringUtils.isNotEmpty(value))
            {
                return value;
            }
        }
        return null;
    }
}
