<?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
     * @param int $parentId 上一层ID
     * @return mixed|null
     */
    public function getLike($name, $file = '*', $parentId = -1)
    {
        if (empty($name)) return null;
        if ($parentId == -1)
            $data = $this->data;
        else
            $data = $this->getChilds($parentId);

        foreach ($data as $v) {
            if (strpos($v['Name'], $name) !== false) {
                return ($file == '*' ? $v : $v[$file]);
            }
        }
        return null;
    }

    /**
     * 获取地址到ID
     * @param $region
     */
    public function getLikeS($name)
    {
        if (empty($name)) return 0;
        $nameAr   = explode('-', $name);
        $province = 0;
        $city     = 0;
        $area     = 0;
        if (!empty($nameAr)) {
            $province = $this->getLike($nameAr[0], 'ID');
        }

        if (count($nameAr) > 1) {
            $city = $this->getLike($nameAr[1], 'ID', $province);
        }

        if (count($nameAr) > 2) {
            $area = $this->getLike($nameAr[1], 'ID', $province);
        }

        if (!empty($area)) return $area;
        if (!empty($city)) return $city;
        if (!empty($province)) return $province;
        return 0;
    }


    /**
     * 查询地址信息
     * @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;
                $v['len2'] = strlen($item['ProvinceShortName']);
                $province  = $v;
            }
        }
        //城市列表
        if (!empty($province)) {
            $data = $this->getChild($province['ID']);
            if (count($data) == 1) {
                $city        = $data[0];
                $city['len'] = 0;
            } else {
                //匹配城市 | 地址前面优先匹配
                $pLen = -1;
                foreach ($data as $v) {
                    $str2   = substr($str . '-', $province['len'] + $province['len2'], -1);
                    $strLen = strpos($str2, empty($v['CityShortName']) ? '' : $v['CityShortName']);
                    if ($strLen !== false && $pLen == -1) {
                        $pLen = $strLen;
                    }
                    if ($strLen !== false && $strLen <= $pLen && $v['LevelType'] == 2) {
                        $v['len'] = $strLen + $province['len'];
                        $city     = $v;
                        $pLen     = $strLen;
                    }
                }
                //可能城市和省会一样检测
                if (empty($city)) {
                    foreach ($data as $v) {
                        $strLen = strpos($str, empty($v['CityShortName']) ? '' : $v['CityShortName']);
                        if ($strLen !== false && $v['LevelType'] == 2) {
                            $v['len'] = $strLen;
                            $city     = $v;
                            break;
                        }
                    }
                }
            }
        }
        //地区数据
        if (!empty($city)) {
            $data = $this->getChild($city['ID']);
            foreach ($data as $v) {
                $item   = $v;
                $strLen = strpos($str, empty($item['DistrictShortName']) ? '' : $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);
    }

}