package com.yaoyuan.jiscuss.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.Set;

/**
 * Lightweight IP region service.
 *
 * <p>Current implementation distinguishes local/private addresses from external ones.
 * To display accurate province-level location (e.g. "北京", "广东"), replace the
 * {@code lookupExternal} method with an ip2region XDB lookup or similar offline database.
 *
 * <p>Upgrade path:
 * <ol>
 *   <li>Add {@code org.lionsoul:ip2region:2.7.0} to pom.xml</li>
 *   <li>Place {@code ip2region.xdb} (from the ip2region GitHub release) under
 *       {@code src/main/resources/}</li>
 *   <li>Replace {@code lookupExternal()} with:
 *       {@code Searcher.newWithFileOnly(xdbPath).searchByStr(ip)}</li>
 * </ol>
 */
@Service
public class IpRegionService {

    private static final Logger log = LoggerFactory.getLogger(IpRegionService.class);

    private static final Set<String> LOCAL_PREFIXES = Set.of(
            "127.", "0.", "::1", "0:0:0:0:0:0:0:1"
    );

    private static final Set<String> PRIVATE_PREFIXES = Set.of(
            "10.", "192.168.", "172.16.", "172.17.", "172.18.", "172.19.",
            "172.20.", "172.21.", "172.22.", "172.23.", "172.24.", "172.25.",
            "172.26.", "172.27.", "172.28.", "172.29.", "172.30.", "172.31."
    );

    /**
     * Returns a display-friendly region label for the given IP address.
     *
     * @param ip client IP string (IPv4 or IPv6)
     * @return region label, e.g. "本地", "局域网", or "未知地区"
     */
    public String getRegion(String ip) {
        if (ip == null || ip.isBlank()) {
            return "";
        }
        for (String prefix : LOCAL_PREFIXES) {
            if (ip.startsWith(prefix)) {
                return "本地";
            }
        }
        for (String prefix : PRIVATE_PREFIXES) {
            if (ip.startsWith(prefix)) {
                return "局域网";
            }
        }
        return lookupExternal(ip);
    }

    /**
     * Override this method to integrate an offline IP database (e.g. ip2region).
     * Default implementation returns "未知地区" as a placeholder.
     */
    protected String lookupExternal(String ip) {
        // TODO: integrate ip2region XDB for accurate province-level lookup
        return "未知地区";
    }
}
