<?php

use Snaju\Inception\Http\Message\FlashMessage;
use Snaju\Inception\Http\Request\Controller;
use Snaju\Inception\Http\Response\ResponseHandler;
use Snaju\Inception\Settings\Config;

// TODO: add checks to make sure function doesn't exists using these reserved keywords. throw exception if they do or remove and override them. Check with Zack

if (!function_exists('app')) {
    function app()
    {

    }
}

if (!function_exists('render')) {
    /**
     * Renders a view, relative to the pages/views directory. The pages
     * directory is determined by the
     *
     * @param mixed ...$args
     * @return string
     * @global ResponseHandler
     * @see ResponseHandler::getInstance()->render()
     */
    function render(...$args): string
    {
        return ResponseHandler::getInstance()->render(...$args);
    }
}

if (!function_exists('array_dot')) {
    /**
     * Flatten a multi-dimensional associative array with dots.
     *
     * @param iterable $array
     * @param string $prepend
     *
     * @return array
     */
    function array_dot(iterable $array, string $prepend = ''): array
    {
        $results = [];

        foreach ($array as $key => $value) {
            if (is_array($value) && !empty($value)) {
                $results = array_merge($results, array_dot($value, $prepend . $key . '.'));
            } else {
                $results[$prepend . $key] = $value;
            }
        }

        return $results;
    }
}

if (!function_exists('response')) {
    /**
     * Returns the Response class which can then be used to return a specific response type.
     * @return ResponseHandler
     * @see ResponseHandler
     *
     */
    function response(): ResponseHandler
    {
        return ResponseHandler::getInstance();
    }
}

if (!function_exists('config')) {
    /**
     * Retrieves a value from a config file given its name/key. Null returned if key not found.
     *
     * @param $key
     * @return mixed|null
     * @see Config
     * @todo Add secondary argument to set and return the key if it doesn't exist
     */
    function config($key)
    {
        return Config::get($key);
    }
}

if (!function_exists('env')) {
    /**
     * Retrieves a value from the .env file given its name/key. Null returned if key not found.
     *
     * @todo Add secondary argument to set and return the key if it doesn't exist
     * @param $key
     * @return string|null
     */
    function env($key): ?string
    {
        if (isset($_ENV[$key])) {
            return $_ENV[$key];
        }
        return null;
    }
}

if (!function_exists('flash')) {
    /**
     * @return FlashMessage
     * @see FlashMessage::instance()
     */
    function flash(): FlashMessage
    {
        return FlashMessage::instance();
    }
}

if (!function_exists('controller')) {
    /**
     * @param array $middleware
     * @return Controller
     * @see Controller::getInstance()
     */
    function controller($middleware = []): Controller
    {
        return Controller::getInstance($middleware);
    }
}

if (!function_exists('view')) {
    /**
     * @return \Snaju\Inception\View\ViewController
     * @see \Snaju\Inception\View\ViewController
     */
    function view(): \Snaju\Inception\View\ViewController
    {
        return \Snaju\Inception\View\ViewController::getInstance();
    }
}

if (!function_exists('redirect')) {
    /**
     * Performs either or permanent (301) or temporary (302) redirect to a specified url.
     * @param $url
     * @param false $permanent
     */
    function redirect($url, $permanent = false)
    {
        if ($url == "") {
            $url = $_SERVER['HTTP_REFERER'];
        } else {
            $url = str_replace('Location: ', '', $url);
        }

        header('Location: ' . $url, true, $permanent ? 301 : 302);
        exit;
    }
}