<?php

declare (strict_types = 1);
namespace library\utils;

use think\facade\Config;
use think\facade\Db;
use think\facade\Lang;
use think\Response;

class Region
{

    public $data = [];

    public function __construct()
    {
        $this->data = $this->getData();
    }



    /**
     * 通过子集获取,全部父级
     * @param int $id
     * @param string $file 全部父级字段
     * @param string $Division 分割线
     */
    public function getParentS($id = 0,$file = '*',$Division = ''){
        $tAr = [];
        $rAr = [];
        while (true){
            $data = $this->getParent($id);
            if(empty($data)){
                break;
            }
            if(!empty($data)){
                $tAr[] = $data;
                $id = $data['ParentId'];
            }
        }
        $tAr = array_reverse($tAr);
        foreach ($tAr as $v){
            $rAr[] = ($file == '*' ? $v : $v[$file]);
        }
        if($file != '*' && $Division != '')
            return join($Division,$rAr);
        else
            return $rAr;
    }

    /**
     * 获取子集所以Id
     * @param $id
     */
    public function getChildIds($id){
        $rAr = $this->getChilds($id);

        return array_column($rAr, 'ID');

    }
    /**
     * 获取子集数据
     * @param int $id
     */
    public function getChild($id = 0){
        $rAr = [];
        foreach ($this->data as $v){
            if($v['ParentId'] == $id) $rAr[] = $v;
        }
        return $rAr;
    }

    /**
     * 数据
     * @param int $id
     * @return array
     */
    public function getChilds($id = 0){
        $data = $this->getChild($id);
        foreach ($data as $v){
            $d = $this->getChilds($v['ID']);
            $data = array_merge($data,$d);
        }
        return $data;
    }
    /**
     * 上一层数
     * @param int $parentId
     * @param string $file 字段
     */
    public function getParent($parentId = 0,$file ='*'){
        foreach ($this->data as $v){
            if($v['ID'] == $parentId) return ($file == '*' ? $v : $v[$file]);
        }
        return null;
    }
    /**
     * 获取层级数据
     * @param int $lIndex
     */
    public function getLevel($lIndex = 0){
        $rAr = [];
        foreach ($this->data as $v){
            if($v['LevelType'] == $lIndex) $rAr[] = $v;
        }
        return $rAr;
    }

    /**
     * 模糊搜索ID
     * @param $name
     * @param string $file
     * @return mixed|null
     */
    public function getLike($name,$file ='*') {
        if(empty($name)) return null;
        foreach ($this->data as $v) {
            if(strpos($v['Name'],$name) !== false) {
                return ($file == '*' ? $v : $v[$file]);
            }
        }
        return null;
    }
    /**
     * 查询地址信息
     * @param type $id
     * @param type $file
     * @return type
     */
    public function getField($id,$file ='*') {
        foreach ($this->data as $v) {
            if($v['ID'] == $id) {
                return ($file == '*' ? $v : $v[$file]);
            }
        }
        return null;
    }


    public function getRegion($str) {
        $province = [];
        $city = [];
        $area = [];
        foreach ($this->data as $v) {
            $item = $v;
            $strLen = strpos($str,$item['ProvinceShortName']);
            if($item['LevelType'] == 1 && $strLen !== false &&
                (empty($province) || $province['len'] > $strLen )
            ) {
                $v['len'] = $strLen;
                $province = $v;
            }
        }

        //城市列表
        if(!empty($province)) {
            $data = $this->getChild($province['ID']);
            if(count($data) == 1) {
                $data[0]['len'] = 0;
                $city = $data[0];
            } else {
                foreach ($data as $v) {
                    $item = $v;
                    $strLen = strpos($str,$item['CityShortName']);
                    if($strLen !== false && (empty($city) || $city['len'] > $strLen ) && $province['ProvinceShortName']
                        != $item['CityShortName']  && $v['LevelType'] == 2 ) {
                        $v['len'] = $strLen;
                        $city = $v;
                    }
                }

                if(empty($city)) {
                    foreach ($data as $v) {
                        $item = $v;
                        $strLen = strpos($str,$item['CityShortName']);
                        if($strLen !== false && (empty($city) || $city['len'] > $strLen )  && $v['LevelType'] == 2 ) {
                            $v['len'] = $strLen;
                            $city = $v;
                        }
                    }
                }


            }
        }
        //地区数据
        if(!empty($city)) {
            $data = $this->getChild($city['ID']);
            foreach ($data as $v) {
                $item = $v;
                $strLen = strpos($str,$item['DistrictShortName']);
                if($strLen !== false) {
                    $v['len'] = $strLen;
                    $area = $v;
                }
            }
        }
        //地区
        foreach ($this->data as $v) {
            $item = $v;
            $strLen = strpos($str,$item['ProvinceShortName']);
            if($item['LevelType'] == 3 && $strLen !== false && empty($city) &&
                (empty($area) || $area['len'] < $strLen )
            ) {
                $v['len'] = $strLen;
                $area = $v;
            }
        }

        ////////////
        //省份
        if(!empty($province)) {
            $len = strpos($str,$province['Name']);
            $name = $province['ProvinceShortName'];
            if($len !== false && $len == $province['len']) {
                $name = $province['Name'];
            }
            $str = $this->strReplaceLimit($name,'',$str,1);
        }
        //城市列表
        if(!empty($city)) {
            $len = strpos($str,$city['Name']);
            $name = $city['CityShortName'];
            if($len !== false) {
                $name = $city['Name'];
            }
            $str = $this->strReplaceLimit($name,'',$str,1);
        }
        //城市列表
        if(!empty($area)) {
            $len = strpos($str,$area['Name']);
            $name = $area['DistrictShortName'];
            if($len !== false) {
                $name = $area['Name'];
            }
            $str = $this->strReplaceLimit($name,'',$str,1);
        }

        //var_dump(['address'=>trim($str),'province'=> empty($province) ? '' : $province['Name'],'city'=> empty($city) ? '' : $city['Name'],'area'=>empty($area) ? '' : $area['Name']]);
        return ['address'=>trim($str),'province'=> empty($province) ? '' : $province['Name'],'city'=> empty($city) ? '' : $city['Name'],'area'=>empty($area) ? '' : $area['Name']];
    }


    /**
     * 获取基础数据【缓存数据】
     */
    private function getData(){
        $data = cache('region');
        if(empty($data)){
            $data = Db::name("region")->field("ID,ParentId,LevelType,Name,Pinyin,ProvinceShortName,DistrictShortName,CityShortName")->select()->toArray();
            cache('region',$data);
        }
        return $data;
    }

    /**
     * @param $method
     * @param $args
     * @return mixed
     */
    public static function __callStatic($method, $args)
    {
        $model = new static();

        return call_user_func_array([$model, $method], $args);
    }


    /**
    $search:要替换的字符串或者数组
    $replace:要替换的值
    $subject:要替换的文本
    $limit:替换的此数字
     * @return string|string[]|null
     */
    function strReplaceLimit($search, $replace, $subject, $limit=-1) {
        if (is_array($search)) {
            foreach ($search as $k=>$v) {
                $search[$k] = '`' . preg_quote($search[$k],'`') . '`';
            }
        }
        else {
            $search = '`' . preg_quote($search,'`') . '`';
        }
        return preg_replace($search, $replace, $subject, $limit);
    }

}