<?php
namespace Mtc\Shop;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Mtc\Shop\Item\Size;

/**
 * @author Uldis Zvirbulis <uldis.zvirbulis@mtcmedia.co.uk>
 */
class Ingredient extends Model
{

    protected $fillable = [
        'name',
        'strength',
        'limit_order',
        'limit_period',
        'limit_amount',
        'limit_once',
        'limit_type',
        'message',
    ];

    /**
     * Define the relationship to Item
     * @return \Illuminate\Database\Eloquent\Relations\belongsToMany
     */
    public function items()
    {
        return $this->belongsToMany(Item::class, 'items_ingredients');
    }

    /**
     * Define the relationship to Size
     * @return \Illuminate\Database\Eloquent\Relations\belongsToMany
     */
    public function sizes()
    {
        return $this->belongsToMany(Size::class, 'items_ingredients');
    }

    /**
     * check if ingredient purchase limits have been exceeded
     *
     * @param Collection $items_in_basket
     * @param array $ingredient_order_history
     * @return bool
     */
    public function exceedsIngredientLimit($items_in_basket, array $ingredient_order_history)
    {
        // if has already purchased item and it's limited to one purchase
        if (!empty($ingredient_order_history) && !empty($this->limit_once)) {
            return true;
        }

        $quantity = $this->amount_in_basket;

        if ($this->limit_type === 'tablets') {
            // Limit is quantity (number of tablets)

            $items_in_basket->reject(function ($basket_item) {
                return empty($basket_item['sizeid']);
            });

            if (count($items_in_basket) == 0) {
                // Don't calculate if there's no variations. Only variations have quantities
                return false;
            }

            $quantity = $items_in_basket->map(function ($basket_item) {
                $quantity = Size::query()->find($basket_item['sizeid'])->quantity ?? 0;
                return (int)$quantity * (int)$basket_item['quantity'];
            })->sum();

        }
        // If exceeds per Order limit
        if (!empty($this->limit_order) && $quantity > $this->limit_order) {
            return true;
        }

        // No custom limits have been set
        if (empty($this->limit_period) || empty($this->limit_amount)) {
            return false;
        }

        // Periods. Can add other periods here if required
        $periods = [
            [
                'days' => $this->limit_period,
                'limit' => $this->limit_amount,
                'purchased' => $quantity,
            ]
        ];

        if (!empty($ingredient_order_history)) {
            foreach ($ingredient_order_history as $historical_purchase) {
                $seconds_from_purchase = time() - strtotime($historical_purchase['date']);

                $purchased_quantity = $this->limit_type === 'boxes' ?
                    $historical_purchase['quantity'] :
                    $historical_purchase['tablets_quantity'];

                // Build the amounts purchased in the period
                foreach ($periods as $key => $period) {
                    if ($seconds_from_purchase < \Util::SECONDS_IN_A_DAY * $period['days']) {
                        $periods[$key]['purchased'] += $purchased_quantity;
                    }
                }
            }
        }
        foreach ($periods as $key => $period) {
            if ($period['limit'] > 0 && $period['purchased'] > $period['limit']) {
                return true;
            }
        }

        return false;
    }

}
