<?php

namespace Kylin\World\Services;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

/**
 * 行政区划查询服务
 *
 * 提供国家/省份/城市/区县四级行政区划数据查询，
 * 支持缓存加速、按层级和父级 ID 筛选。
 *
 * 数据标准：
 *  - ISO 3166-1：国家代码（alpha-2）
 *  - ISO 3166-2：行政区划代码
 *  - ISO 4217：货币代码
 *  - ITU-T E.164：电话区号
 *  - GB/T 2260-2007：中华人民共和国行政区划代码
 */
class RegionService
{
    /**
     * 获取所有国家
     */
    public function getCountries(): array
    {
        return Cache::remember('kylin-world-countries', 86400, fn () =>
            DB::table('kylin_regions')
                ->where('level', 0)
                ->orderBy('sort', 'asc')
                ->get()
                ->toArray()
        );
    }

    /**
     * 获取所有国家（别名）
     */
    public function countries(): array
    {
        return $this->getCountries();
    }

    /**
     * 获取指定国家的省份
     */
    public function getProvinces(string $countryCode): array
    {
        return Cache::remember("kylin-world-provinces-{$countryCode}", 86400, fn () =>
            DB::table('kylin_regions')
                ->where('level', 1)
                ->where('country_code', $countryCode)
                ->orderBy('sort', 'asc')
                ->get()
                ->toArray()
        );
    }

    /**
     * 获取指定国家的省份（别名）
     */
    public function provinces(string $countryCode): array
    {
        return $this->getProvinces($countryCode);
    }

    /**
     * 获取指定父级下的城市
     */
    public function getCities(int $parentId): array
    {
        return Cache::remember("kylin-world-cities-{$parentId}", 86400, fn () =>
            DB::table('kylin_regions')
                ->where('level', 2)
                ->where('parent_id', $parentId)
                ->orderBy('sort', 'asc')
                ->get()
                ->toArray()
        );
    }

    /**
     * 获取指定父级下的城市（别名）
     */
    public function cities(int $parentId): array
    {
        return $this->getCities($parentId);
    }

    /**
     * 获取指定父级下的区县
     */
    public function getDistricts(int $parentId): array
    {
        return Cache::remember("kylin-world-districts-{$parentId}", 86400, fn () =>
            DB::table('kylin_regions')
                ->where('level', 3)
                ->where('parent_id', $parentId)
                ->orderBy('sort', 'asc')
                ->get()
                ->toArray()
        );
    }

    /**
     * 获取指定父级下的区县（别名）
     */
    public function districts(int $parentId): array
    {
        return $this->getDistricts($parentId);
    }

    /**
     * 获取完整行政区划树
     */
    public function getRegionTree(string $countryCode = 'CN'): array
    {
        return Cache::remember("kylin-world-tree-{$countryCode}", 86400, function () use ($countryCode) {
            $regions = DB::table('kylin_regions')
                ->where('country_code', $countryCode)
                ->orderBy('level', 'asc')
                ->orderBy('sort', 'asc')
                ->get();

            $tree = [];
            $map = [];

            foreach ($regions as $region) {
                $node = [
                    'id' => $region->id,
                    'name' => $region->name,
                    'code' => $region->code,
                    'level' => $region->level,
                    'children' => [],
                ];
                $map[$region->id] = &$node;

                if ($region->parent_id && isset($map[$region->parent_id])) {
                    $map[$region->parent_id]['children'][] = &$node;
                } else {
                    $tree[] = &$node;
                }
            }

            return $tree;
        });
    }

    /**
     * 获取完整行政区划树（别名）
     */
    public function regionTree(string $countryCode = 'CN'): array
    {
        return $this->getRegionTree($countryCode);
    }

    /**
     * 按区域编码查询
     */
    public function byCode(string $code): ?object
    {
        return Cache::remember("kylin-world-code-{$code}", 86400, fn () =>
            DB::table('kylin_regions')
                ->where('code', $code)
                ->first()
        );
    }

    /**
     * 按名称查询
     */
    public function byName(string $name, ?string $countryCode = null): ?object
    {
        $cacheKey = "kylin-world-name-{$countryCode}-{$name}";
        return Cache::remember($cacheKey, 86400, function () use ($name, $countryCode) {
            $query = DB::table('kylin_regions')->where('name', $name);
            if ($countryCode !== null) {
                $query->where('country_code', $countryCode);
            }
            return $query->first();
        });
    }

    /**
     * 搜索行政区划
     */
    public function search(string $keyword, int $limit = 20): array
    {
        return DB::table('kylin_regions')
            ->where('name', 'like', "%{$keyword}%")
            ->orWhere('pinyin', 'like', "%{$keyword}%")
            ->orWhere('full_name', 'like', "%{$keyword}%")
            ->limit($limit)
            ->get()
            ->toArray();
    }

    /**
     * 清除所有缓存
     */
    public function clearCache(): void
    {
        Cache::forget('kylin-world-countries');
        // 清理按国家代码、父级 ID 缓存的键需要遍历，简单实现使用前缀扫描
        $keys = [
            'kylin-world-countries',
            "kylin-world-tree-CN",
        ];
        foreach ($keys as $key) {
            Cache::forget($key);
        }
    }
}
