<?php

namespace SHServ;

class Routes {

	use \SHServ\Routes\DevMode;
	use \SHServ\Routes\DevicesRESTAPI_v1;
	use \SHServ\Routes\ScriptsRESTAPI_v1;
	use \SHServ\Routes\ModesRESTAPI_v1;
	use \SHServ\Routes\AreasRESTAPI_v1;
	use \SHServ\Routes\FirmwareRESTAPI_v1;

	/**
	 * Instance of Router module
	 */
	protected \Fury\Modules\Router\Router $router;

	/**
	 * Controllers folder
	 */
	protected String $cf;

	/**
	 * Controllers namespace
	 */
	protected String $cn;

	public function __construct(\Fury\Modules\Router\Router $router) {
		$this -> router = $router;
		$this -> cf = FCONF["controllers_folder"];
		$this -> cn = "\\" . FCONF["app_name"] . "\\" . FCONF["controllers_folder"];
	}

	public function routes_init() {
		$this -> uri_routes();
		$this -> get_routes();
		$this -> post_routes();

		$this -> devices_restapi_uri_routes();
		$this -> devices_restapi_get_routes();
		$this -> devices_restapi_post_routes();

		$this -> scripts_restapi_uri_routes();
		$this -> scripts_restapi_get_routes();
		$this -> scripts_restapi_post_routes();

		$this -> modes_restapi_uri_routes();
		$this -> modes_restapi_get_routes();
		$this -> modes_restapi_post_routes();

		$this -> areas_restapi_uri_routes();
		$this -> areas_restapi_get_routes();
		$this -> areas_restapi_post_routes();

		$this -> firmware_restapi_uri_routes();
		$this -> firmware_restapi_get_routes();
		$this -> firmware_restapi_post_routes();

		// DEV MODE
		if(FCONF["devmode"]) {
			$this -> devmode_uri_routes();
			$this -> devmode_get_routes();
			$this -> devmode_post_routes();
		}
	}

	protected function uri_routes() {
		$this -> router -> uri("/", "{$this -> cn}\\AppController@index");

		$this -> router -> uri("/cron/regular-scripts", "{$this -> cn}\\CronController@run_regular_cron_scripts");
		$this -> router -> uri("/cron/status-update-scanning", "{$this -> cn}\\CronController@status_update_scanning");
		$this -> router -> uri("/cron/run-timers", "{$this -> cn}\\CronController@run_timers");
		$this -> router -> uri("/text-msgs", "{$this -> cn}\\AppController@text_msgs");

		// Auth
		$this -> router -> uri("/auth/login", "{$this -> cn}\\AuthController@login");
		$this -> router -> uri("/auth/callback", "{$this -> cn}\\AuthController@callback");
		$this -> router -> uri("/auth/mobile-bridge", "{$this -> cn}\\AuthController@mobileBridge");
		$this -> router -> uri("/auth/me", "{$this -> cn}\\AuthController@me");

		// Auth (API v1 aliases for unified client routing)
		$this -> router -> uri("/api/v1/auth/login", "{$this -> cn}\\AuthController@login");
		$this -> router -> uri("/api/v1/auth/callback", "{$this -> cn}\\AuthController@callback");
		$this -> router -> uri("/api/v1/auth/me", "{$this -> cn}\\AuthController@me");

		// Webhooks
		$this -> router -> uri("/webhooks/gnexus-auth", "{$this -> cn}\\WebhookController@gnexus_auth");
	}

	protected function get_routes() {

	}

	protected function post_routes() {
		// $this -> router -> post(
		// 	[ "email", "password", "password_again" ], 
		// 	"{$this -> cn}\\AuthController@signup", 
		// 	"/auth/signup"
		// );

		$this -> router -> post(
			[ "event_name", "device_id", "data"],
			"{$this -> cn}\\EventsController@new_event",
			"/events/new"
		);

		// Auth
		$this -> router -> post(
			[],
			"{$this -> cn}\\AuthController@logout",
			"/auth/logout"
		);
		$this -> router -> post(
			[],
			"{$this -> cn}\\AuthController@refresh",
			"/auth/refresh"
		);

		// Auth (API v1 aliases)
		$this -> router -> post(
			[],
			"{$this -> cn}\\AuthController@logout",
			"/api/v1/auth/logout"
		);
		$this -> router -> post(
			[],
			"{$this -> cn}\\AuthController@refresh",
			"/api/v1/auth/refresh"
		);

	}

	/**
	 * urlto, get url by action name [with arguments]
	 * @var String   $action_name - Action name, like a "HelloController@world_action"
	 * @var Array   $url_args - Assoc array with arguments (ONLY FOR REQUEST TYPE GET)
	 * 
	 * @return String  Url to action, ready for use
	 */
	public function urlto(String $action_name, Array $url_args = []) {
		$routes_map = $this -> router -> get_routes_map();
		$desired_action = "{$this -> cn}\\{$action_name}";
		foreach($routes_map["uri"] as $url => $action) {
			if($action == $desired_action) {
				foreach($url_args as $arg_name => $arg_val) {
					$url = str_replace("\${$arg_name}", $arg_val, $url);
				}

				return $url;
			}
		}

		foreach($routes_map["post"] as $url_pattern => $action){
			if($action == $desired_action) {
				list($url) = explode("?", $url_pattern); 
				return $url;
			}
		}

		foreach($routes_map["get"] as $url_pattern => $action){
			if($action == $desired_action) {
				list($url, $param_names) = explode("?", $url_pattern); 
				if(count($url_args)) {
					$param_names = explode("&", $param_names);
					$params = array_flip($param_names);
					foreach($params as $key => $val) {
						if(!isset($url_args[$key])) {
							continue;
						}

						$params[$key] = $url_args[$key];
					}
				}else{
					$params = [];
				}

				return $url . "?" . http_build_query($params);
			}
		}
	}
}