<?php

use Illuminate\Database\Eloquent\ModelNotFoundException;
use Mtc\Core\Currency;
use Mtc\Shop\Brand;
use Mtc\Shop\Category;
use Mtc\Shop\Item;

/**
 * Functions
 *
 * @package mtc ecommerce
 * @author mtc.
 * @copyright 2013 mtc. http://www.mtcmedia.co.uk/
 * @version 2013
 * @access public
 */


    /**
     * categoryChild()
     *
     * Generate 3D array of categories / sub categories, etc.
     *
     * @param  mixed $id
     * @return array categories array
     */
    function categoryChild($id)
    {
        return Category::childOf($id)
            ->get()
            ->toArray();
    }

    /**
     * Deprecated - moved to eloquent model
     * Use Mtc\Shop\Category::getFlatTree($id, true) instead
     * Generate 2D array of all child categories
     *
     * @param  mixed $id
     * @return array categories array
     * @deprecated
     */

    function categoryAllChildren($id)
    {
        return Category::getFlatTree($id, true);
    }

    /**
     * Deprecated - moved to eloquent model
     * Use Mtc\Shop\Category::allParents($id) instead
     * Get all the categories parents
     *
     * @param mixed $id
     * @return array
     * @deprecated
     */
      function categoryAllParents($id)
      {
          return Category::allParents($id);
      }


    /**
     * has_ordered()
     *
     * Checks to see if a member has ordered from the website before
     *
     * @param  string  $email
     * @param  integer $member
     * @return bool    true/false
     */
    function has_ordered($email = '', $member = 0, $basket_id = false)
    {
        // if no email has been entered yet, don't check for orders with an empty email
        if (empty($email)) {
            if (!empty($member)) {
                try {
                    $email = \Mtc\Modules\Members\Models\Member::find($member)->email;
                } catch (Exception $e) {
                    return false;
                }
            } else {
                // no email and no member means empty basket details and we can't check at this point if the customer has placed orders before or not,
                // so we assume not for the time being
                return false;
            }
        }
        return \Mtc\Shop\Order::query()
            ->join('order_info', 'order_info.order_id', '=', 'order.id')
            ->where('order_info.email', '=', $email)
            ->where('order.paid', '=', 1)
            ->when(!empty($basket_id), function ($query) use ($basket_id): void {
                $query->where('order.basket_id', '!=', $basket_id);
            })
            ->when(!empty($member), function ($query) use ($member): void {
                $query->where('order.member', '=', $member);
            })
            ->exists();
    }

    /**
     * get_item_meta()
     *
     * Meta data used for open graph data
     *
     * @param  mixed $id
     * @return array meta data
     */
    function get_item_meta($id)
    {
        try {
            $item = Item::select('id', 'name')->find($id);
            $first_image  = $item->images()
                ->isDefault()
                ->first()
            ;

            $item->image  = $first_image->name ?? null;

            return $item->toArray();
        } catch (ModelNotFoundException $e) {
            return [];
        }
    }

    /**
     * browse_url()
     *
     * Generate browse page url
     *
     * @param  integer $catid
     * @param  integer $brandid
     * @param  string  $startnumber
     * @param  string  $order
     * @param  string  $newsex
     * @param  mixed   $perpage
     * @return string  browse url
     */
    function browse_url($catid = 0, $brandid = 0, $startnumber = '', $order = 'new-additions', $newsex = '', $perpage = MAX_PER_PAGE, $sex = '') {
        return ProductFilter::browseUrl([
                'catid' => $catid,
                'brandid' => $brandid,
                'page' => ($startnumber > 0)? floor($startnumber / $perpage) : 0,
                'order' => $order,
                'sex' => $sex,
        ]);
    }

    /**
     * Deprecated - moved to eloquent model
     * Use Mtc\Shop\Brand::find($id) instead
     * Get brand name from id
     *
     * @param  mixed  $brand_id
     * @return string brand name
     * @deprecated
     */
    function brand_name($brand_id)
    {
        try {
            return Brand::find($brand_id)->name;
        } catch (ModelNotFoundException $e) {
            return '';
        }
    }

    /**
     * Deprecated - moved to eloquent model
     * Use Mtc\Shop\Brand::find($id) instead
     * Get brand data from id
     *
     * @param  mixed $brand_id
     * @return array brand data
     * @deprecated
     */
    function brand_data($brand_id)
    {
        $brand = \App\MultisiteHelper::getBrandToDisplay($brand_id);

        if ($brand) {
            $brand->url = browse_url(0, $brand->id);
        }

        return $brand ? $brand->toArray() : false;
    }

    /**
     * Deprecated - moved to eloquent model
     * Use Mtc\Shop\Category::find($id) instead
     * Get category data from id
     *
     * @param  mixed $cat_id
     * @return array category data
     * @deprecated
     */
    function category_data($cat_id)
    {
        $category_data = [
            'id' => null,
            'name' => null,
            'image' => null,
        ];

        $category = \App\MultisiteHelper::getCategoryToDisplay($cat_id);

        if ($category) {
            $category_data = $category->toArray();
        }

        return $category_data;
    }

    /**
     * Deprecated - moved to eloquent model
     * Use Mtc\Shop\Item::find($id) instead
     * Item name from id
     *
     * @param  mixed  $id
     * @return string name
     * @deprecated
     */
    function item_name($id)
    {
        return Item::findOrNew($id)->name;
    }

    /**
     * Deprecated - moved to eloquent model
     * Use Mtc\Shop\Category::find($id) instead
     * Category name from id
     *
     * @param  mixed  $cat_id
     * @return string name
     * @deprecated
     */
    function Category_Name($cat_id)
    {
        try {
            return Category::findOrFail($cat_id)->name;
        } catch (ModelNotFoundException $e) {
            return '';
        }
    }


    /**
     * Deprecated - moved to eloquent
     * Use Mtc\Shop\Category::renderList($params) instead
     * Generate html for category dropdown box
     *
     * @param  mixed   $selected
     * @param  bool    $showsubs
     * @param  array $exclude ids of categories to exlude from options
     * @return string  html dropdown box
     * @deprecated
     */
    function get_the_categories($selected, $showsubs=true, Array $exclude = array())
    {
        return Category::renderList([
            'template' => 'option',
            'selected' => $selected,
            'show_subs' => $showsubs,
            'exclude' => $exclude
        ]);
    }

    /**
     * Deprecated - moved to eloquent
     * Use Mtc\Shop\Category::getFlatTree($cat_id, true) instead
     * Generates an array of all the category ids in the current tree
     *
     * @param  mixed $cat_id
     * @return array category id array
     * @deprecated
     */
    function get_cat_ids($cat_id)
    {
        return Category::getFlatTree($cat_id, true);
    }


/**
 * Takes a value in GBP and formats it for output in defined currrency
 *
 * @param float $gbp_value
 * @param string $currency
 * @return string
 */
function getCurrency($gbp_value, $currency = '') {

    $currency = $currency ?: $_SESSION['currency']['currency'];

    $currencyValue = getCurrencyValue($gbp_value, $currency);
    $currencySymbol = $_SESSION['currency']['symbol'];

    return '<span class="currencySymbol">' . $currencySymbol . '</span><span class="currencyPrice">' . sprintf("%.2f", $currencyValue) . '</span>';
}

/**
 * Takes value in GBP and converts it to raw, unrounded value in defined
 * currency
 *
 * @param type $gbp_value
 * @param type $currency
 * @return float
 */
function getCurrencyValue($gbp_value, $currency = '') {

    $currency = $currency ?: $_SESSION['currency'];

    //populate currency rates session array if not set
    if (!isset($_SESSION['c_rates'])) {
        $currencies = Currency::all();
        foreach ($currencies as $currency) {
            $_SESSION['c_rates'][$currency->currency] = $currency->ratio;
        }
    }

    return $gbp_value * $_SESSION['c_rates'][$currency];
}

/**
 * Filters $args for $view_state_keys and builds a query string of the following
 * format: key1=val1&key2=val2
 *
 * @param array $args could be GET, POST or REQUEST arrays - or others
 * @param array $view_state_keys list of keys to keep in the query string
 * @return string
 */
function getViewStateQueryString($args, $view_state_keys)
{
    $view_state = [];
    foreach ($args as $key => $value) {
        if (in_array($key, $view_state_keys)) {
            $view_state[] = "$key=$value";
        }
    }

    if (count($view_state)) {
        return implode('&', $view_state);
    } else {
        return '';
    }
}

/**
 * Adds values from assoc array to query string of given view state
 *
 * @param array $args could be GET, POST or REQUEST arrays - or others
 * @param array $view_state_keys list of keys to keep in the query string
 * @param array $values_to_add key value pairs to add to the query string
 * @return string
 */
function modifyViewStateQueryString($args, $view_state_keys, $values_to_add)
{

    //build current viewstate URL
    $query_string = getViewStateQueryString($args, $view_state_keys);

    //add in values
    if ($query_string) {
        $query_string = util::add_query_arg($values_to_add, $query_string);

        //bugfix double encoding in util::add_query_arg
        $query_string = urldecode($query_string);
    } else {
        $query_string = getViewStateQueryString($values_to_add, $view_state_keys);
    }

    return $query_string;
}