<?php

namespace App\Http\Controllers;

use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Mtc\Shop\Category;
use Mtc\Shop\Item;
use Mtc\Shop\Assessment\Assessment;
use MtcPharmacy\QualifyingAnswers\Classes\QualifyingAnswersFilter;
use App\MetaDataFactory;
use MtcPharmacy\Bundles\Classes\BundleTypeItem;


class CategoryController extends Controller
{

    public static function index(Request $request, $category_slug = null)
    {
        redirect_if_trailing_slash();

        if ($category_slug) {
            $category = Category::query()->where('slug', $category_slug)->first();
        } else {
            $category = Category::query()->where('is_online_doctor', 1)->where('sub_id', 0)->first();
        }

        if (!$category) {
            abort(404);
        }

        $fullscreen = (bool) request()->input('fullscreen');
        if ($fullscreen) {
            $template = 'shop/category/fullscreen_products.twig';
        } else {
            $template = 'shop/category/landing.twig';
        }

        $template_data = [];
        $template_data['category'] = $category;

        $meta_data_factory = new MetaDataFactory($category);
        $template_data['page_meta'] = [
            'title' => $meta_data_factory->getMetaTitle(),
            'description' => $meta_data_factory->getMetaDescription(),
        ];

        $template_data['items'] = self::getDisplayItems($category);
        $template_data['items_doctor'] = self::getDisplayItems($category, ['doctor']);
        $template_data['items_standard'] = self::getDisplayItems($category, ['general', 'pharmacy']);

        return template($template, $template_data);
    }


    /*** HELPERS ***/

    public static function getDisplayItems(Category $category, $type_filter = [], $assessmentResults = false)
    {
        $base_category = $category;

        $available_items_query = $base_category->items()->active();

        $available_items_query->addSelect(['items.*']);

        /** @var Collection $available_items */
        // Eager-load every relation mapItemFields() / getProductCardData()
        // touch per item. Without `categories` and `custom` the per-item
        // accessors fired one SELECT each on the category landing page.
        $items = $available_items_query
            ->with(['images', 'sizes', 'categories', 'custom'])
            ->orderBy('order')
            ->orderBy('id')
            ->get();

        /** @var Assessment $assessment */
        $assessment = Assessment::getCompletedForCategory($base_category);
        $items = self::addGroupBuyItems($items);
        $items = $items->unique();

        $items = self::applyQualifyingAnswersFilter($items, $assessment);
        $items = self::applyTypeFilter($items, $type_filter);
        /** @var Collection $items */

        // Find recommended items based on answers
        if ($assessmentResults && !empty($assessment)) {
            $items = $assessment->buildProductListBasedOnAnswers($items);
            $items = self::applyStockFilter($items);
        }

        return self::mapItemFields($items)->values();
    }

    protected static function applyQualifyingAnswersFilter($items, $assessment)
    {
        $qa_filter = QualifyingAnswersFilter::init($assessment);

        if (isset($_SESSION['adminId']) && request()->input('debug')) {
            \Util::var_dump($qa_filter->getDebugInfo());
            \Util::var_dump($qa_filter);
        }

        $rejected_items = $qa_filter->getRejectedItemIDs();

        return $items->filter(function ($i) use ($rejected_items) {
            return (!in_array($i->id, $rejected_items));
        });
    }

    protected static function addGroupBuyItems($items)
    {
        $groupbuy_items = Item::getMatchingGroupBuyItems($items);

        foreach ($groupbuy_items as $groupbuy_item) {
            $items->push($groupbuy_item);
        }
        return $items;
    }

    protected static function applyTypeFilter($items, $type_filter)
    {
        if (empty($type_filter)) {
            return $items;
        }

        return $items->filter(function ($item) use ($type_filter) {
            foreach ($type_filter as $type) {
                if ($item->product_type == $type || empty($item->product_type) && $type == 'general') {
                    return true;
                }
            }
            return false;
        });
    }

    protected static function mapItemFields($items)
    {
        $items->map(function ($item) {

            $assessment_display = !empty($category->displayed_on_assessment) || !empty($assessment);
            $item->basket_button_data = $item->getProductCardData(true, "Get started", $assessment_display);

            $main_category_id = $item->getMainCategory()->id;

            $sub_categories = $item->categories->filter(function ($c) use ($main_category_id) {
                return $main_category_id != $c->id;
            });

            $sub_category = $sub_categories->first();

            $sub_category_data = [];
            $sub_category_data['id'] = false;
            $sub_category_data['name'] = false;

            if (!empty($sub_category)) {
                $sub_category_data['id'] = $sub_category->id;
                $sub_category_data['name'] = $sub_category->name;
            }

            $item->main_sub_category = $sub_category_data;

            if (config('subscription.enabled')) {
                $item->resolvePricePerPill();
                $item->mapSizePricesToSubscriptions();
            }

            return $item;

        });

        return $items;
    }

    /**
     * Removes out of stock items
     *
     * @param $items
     * @return mixed
     */
    protected static function applyStockFilter($items)
    {
        return $items->filter(function ($item) {
            return $item->in_stock;
        });
    }
}
