<?php

namespace App\Http\Controllers\Frontend;

use App\Models\Category;
use App\Models\Product;
use App\Models\ProductAttribute;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;

class CategoryController extends Controller
{
    private $nbConditions = 0;
    public function show(Category $category)
    {
        $categories = Category::with('subs')->where('parent_id', $category->id)->get();
        return view('frontend.categories', compact('categories', 'category'));
    }

    /**
     * @param Request $request
     * @param Category $category
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function produits(Request $request, Category $category)
    {
        $attributes = array_filter($request->input(), function ($key) {
            return strpos($key, 'attr-') === 0;
        }, ARRAY_FILTER_USE_KEY);

        $attributes = array_filter($attributes, function($e) {
            if(is_array($e) && (array_key_exists('min', $e) || array_key_exists('min', $e) )){
                if($e['min'] == null && $e['max'] == null) return false;
            }
            return ($e !== null);
        });

        $productsQuery = Product::published()->with(['brand'])->where('category_id', $category->id);
        
        if(!empty($attributes)) {
            $ids = $this->getIDs($category, $attributes);
            $productsQuery->whereIn('id', $ids);
        }
        $products = $productsQuery->paginate(54);
        return view('frontend.produits', compact('products', 'category'));
    }

    /**
     * @param Category $category
     * @param $attributes
     * @return array
     */
    public function getIDs(Category $category, $attributes)
    {
        $productsIDsQuery = ProductAttribute::has('product')->where('category_id', $category->id)->where(function ($productsIDsQuery) use ($attributes) {
            foreach ($attributes as $key => $attribute) {
                if (!empty($attribute)) {
                    if (strpos($key, "attr-n-") !== false) {
                        $id = str_replace('attr-n-', '', $key);
                        $min = $attribute['min'];
                        $max = $attribute['max'];
                        if (!empty($min) && !empty($max)) {
                            $this->nbConditions++;
                            $productsIDsQuery->orWhere(function ($query) use ($id, $attribute, $min, $max) {
                                $query->where('attribute_id', $id)->where(function ($query) use ($attribute, $min, $max) {
                                    $query->where('value', '>=', $min)->where('value', '<=', $max);
                                });
                            });
                        } elseif (!empty($min)) {
                            $this->nbConditions++;
                            $productsIDsQuery->orWhere(function ($query) use ($id, $min) {
                                $query->where('attribute_id', $id)->where('value', '>=', $min);
                            });
                        } elseif (!empty($max)) {
                            $this->nbConditions++;
                            $productsIDsQuery->orWhere(function ($query) use ($id, $max) {
                                $query->where('attribute_id', $id)->where('value', '<=', $max);
                            });
                        }
                    } elseif (strpos($key, "attr-s-") !== false || strpos($key, "attr-b-") !== false) {
                        $this->nbConditions++;
                        $id = str_replace(['attr-s-', 'attr-b-'], '', $key);
                        $productsIDsQuery->orWhere(function ($query) use ($id, $attribute) {
                            $query->where('attribute_id', $id)->where(function ($query) use ($attribute) {
                                foreach ($attribute as $item) {
                                    if ($item === reset($attribute)) {
                                        $query->where('value', $item);
                                    } else {
                                        $query->orWhere('value', $item);
                                    }
                                }
                            });
                        });
                    } elseif (strpos($key, "attr-int-") !== false) {   //Interval
                        $id = str_replace('attr-int-', '', $key);
                        $min = $attribute['min'];
                        $max = $attribute['max'];
                        if (!empty($min) && !empty($max)) {
                            $this->nbConditions++;
                            $productsIDsQuery->orWhere(function ($query) use ($id, $attribute, $min, $max) {
                                $query->where('attribute_id', $id)->where(function ($query) use ($attribute, $min, $max) {
                                    $query->whereRaw($min ." >= (1 * SUBSTRING_INDEX(value, ':', 1))")
                                            ->whereRaw($max . " <= (1 * SUBSTRING_INDEX(value, ':', -1))");
                                });
                            });
                        } elseif (!empty($min)) {
                            $this->nbConditions++;
                            $productsIDsQuery->orWhere(function ($query) use ($id, $min) {
                                $query->where('attribute_id', $id)->whereRaw($min ." >= (1 * SUBSTRING_INDEX(value, ':', 1))");
                            });
                        } elseif (!empty($max)) {
                            $this->nbConditions++;
                            $productsIDsQuery->orWhere(function ($query) use ($id, $max) {
                                $query->where('attribute_id', $id)->whereRaw($max . " <= (1 * SUBSTRING_INDEX(value, ':', -1))");
                            });
                        }

                    } else {
                        $this->nbConditions++;
                        $id = str_replace('attr-', '', $key);
                        $productsIDsQuery->orWhere(function ($query) use ($id, $attribute) {
                            $query->where('attribute_id', $id)->where('value', 'LIKE', '%' . $attribute . '%');
                        });
                    }
                }
            }
        });


        $ids = $productsIDsQuery
            ->groupBy('product_id')
            ->havingRaw('count(product_id) = ' . $this->nbConditions)
            ->select('product_id')
            ->distinct('product_id')
            ->pluck('product_id')->all();
        return $ids;
    }
}
