<?php
/**
 * Customers Also Viewed
 *
 * Show related products that were viewed at the same time as other products
 *
 * @author Andrew Morgan <andrew.morgan@mtcmedia.co.uk>
 */
namespace Mtc\Plugins\CustomersAlsoViewed\Classes;

use Item;
use Illuminate\Database\Eloquent\Model;
use Twig\Environment;

/**
 * Customers Also Viewed
 *
 * Show related products that were viewed at the same time as other products
 *
 * @author Andrew Morgan <andrew.morgan@mtcmedia.co.uk>
 */
class CustomersAlsoViewed extends Model  {
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'customers_also_viewed';

    /**
     * Allow item_id to be set
     *
     * @var Array
     */
    protected $fillable = [
        'item_id',
        'also_viewed_id',
    ];
    /**
     * RecentlyViewed::getAlsoViewed()
     *
     * Returns an array of items also viewed
     *
     * @author Andrew Morgan <andrew.morgan@mtcmedia.co.uk>
     *
     * @return Array $customers_also_viewed Array of item ID's
     * @param Environment $twig used for templating
     * @param int $limit Maximum amount to return
     * @param int $item_id ID of item
     */
    public static function getAlsoViewed(Environment $twig, $limit, $item_id)
    {
        // initialise array
        $customers_also_viewed = [];

        // return all item ID's for this product ordered by views
        $customers_also_viewed_results = self::query()
            ->orderBy('views')
            ->groupBy('item_id')
            ->pluck('item_id')
            ->take($limit);

        // Loop through all items and render them with twig returning as array
        if (!empty($customers_also_viewed_results)) {

            foreach ($customers_also_viewed_results as $customers_also_viewed_item_id) {

                if ($customers_also_viewed_item_id == $item_id) {
                    continue;
                }

                $customers_also_viewed_item = new Item();
                $customers_also_viewed_item->Get_Item($customers_also_viewed_item_id);

                $customers_also_viewed[] = $twig->render('shop/item/small.twig', [
                    'item' => $customers_also_viewed_item
                ]);

            }

        }

        return $customers_also_viewed;

    }

    /**
     * RecentlyViewed::itemCombinationExists()
     *
     * Check if a particular item and also viewed item combination exists
     *
     * @return bool
     * @param int $item_id ID of item
     * @param int $also_viewed_id ID of item that is being checked
     */
    public static function itemCombinationExists($item_id, $also_viewed_id)
    {
        // Work out if this item combination already exists
        $check = self::where('item_id', $item_id)
            ->where('also_viewed_id', $also_viewed_id)->count();

        return !empty($check);
    }

    /**
     * RecentlyViewed::registerItemView()
     *
     * Adds ID of the given item to the session of recently viewed items
     *
     * @param Array $args Item Object is passed through a hook to this function
     * @return null
     */
    public static function registerItemView($args)
    {

        $item = &$args[0];

        if (empty($_SESSION['also_viewed'])) {
            $_SESSION['also_viewed'] = [];
        }

        $also_viewed_ids = array_filter(
            $_SESSION['also_viewed'],
            fn($id) => $id != $item->id
        );

        if (!empty($also_viewed_ids)) {
            $existing = self::where('item_id', $item->id)
                ->whereIn('also_viewed_id', $also_viewed_ids)
                ->pluck('also_viewed_id')
                ->all();

            if (!empty($existing)) {
                self::where('item_id', $item->id)
                    ->whereIn('also_viewed_id', $existing)
                    ->increment('views');
            }

            $new = array_diff($also_viewed_ids, $existing);
            if (!empty($new)) {
                $rows = array_map(fn($id) => [
                    'item_id' => $item->id,
                    'also_viewed_id' => $id,
                    'views' => 1,
                ], $new);
                self::insert($rows);
            }
        }

        if (!in_array($item->id, $_SESSION['also_viewed'])
            && !empty($item->id))
        {
            $_SESSION['also_viewed'][] = $item->id;
        }

    }
}
