<?php
namespace a_modules\common\repository;
use Illuminate\Database\Capsule\Manager as Capsule;
class Router {

    private static $routes = array();
    private static $route_names = array();
    public $domain_routes = array();

    public function __construct() {}
    private function __clone() {}

    public static function route($pattern, $callback, $route_name = null) {
        $pattern = '/^' . str_replace('/', '\/', $pattern) . '$/';
        self::$routes[$pattern] = $callback;
        if($route_name != null) {
            self::$route_names[$route_name] = $pattern;
        }
    }

    public static function execute($url) {
        foreach (self::$routes as $pattern => $callback) {
            if (preg_match($pattern, $url, $params)) {
                array_shift($params);
                return call_user_func_array($callback, array_values($params));
            }
        }
    }



    public static function array_pull(&$array, $key, $default = null) {
        $value = isset($array[$key]) ? $array[$key] : $default;

        if(isset($array[$key])) unset($array[$key]);

        return $value;
    }


    public function getRouteByName($route_name) {
        $domain_routes = $this->domain_routes->toArray();
        //dd($domain_routes);
        if(strpos($route_name, '.') !== false) {
            $arr = explode('.', $route_name);
            $num = count($arr);
            $parent = $domain_routes;
            while(count($arr) > 0) {
                $k = array_shift($arr);

                if(is_array($parent) && isset($parent[$k])) {
                    if(count($arr) == 0) return $parent[$k];
                    else $parent = $parent[$k];
                }
            }
        }
        elseif(isset($domain_routes[$route_name])) {
            return $domain_routes[$route_name];
        }

        return null;

    }

    public function routeTo($route_name, array $parameters) {
        $path = '#';
        $route = $this->getRouteByName($route_name);
        if($route && isset($route['url'])) {
            $path = $this->replaceNamedParameters($route['url'], $parameters);

            if(count($parameters) > 0) {
                $path .= '?' . http_build_query($parameters);
            }
        }

        $path = ltrim($path, '/');

        return $path;
    }

    public function getDomainRoutes($domain_id) {
        ob_start();
        $domain_routes = array();
        /*$m = Capsule::table('module as m')
            ->leftJoin('domain_modules as d', 'm.module_id', '=', 'd.module_id')
            ->where('d.domain_id', $domain_id)
            ->select(['m.*', 'd.routes'])
            ->get();*/

        $m = Capsule::table('module as m')
            ->where('m.required', 1)
            ->get();


        if($m) {
            foreach($m as $module) {
                $module_dir = dirname(__FILE__) . "/../../" . $module->url;
                if(is_dir($module_dir)) {
                    $module_routes_file = $module_dir . "/routes.php";
                    if(file_exists($module_routes_file)) {
                        $domain_routes [$module->url] = require($module_routes_file);
                    }
                }
            }
        }

        $log = ob_get_clean();





        $this->domain_routes = collect($domain_routes);

        return $this->domain_routes;
    }

    protected function replaceNamedParameters($path, &$parameters)
    {
        return preg_replace_callback('/\{(.*?)\??\}/', function ($m) use (&$parameters) {
            return isset($parameters[$m[1]]) ? $this->array_pull($parameters, $m[1]) : $m[0];
        }, $path);
    }

    public static function getRoutes() {
        dd(toArray(self::$routes));
    }

}