<?php

namespace Kylin\Region\Services;

use Illuminate\Support\Facades\Cache;
use Kylin\Region\Models\Region;

/**
 * 行政区划服务
 *
 * 提供中国省市区街道四级行政区划数据查询。
 *
 * 数据来源：国家统计局公开发布的行政区划数据。
 * 法律合规：依据 GB/T 2260-2007《中华人民共和国行政区划代码》。
 */
class RegionService
{
    /**
     * 获取所有省份
     */
    public function getProvinces(): array
    {
        return Cache::remember('kylin.regions.provinces', 86400, fn () =>
            Region::where('level', 1)->orderBy('sort')->get(['id', 'code', 'name'])->toArray()
        );
    }

    /**
     * 获取省份（getProvinces 别名）
     */
    public function provinces(): array
    {
        return $this->getProvinces();
    }

    /**
     * 获取指定父级下的子地区
     */
    public function getChildren(int $parentId): array
    {
        return Cache::remember("kylin.regions.children.{$parentId}", 86400, fn () =>
            Region::where('parent_id', $parentId)->orderBy('sort')->get(['id', 'code', 'name', 'parent_id'])->toArray()
        );
    }

    /**
     * 获取城市列表（level=2）
     *
     * @param int $provinceCode 省份行政区划代码（如 110000=北京市）
     */
    public function cities(int $provinceCode): array
    {
        $province = Region::where('code', $provinceCode)->where('level', 1)->first();
        if (! $province) {
            return [];
        }
        return $this->getChildren($province->id);
    }

    /**
     * 获取区县列表（level=3）
     *
     * @param int $cityCode 城市行政区划代码（如 110100=北京市市辖区）
     */
    public function districts(int $cityCode): array
    {
        $city = Region::where('code', $cityCode)->where('level', 2)->first();
        if (! $city) {
            return [];
        }
        return $this->getChildren($city->id);
    }

    /**
     * 根据名称搜索地区
     *
     * @param string $keyword 关键词（如"海淀"）
     * @param int $limit 返回数量限制
     */
    public function search(string $keyword, int $limit = 50): array
    {
        return Cache::remember(
            "kylin.regions.search.{$keyword}.{$limit}",
            3600,
            fn () => Region::where('name', 'like', "%{$keyword}%")
                ->orderBy('level')
                ->orderBy('sort')
                ->limit($limit)
                ->get(['id', 'code', 'name', 'parent_id', 'level'])
                ->toArray()
        );
    }

    /**
     * 根据行政区划代码获取地区
     */
    public function byCode(int $code): ?array
    {
        return Cache::remember("kylin.regions.bycode.{$code}", 86400, function () use ($code) {
            $region = Region::where('code', $code)->first();
            return $region?->toArray();
        });
    }

    /**
     * 根据名称获取地区（精确匹配）
     */
    public function byName(string $name, ?int $level = null): ?array
    {
        $cacheKey = "kylin.regions.byname.{$name}." . ($level ?? 'all');
        return Cache::remember($cacheKey, 86400, function () use ($name, $level) {
            $query = Region::where('name', $name);
            if ($level !== null) {
                $query->where('level', $level);
            }
            return $query->first()?->toArray();
        });
    }

    /**
     * 获取完整树形结构
     */
    public function getTree(): array
    {
        return Cache::remember('kylin.regions.tree', 86400, function () {
            $regions = Region::orderBy('sort')->get(['id', 'parent_id', 'level', 'code', 'name']);
            return $this->buildTree($regions->where('level', 1), $regions);
        });
    }

    /**
     * 清除所有地区缓存
     */
    public function clearCache(): void
    {
        Cache::forget('kylin.regions.provinces');
        Cache::forget('kylin.regions.tree');
        // 子地区和搜索缓存通过前缀清除（如使用 Redis 缓存标签）
        // 此处仅清除主要缓存键
    }

    private function buildTree($parents, $all): array
    {
        $tree = [];
        foreach ($parents as $item) {
            $node = $item->toArray();
            $children = $all->where('parent_id', $item->id);
            if ($children->isNotEmpty()) {
                $node['children'] = $this->buildTree($children, $all);
            }
            $tree[] = $node;
        }
        return $tree;
    }
}
