<?php

namespace Lib;

/**
 * @author:dc
 * @time 2023/2/13 15:07
 * Class App
 * @package Lib
 */
class App {

    /**
     * @var App
     */
    public static App $instance;

    /**
     * 当前日期
     * @var string
     */
    private string $date = '';

    /**
     * 当前时间
     * @var string
     */
    private string $dateTime = '';

    /**
     * @var Route
     */
    private Route $route;

    /**
     * 请求的参数
     * @var array
     */
    private array $request = [];


    /**
     * TODO:: 如果debug打开,错误时会返回错误消息到前端
     * @var bool
     */
    public bool $debug = false;

    /**
     * 输出到前端的数据
     * @var array
     */
    private array $data = [];

    public function __construct()
    {

        $this->date = date('Y-m-d');
        $this->dateTime = date('Y-m-d H:i:s');


        // 路由
        $this->route = new Route();

        // 请求参数 TODO::不允许其他类型的请求参数
        $this->request = my_filter($_POST,['trim']);

        // 调试
        if(defined('APP_DEBUG')){
            $this->debug = boolval(APP_DEBUG);
        }

    }


    /**
     * @return App
     * @author:dc
     * @time 2023/2/13 10:37
     */
    public static function instance(){
        if(empty(static::$instance)){
            static::$instance = new App();
        }
        return static::$instance;
    }


    /**
     * 开始运行
     * @author:dc
     * @time 2023/2/13 11:15
     */
    public static function run() {
        $app = self::instance();
        try {
//            if ($_SERVER['REQUEST_METHOD'] != 'POST'){
//                $app->e('need_post_request');
//            }

            // 取到路由 控制器
            $route = $app->route->get(explode('?',$_SERVER['REQUEST_URI'])[0]);
            if(!$route){
                $app->e('route_not_found');
            }
            list($class,$action) = $route;
            $controller = new $class();
            $data = $controller->{$action}();
            if($data){
                $app->data = $data;
            }
            // end 控制器


        }catch (\Throwable $exception){

            if(!($exception instanceof Err)){
                // 记录日志
                $filename = LOG_PATH.'/'.$app->nowDate().'.log';
                logs(
                    $exception->getMessage().PHP_EOL.$exception->getTraceAsString(),
                    $filename
                );

                // 非 Err 错误类型
                $app->data = [
                    'error_message' => $app->debug ? $exception->getMessage().PHP_EOL.$exception->getTraceAsString() : __('server_error'),
                    'status'    =>  $exception->getCode() ? $exception->getCode() : 500,
                ];
            }else{
                $app->data = [
                    'error_message' => $exception->getMessage(),
                    'status'    =>  $exception->getCode() ? $exception->getCode() : 500,
                ];
            }

        }

    }

    /**
     * 请求的参数
     * @param string $name
     * @param null $default
     * @param array|string|null $filter
     * @return array|false|float|int|mixed|null
     * @author:dc
     * @time 2023/2/17 9:37
     */
    public function request($name='*',$default=null,$filter = null){
        $data = [];
        if($name === '*'){
            $data = $this->request;
        } else if (is_string($name)){
            $data = $this->request[$name]??$default;
        }else if(is_array($name)){
            foreach ($this->request as $key=>$value){
                if(in_array($key,$name)){
                    $data[$key] = $value;
                }
            }
        }
        if($filter){
            $data = my_filter($data,$filter);
        }
        if($data !== []){
            return $data;
        }
        return null;
    }


    /**
     * @return string
     * @author:dc
     * @time 2023/2/13 11:17
     */
    public function nowDate():string {
        return $this->date;
    }

    /**
     * @return string
     * @author:dc
     * @time 2023/2/13 11:18
     */
    public function nowDateTime():string{
        return $this->dateTime;
    }

    /**
     * 错误
     * @param string $message
     * @param int $status
     * @throws Err
     * @author:dc
     * @time 2023/2/13 10:57
     */
    public function e($message,$status=400){
        if(is_array($message)){
            $this->data['error_message'] = __($message[0]);
            $this->data['error_message'] = sprintf($this->data['error_message'],...$message[1]);
        }else{
            $this->data['error_message'] = __($message);
        }
        $this->data['status'] = $status;
        throw new Err($this->data['error_message'],$status);
    }

    /**
     * 成功消息
     * @param $data
     * @param string $message
     * @throws Err
     * @author:dc
     * @time 2023/2/13 11:03
     */
    public function _json($data){
        $this->data = $data;
        throw new Err('',200);
    }


    /**
     * 结束
     * @author:dc
     * @time 2023/2/13 10:54
     */
    public static function end()
    {
        // 这里可以做其他事

        /**
         * 这里写
         */

        // end code

        header("Content-Type:application/json;Charset=UTF-8;");
//        header("Content-Type:text/html;Charset=UTF-8;");
//        header("Content-Type:text/event-stream;Charset=UTF-8;");

        if(self::instance()->data){
            echo json_encode(self::instance()->data,JSON_UNESCAPED_UNICODE);
        }

//        ob_flush();
//        ob_clean();
    }




}