<?php

namespace Server\language;

use App\Services\CacheService;
use App\Services\CloudService;
use App\Services\FileService;
use App\Services\MicroService;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

class LanguageService extends MicroService
{

    public $CompileDrive = "blade";
    public $appLocale;
    public $systemLocales = array("zh"=>"简体中文", "en"=>"English");

    function __construct(){
        parent::__construct('language');
        $this->appLocale = env('APP_LANGUAGE', 'zh');
        global $_W;
        if (!isset($_W['setting']['languages'])){
            $this->langUsable();
        }
    }

    /**
     * 切换系统默认语言
     * @param string $locale 语种Id
     * @return bool 切换结果
    */
    public function langSwitch($locale){
        if (empty($locale)) return false;
        $currentLocale = env('APP_LANGUAGE');
        $search = "APP_LANGUAGE=$currentLocale";
        $replace = "APP_LANGUAGE=$locale";
        if (empty($currentLocale)){
            if (!is_null($currentLocale)){
                $search = "APP_LANGUAGE=";
            }else{
                $search = "APP_RELEASE=" . env("APP_RELEASE");
                $replace = <<<EOF
$search
$replace
EOF;

            }
        }
        return CloudService::CloudEnv($search, $replace);
    }

    /**
     * 扫描语种支持的语言包列表
     * @param string $locale 语种Id
     * @param bool|null $whitData 是否返回语言包内容
     * @return array 语言包列表
    */
    public function langScan($locale, $whitData=false){
        if (empty($locale)) $locale = $this->appLocale;
        $packages = [];
        $frameFile = resource_path("lang/$locale.json");
        if (file_exists($frameFile)){
            $data = json_decode(file_get_contents($frameFile), true);
            $packages['framework'] = array(
                'name'=>$data['languageName'],
                'code'=>$locale,
                'id'=>'framework',
                'data'=>$whitData?$data:[]
            );
        }
        $files = FileService::file_tree(resource_path("lang/$locale"), array("*.php"));
        if (!empty($files)){
            foreach ($files as $value){
                $lang = require($value);
                if (!isset($lang['packageName']) || $lang['packageID']=='framework') continue;
                $langInfo = array(
                    'name'=>$lang['packageName'],
                    'code'=>$locale,
                    'id'=>$lang['packageID'],
                    'data'=>$whitData?$lang:[]
                );
                $packages[$lang['packageID']] = $langInfo;
            }
        }
        return $packages;
    }

    /**
     * 保存语言包
     * @param string $id 语种Id
     * @param string $name 语言包名称
     * @param string $locale 语言包Id
     * @param array|null $data 语言包内容
     * @return array|bool 更新结果
    */
    public function langSave($id, $name, $locale, $data=[]){
        if (empty($id) || !preg_match('/^([a-zA-Z])(\w+?)$/', $id)) return error(-1, "lang.invalidPackageId");
        if ($id=='framework'){
            //if ($this->systemLocales[$locale]) return $this->error(__('lang.modifyDefaultLanguage'));
            $langFile = resource_path("lang/$locale.json");
            $data['languageName'] = $name;
            $data['languageID'] = $locale;
            if (file_exists($langFile)){
                @unlink($langFile);
            }
            if (!file_put_contents($langFile, json_encode($data, 448))){
                return $this->error("saveFailed");
            }
            CacheService::flush();
        }else{
            $langFile = resource_path("lang/$locale/$id.php");
            if (!is_dir(resource_path("lang/$locale/"))){
                FileService::mkdirs(resource_path("lang/$locale/"));
            }
            $string = <<<EOF
<?php

return [
    'packageName'=>'$name',
    'packageID'=>'$id'
EOF;
            foreach ($data as $key=>$value){
                $string .= ",
    '$key'=>'$value'";
            }
            $string .= <<<EOF

];

EOF;
            if (file_exists($langFile)){
                @unlink($langFile);
            }
            if (!file_put_contents($langFile, $string)){
                return $this->error("saveFailed");
            }
        }
        return true;
    }

    /**
     * 更新语言包
     * @param string $lang 语言包标识符（包含语种）
     * @param array|null $data 语言包内容
     * @return array|bool 更新结果
     */
    public function langAppend($lang, $data=[]){
        if (empty($data)) return true;
        if (empty($lang) || !is_array($data)) return false;
        $id = 'framework';
        if (strexists($lang, '.')){
            list($id, $locale) = explode(".", $lang);
        }else{
            $locale = $lang;
        }
        $languages = $this->langGet($locale, $id, true);
        $langData = array_merge($languages, $data);
        $languageName = $id=='framework' ? $languages['languageName'] : $languages['packageName'];
        return $this->langSave($id, $languageName, $locale, $langData);
    }

    /**
     * 获取语言包
     * @param string $locale 语言包Id
     * @param string $id 语种Id
     * @param bool $full 是否完整返回，否则去掉包名和Id
     * @return array 语言包内容
    */
    public function langGet($locale, $id, $full=false){
        $langFile = resource_path("lang/$locale/$id.php");
        if ($id=='framework'){
            $langFile = resource_path("lang/$locale.json");
            if (!file_exists($langFile)) return [];
            $data = json_decode(file_get_contents($langFile), true);
            if(!$full) unset($data['languageName'], $data['languageID']);
            return $data;
        }
        if (!file_exists($langFile)) return [];
        $data = require($langFile);
        if(!$full) unset($data['packageName'], $data['packageID']);
        return $data;
    }

    /**
     * 获取系统语种列表
     * @param bool $status 可用状态
     * @return array 语种列表
    */
    public function getLanguages($status=false){
        $query = DB::table('languages');
        if ($status!==false){
            return $query->where('status', intval($status))->get()->keyBy('code')->toArray();
        }
        return $query->get()->keyBy('code')->toArray();
    }

    /**
     * 获取可用的语种列表
     * @param bool $cache 是否从缓存读取
     * @return array 可用的语种列表
    */
    public function langUsable($cache=true){
        global $_W;
        $cacheKey = "{$_W['config']['identity']}:Languages";
        $languages = Cache::get($cacheKey);
        if (!empty($languages) && $cache){
            return $languages;
        }
        $languages = DB::table('languages')->where('status', 1)->get()->keyBy('code')->toArray();
        cache_write($cacheKey, $languages);
        $this->SettingSave("languages", $languages);
        return $languages;
    }

}
