<?php

namespace App\Services;

use App\Region;
use App\Traits\ServiceAppAop;

class RegionService
{
    use ServiceAppAop;
    protected $modelClass=Region::class;


    /**
     * 根据行政级别格式化地域名，提取关键字
     *
     * @param string $name
     * @param int $type
     *
     * @return string
     */
    public function formatName($name, $type)
    {
        switch ($type){
            case 1:
                $pool = ["省","自治区","市","特别行政"];
                break;
            case 2:
                $pool = ["市","区","自治州"/*,"州"*/,"盟"];
                break;
            case 3:
                $pool = ["市","区","自治县","县","自治旗","旗","特区","林区"];
                break;
            default:
                $pool = [];
        }
        return $this->extractKeyword($name,$pool);
    }

    /**
     * 根据省份获取ID
     *
     * @param string $province
     *
     * @return int
     */
    public function getProvince(string $province):int
    {
        $province = $this->formatName($province,1);
        $region = Region::withTrashed()->where("name","like",$province."%")
            ->where("type",1)->first();
        if (!$region)$region = Region::query()->create([
            "name"      => $province,
            "type"      => 1,
        ]);
        return $region->id;
    }

    /**
     * 根据城市获取ID
     *
     * @param string $city
     * @param string|int|null $parent
     *
     * @return int
     */
    public function getCity(string $city, $parent = null):int
    {
        $city = $this->formatName($city,2);
        $region = Region::withTrashed()->where("name","like",$city."%")
            ->where("type",2)->first();
        if (!$region){
            $region = [
                "name"      => $city,
                "type"      => 2,
            ];
            if ($parent){
                if (is_int($parent))$region["parent_id"] = $parent;
                else $region["parent_id"] = $this->getProvince($parent);
            }
            $region = Region::query()->create($region);
        }
        return $region->id;
    }

    /**
     * 根据区县获取ID
     *
     * @param string $district
     * @param string|int|null $parent
     *
     * @return int
     */
    public function getDistrict(string $district, $parent = null):int
    {
        $district = $this->formatName($district,3);
        $region = Region::withTrashed()->where("name","like",$district."%")
            ->where("type",3)->first();
        if (!$region){
            $region = [
                "name"      => $district,
                "type"      => 3,
            ];
            if ($parent){
                if (is_int($parent))$region["parent_id"] = $parent;
                else $region["parent_id"] = $this->getCity($parent);
            }
            $region = Region::query()->create($region);
        }
        return $region->id;
    }

    /**
     * 根据字典池提取关键字
     *
     * @param string $name
     * @param array $pool
     *
     * @return string
     */
    private function extractKeyword(string $name,array $pool)
    {
        foreach ($pool as $keyword){
            $result = mb_strpos($name,$keyword);
            if ($result!==false){
                return mb_substr($name,0,$result);
            }
        }
        return $name;
    }

    public function getSelection($type = null, $columns = ["id","name"])
    {
        $regions = Region::query()->select($columns);
        if ($type)$regions->where("type",$type);
        return $regions->get();
    }
}
