<?php
// +----------------------------------------------------------------------
// | 麦沃德科技赋能开发者，助力中小企业发展 
// +----------------------------------------------------------------------
// | Copyright (c) 2017～2024  www.wdadmin.cn    All rights reserved.
// +----------------------------------------------------------------------
// | Wdadmin系统产品软件并不是自由软件，不加密，并不代表开源，未经许可不可自由转售和商用
// +----------------------------------------------------------------------
// | Author: MY WORLD Team <bd@maiwd.cn>   www.wdadmin.cn
// +----------------------------------------------------------------------
namespace app\common\service;

use Ip2Region;
use think\facade\Log;

class IpService
{
    /**
     * 根据IP获取地理位置信息
     * * @param string $ip 目标IP地址
     * @return array|null 返回包含省、市、运营商的数组，失败返回 null
     */
    public static function getLocation(string $ip): ?array
    {
        // 1. 简单的 IP 格式校验
        if (!filter_var($ip, FILTER_VALIDATE_IP)) {
            return null;
        }

        try {
            // 2. 实例化 Ip2Region
            // 使用默认缓存策略 'file'，并指定 IPv4 数据库路径
            // root_path() 是 TP8 获取项目根目录的助手函数
            $dbPath = root_path() . '/public/storage/ip2region_v4.xdb';

            // 检查文件是否存在
            if (!file_exists($dbPath)) {
                Log::error("IP数据库文件不存在: " . $dbPath);
                return null;
            }

            // 实例化 Ip2Region，传入缓存策略和数据库路径
            $ip2region = new Ip2Region('file', $dbPath);

            // 3. 执行查询 (使用 getIpInfo 方法，返回结构化数据)
            // 返回格式：['country' => '国家', 'province' => '省份', 'city' => '城市', 'isp' => 'ISP']
            $result = $ip2region->getIpInfo($ip);

            // 4. 返回结果
            if ($result && is_array($result)) {
                // 过滤掉 '0' 这种无效数据
                return [
                    'country'  => ($result['country'] ?? '') === '0' ? '' : ($result['country'] ?? ''),
                    'province' => ($result['province'] ?? '') === '0' ? '' : ($result['province'] ?? ''),
                    'city'     => ($result['city'] ?? '') === '0' ? '' : ($result['city'] ?? ''),
                    'isp'      => ($result['isp'] ?? '') === '0' ? '' : ($result['isp'] ?? ''),
                    'ip'       => $result['ip'] ?? $ip,
                    'version'  => $result['version'] ?? 'v4'
                ];
            }

            return null;

        } catch (\Exception $e) {
            // 记录错误日志，防止报错中断业务
            Log::error("IP定位失败: " . $e->getMessage());
            return null;
        }
    }
}