<?php

use \Illuminate\Support\Debug\Dumper;
use Illuminate\Support\Arr;

/**
 * __mtc_autoload_classes()
 *
 * Autoloading classes<br />
 * This is an mtc custom function so it won't screw with any 3rd party scripts
 * that also use an autoloading fuction
 *
 * @param mixed $classname
 * @return
 */
function __mtc_autoload_classes($classname) {
    $classname = strtolower($classname);

    $files[] = SITE_PATH . '/shop/classes/' . $classname . '.class.php';
    $files[] = SITE_PATH . '/shop/classes/class.' . $classname . '.php';

    $files[] = SITE_PATH . '/cms/classes/' . $classname . '.class.php';
    $files[] = SITE_PATH . '/cms/classes/class.' . $classname . '.php';

    $found = false;
    foreach ($files as $file) {
        if (file_exists($file)) {
            require_once ($file);
            $found = true;
        }
    }

    if (!$found) {
        // Thowing exceptions will cause other autoloaders to fail. :(
        // throw new Exception("Class file $classname not found.");
    }
}

/**
 * clean_page()
 *
 * Used to clean data as it is displayed on the page.  This can be used for
 * most data.  If the HTML flag is set true double encoding will have no effect.
 *
 * @param mixed $text
 * @param bool $double_encoding When double_encode is set to false PHP will not
 * encode existing html entities.
 * @param bool $allow_html Run the string through HTML purifier so it will more
 * intelligently filter HTML strings.
 *
 * @return string clean text
 */
function clean_page($text, $double_encoding = true, $allow_html = false) {
    if ($allow_html === true) {
        $config = HTMLPurifier_Config::createDefault();
        $purifier = new HTMLPurifier($config);
        $text = $purifier->purify($text);
        return $text;
    } else {
        return htmlentities($text, ENT_QUOTES, 'utf-8', $double_encoding);
    }
}

/**
 * showerrors()
 *
 * Outputs error message
 *
 * @param mixed $errors
 * @return
 */
function showerrors($errors) {
    if (is_array($errors) && !empty($errors)) {
        echo '<div class="el error msg">
                <ul class="error">';
        foreach ($errors as $fieldname => $error) {
            echo '<li><a href="#' . $fieldname . '" class="jump">' . $error . "</a></li>";
        }
        echo '</ul>
                <i class="fa fa-exclamation-triangle"></i>
            </div>';
    } else {
        return false;
    }
}

/**
 * Simple function to echo out testing arrays
 */
function pre($array) {
    echo '<div style="position:absolute;top:15px;right:15px;max-width:400px;background:rgba(255,255,255,0.7);padding:15px;color:#333;"><pre>';
    print_r($array);
    echo '</pre></div>';
}

/**
 * Simpler function to echo out testing arrays
 */
function d($array, $format = false) {
    if ($format === true) {
        array_map(function ($x) {
            (new Dumper)->dump($x);
        }, func_get_args());
    } else {
        echo '<pre>';
        print_r($array);
        echo '</pre>';
    }
}

/**
 * clean_db()
 *
 * Used to escape data for inserting into a database<br />
 * However, this function should not be used going forward with PDO, use prepared
 * statements instead.
 * Note that for mysql_real_escape_string() to work a successful call to
 * mysql_connect() has to be made
 *
 * @param  mixed  $text
 * @return string clean text
 */
function clean_db($text) {
    $db = new MtcPdo();
    $text = $db::getPDOInstance()->quote($text);
    return substr($text, 1, -1);
}

/**
 * format_page()
 *
 * Used to format plaintext data as it is displayed on the page
 *
 * @param  mixed  $text
 * @return string formatted text
 */
function format_page($text) {
    trigger_error('format_page function is deprecated, please remove this function', E_DEPRECATED);
    return str_replace("\n", "<br>", htmlentities($text));
}

/**
 * upload_image()
 *
 * Used to validate an image upload, upload the image, resize, crop, etc.
 *
 * @param  mixed $file
 * @param  mixed $folders
 * @return mixed filename on success. false on error.
 */
function upload_image($file, $folders, $item_id = 0) {
    $uploader = \Mtc\Core\Images\ImageUploader::newInstance($folders);
    return $uploader->uploadImage($uploader->file($file), $item_id);
}

/**
 * showmsg()
 *
 * Generates output for error/success/warning messages
 *
 * @param  string $message
 * @param  string $type
 * @param  string $path
 * @return string html output
 */
function showmsg($message = "", $type = "", $path = "") {
    return template('admin/messages.twig', [
        'messages' => [
            [
                'type' => $type,
                'content' => $message
            ]
        ]
    ]);

}

/**
 * date_convert_dmy_to_db()
 *
 * Converts date from dd/mm/yyyy to yyyy-mm-dd
 *
 * @param  mixed  $date
 * @param  string $time
 * @return string|bool Date in yyyy-mm-dd format or false on failure
 */
function date_convert_dmy_to_db($date, $time = "00:00:00") {
    if (!validate_date($date)) {
        return false;
    }

    $array = explode("/", $date);
    $a_time = explode(":", $time);

    $array[2] = substr($array[2], 0, 4);

    $d = $array[2] . "-" . $array[1] . "-" . $array[0];
    $d .= " " . $a_time[0] . ":" . $a_time[1] . ":" . $a_time[2];

    return $d;
}

/**
 * date_convert_db_to_dmy()
 *
 * Converts date from yyyy-mm-dd to dd/mm/yyyy
 *
 * @param  mixed  $date
 * @return string date in dd/mm/yyyy format
 */
function date_convert_db_to_dmy($date) {
    $holder = explode(" ", $date);
    $array = explode("-", $holder[0]);

    return $array[2] . "/" . $array[1] . "/" . $array[0];
}

/**
 * validate_date()
 *
 * Validates that a date is in the correct format of dd/mm/yyyy
 *
 * @param  mixed $date
 * @return bool  true/false
 */
function validate_date($date) {
    // exploding the array
    $arr = explode("/", $date);

    if (count($arr) == 3) {
        // first element of the array is date
        $dd = $arr[0];
        // second element is month
        $mm = $arr[1];
        // third element is year
        $yy = $arr[2];

        if ($dd == '' || !is_numeric($dd)) {
            $dd = 0;
        }
        if ($mm == '' || !is_numeric($mm)) {
            $mm = 0;
        }
        if ($yy == '' || !is_numeric($yy)) {
            $yy = 0;
        }

        if (checkdate($mm, $dd, $yy)) {
            return true;
        }
    }

    return false;
}

/**
 * clean_value()
 *
 * Used to clean output for urls
 *
 * @param  mixed  $input
 * @return string cleaned value
 */
function clean_value($input) {
    $counter = 0;
    $array = array();

    while ($counter < strlen($input)) {
        //echo substr($name, $counter, 1);
        $array[$counter] = substr($input, $counter, 1);
        $counter++;
    }

    $newarray = preg_grep("([a-zA-Z0-9_-])", $array);

    $output = '';
    foreach ($newarray as $a) {
        $output .= $a;
    }

    return $output;
}

/**
 * clean_value_dot()
 *
 * Used to clean output for file names
 *
 * @param  mixed  $input
 * @return string cleaned value
 */
function clean_value_dot($input) {
    $counter = 0;

    while ($counter < strlen($input)) {
        //echo substr($name, $counter, 1);
        $array[$counter] = substr($input, $counter, 1);
        $counter++;
    }

    $newarray = preg_grep("([.a-zA-Z0-9_])", $array);
    $output = "";
    if (!empty($newarray)) {
        foreach ($newarray as $a) {
            $output .= $a;
        }
    }

    return $output;
}

/**
 * clean_value_space()
 *
 * Used to strip all non alphanumeric characters out of string
 *
 * @param  mixed  $input
 * @return string cleaned value
 */
function clean_value_space($input) {
    $counter = 0;

    $array = array();
    while ($counter < strlen($input)) {
        //echo substr($name, $counter, 1);
        $array[$counter] = substr($input, $counter, 1);
        $counter++;
    }

    $newarray = preg_grep("([a-zA-Z0-9_\s])", $array);
    $output = "";
    foreach ($newarray as $a) {
        $output .= $a;
    }

    return $output;
}

/**
 * clean_image_value()
 *
 * Alias for clean_value_dot
 *
 * @param mixed $input
 * @return
 */
function clean_image_value($input) {
    return clean_value_dot($input);
}

/**
 * get_image_size()
 *
 * Retrieves image dimensions
 *
 * @param  mixed $folder
 * @param  mixed $pic
 * @return int[] image sizes
 */
function get_image_size($folder, $pic) {
    $dimensions = getimagesize(base_path("{$folder}/{$pic}"));
    return [
        'width' => $dimensions[0] ?? 0,
        'height' => $dimensions[1] ?? 0
    ];
}

/**
 * date_dmy_to_db()
 *
 * Alias for date_convert_dmy_to_db()
 *
 * @param  mixed  $date
 * @return string date in yyyy-mm-dd format
 */
function date_dmy_to_db($date) {
    return date_convert_dmy_to_db($date);
}

/**
 * Takes date and returns converted to different format (string)
 * Author: Pawel G
 *(PHP 5 >= 5.3.0)
 *
 * @param $date
 * @param string $format
 * @param null $current_format
 * @param null $default
 * @return bool|null|string
 */
function convert_date($date, $format = 'd-m-Y H:i:s', $current_format = null, $default = null) {
    if ($date != '') {
        if ($current_format) {
            if ($formated_date = date_create_from_format($current_format, $date)) {
                return $formated_date->format($format);
            }
        } else {
            return date($format, strtotime($date));
        }
    }
    return $default;
}

/**
 * Returns id value of a variable. If the variable is an object, it will return it's id property, if it's
 * an array, returns 'id' key, otherwise, assuming the id itself has been passed, will return the int value of the
 * variable.
 *
 * @author Aleksey Lavrinenko <aleksey.lavrinenko@mtcmedia.co.uk>
 *
 * @param mixed $object
 * @return int
 */
function id($object) {
    if (is_object($object)) {
        return (int)$object->id;
    } elseif (is_array($object)) {
        return (int)$object['id'];
    } else {
        // assuming the object is ID itself
        return (int)$object;
    }
}

/**
 * Check if we're in an admin page or not
 *
 * @author Kathryn Reeve <kathryn.reeve@mtcmedia.co.uik>
 *
 * @param null|callable $callback
 *
 * @return bool
 */
function isAdminSection($callback = null)
{
    try {
        $request_uri = request()->getRequestUri();
    } catch(\Exception $exception){
        $request_uri = $_SERVER['REQUEST_URI'];
    }

    $admin_urls = [
        'generic' => strpos($_SERVER['PHP_SELF'], '/admin/') !== false,
        'core'    => strpos($_SERVER['PHP_SELF'], '/core/admin/') === 0,
        'shop'    => strpos($_SERVER['PHP_SELF'], '/shop/admin/') === 0,
        'cms'     => strpos($_SERVER['PHP_SELF'], '/cms/admin/') === 0,
        'plugins' => preg_match('#/plugins/[a-zA-Z]+/admin/?#', $_SERVER['PHP_SELF']),

        // add here true value checks to Include as admin page (wp-admin?)
        // add here false value checks to Exclude pages as admin
    ];

    // allow addition or modification of the checks..
    if ($callback !== null && is_callable($callback)) {
        $admin_urls = call_user_func($callback, $admin_urls);
    }

    // filter the list, reducing list where has false
    $admin_urls = array_filter($admin_urls);

    // if all entries are false, the filtered array will have no entries
    return !empty($admin_urls);
}

/**
 * Used to send an emails
 * Example #1: email(['dev@mtc.com' => 'John Johns'], 'My message', 'Hello', ['dev2@mtc.com' => 'Ree Stu'])
 * Example #1: email(dev@mtc.com, 'My message', 'Hello', dev2@mtc.com)
 *
 * @param string $recipient Recipient email
 * @param string $subject Message topic
 * @param string $message Message
 * @param boolean $dev_copy
 * @return bool
 */
function email($recipient, $subject, $message, $dev_copy = false)
{

    $message = (\Illuminate\Support\Facades\App::make(\Mtcmedia\Mailer\SwiftMessage::class))
        ->setTo($recipient)
        ->setSubject($subject)
        ->setFrom([FROM_EMAIL => SITE_NAME])
        ->setBody($message)
        ->setReturnPath(FROM_EMAIL);


    if ($dev_copy || (defined('MAIL_DEV_COPY') && MAIL_DEV_COPY) ) {
        $message->setBcc([
            DEV_EMAIL => 'MTC Developer'
        ]);
    }

    return $message->getSent() > 0;
}

// Laravel helpers moved into core

// check for existence to ensure this is not conflicting with laravel framework in dev dependencies
if (!function_exists('request')) {
    /**
     * Get an instance of the current request or an input item from the request.
     *
     * @param  array|string  $key
     * @param  mixed   $default
     * @return \Illuminate\Http\Request|string|array
     */
    function request($key = null, $default = null)
    {
        $request = \Illuminate\Container\Container::getInstance()->make('request');
        if (is_null($key)) {
            return $request;
        }

        if (is_array($key)) {
            return $request->only($key);
        }

        return data_get($request->all(), $key, $default);
    }
}

// check for existence to ensure this is not conflicting with laravel framework in dev dependencies
if (!function_exists('data_get')) {
    /**
     * Get an item from an array or object using "dot" notation.
     *
     * @param  mixed   $target
     * @param  string|array  $key
     * @param  mixed   $default
     * @return mixed
     */
    function data_get($target, $key, $default = null)
    {
        if (is_null($key)) {
            return $target;
        }

        $key = is_array($key) ? $key : explode('.', $key);

        while (! is_null($segment = array_shift($key))) {
            if ($segment === '*') {
                if ($target instanceof \Illuminate\Support\Collection) {
                    $target = $target->all();
                } elseif (! is_array($target)) {
                    return value($default);
                }

                $result = Arr::pluck($target, $key);

                return in_array('*', $key) ? Arr::collapse($result) : $result;
            }

            if (Arr::accessible($target) && Arr::exists($target, $segment)) {
                $target = $target[$segment];
            } elseif (is_object($target) && isset($target->{$segment})) {
                $target = $target->{$segment};
            } else {
                return value($default);
            }
        }

        return $target;
    }
}

if (! function_exists('template')) {
    /**
     * Get the twig template contents for the given view.
     *
     * @param  string  $view
     * @param  array   $data
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
     */
    function template($template = null, $data = [])
    {
        return app('twig')->render($template, $data);
    }
}

require_once __DIR__ . '/tim_thumb.php';

if (file_exists(dirname(__DIR__) . '/cms/src/helpers.php')) {
    require_once  dirname(__DIR__) . '/cms/src/helpers.php';
}

if (file_exists(dirname(__DIR__) . '/shop/src/helpers.php')) {
    require_once  dirname(__DIR__) . '/shop/src/helpers.php';
}