<?php

namespace App\Http\Controllers\Api\V1\Filters\Helpers;

use App\Models\Ecommerce\Product\Brand\Brand;
use App\Models\Ecommerce\Product\Category\Category;
use App\Models\Ecommerce\Product\Collection\Collection;
use App\Repositories\Ecommerce\Filter\FilterParamRepository;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Laravel\Nova\Makeable;

class CategoriesFilter
{
    use Makeable;

    /**
     * Request object to work with
     */
    protected Request $request;

    /**
     * Request object to work with
     */
    protected Builder $queryBuilder;

    /**
     * Filter repo
     */
    protected FilterParamRepository $filterRepository;

    /**
     * Table columns to get
     */
    protected array $columns = [
        'id',
        'parent_id',
        'name',
    ];

    /**
     * Categories for filtering
     */
    public function __construct(Request $request)
    {
        $this->request = $request;
        $this->queryBuilder = config('ecommerce.models.category')::query();
        $this->filterRepository = FilterParamRepository::make($this->request);
    }

    /**
     * Basic queries
     */
    public function applyBaseQueries(): self
    {
        $this->queryBuilder->enabled()->ordered();

        return $this;
    }

    /**
     * Get all categories
     */
    public function get()
    {
        if ($this->filterRepository->shouldFilterByCategory()) {
            return Category::find($this->request->category_id, ['id', 'parent_id'])->children()->get($this->columns);
        }

        if ($this->filterRepository->shouldFilterByCollection()) {
            return $this->byResource(Collection::find($this->request->collection_id));
        }

        if ($this->filterRepository->shouldFilterByBrand()) {
            return $this->byResource(Brand::find($this->request->brand_id));
        }

        return $this->queryBuilder->get($this->columns);
    }

    public function byResource($resource)
    {
        $products = $resource->products()
            ->where('products.is_visible', true)
            ->where('products.parent_id', null)
            ->where('products.stock', '>', 0)
            ->distinct('products.id')
            ->pluck('products.id');

        return $this->queryBuilder->join('product_has_relations', 'categories.id', '=', 'product_has_relations.productable_id')
            ->where('product_has_relations.productable_type', '=', 'category')
            ->whereIntegerInRaw('product_has_relations.product_id', $products)
            ->get($this->columns)
            ->unique('categories.id');
    }
}
