<?php

namespace Daylight\Core\Modules\Search\Entities;

use Daylight\Core\Modules\Search\SearchQueryBuilder;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;

class SearchResult
{
    protected $results = [];

    public ?Collection $activeFilters;

    public function __construct(
        public SearchQueryBuilder $request,
        public Builder $baseQuery,
        public readonly Collection $originalResults
    ) {
        $this->activeFilters = $this->request->getActiveFilters();
    }

    public function getActiveFilters(bool $formatted = true, bool $ignoreCategory = true): Collection
    {
        $filters = clone $this->request->getActiveFilters();

        if ($ignoreCategory) {
            $filters->forget('categories');
        }

        if ($formatted) {
            return $filters->filter()->mapWithKeys(function ($values, $key) {
                if ($key === 'price') {
                    return collect([
                        $key => collect([
                            new ActivePriceFilter($this, 'price', $values),
                        ]),
                    ]);
                }

                return [
                    $key => collect($values)->map(function ($value) use ($key) {
                        return new ActiveFilter($this, $key, $value);
                    }),
                ];
            })->flatten()->values();
        }

        return $filters;
    }

    //    public function getCurrentFilters(): Collection
    //    {
    //        return FacetGrouping::from(
    //            $this->request->getAvailableFacets()
    //                ->map(function ($name, $property) {
    //                    return new Facet($this, $property, $name);
    //                })
    //                ->values()
    //        )->getGroupedFacets()
    //            ->mapWithKeys(function ($group) {
    //                if ($group['key'] === 'price') {
    //                    $range = $this->request->getActiveFilters()->only($group['facets']->keys())->values()->flatten()->map(function ($price) {
    //                        return formatPrice($price);
    //                    })->join(' - ');
    //
    //                    return [
    //                        $group['key'] => [$range]
    //                    ];
    //                }
    //
    //                $translatedValues = $this->request->getActiveFilters()->only($group['facets']->keys())->map(function ($value, $property) {
    //                    return collect($value)->map(function ($value) use ($property) {
    //                        return Attributes::forProperty($property)[$value] ?? $value;
    //                    })->toArray();
    //                })->values()->flatten()->toArray();
    //
    //                return [
    //                    $group['key'] => $translatedValues
    //                ];
    //            });
    //    }

    //    public function getUnformattedActiveFilters(): Collection
    //    {
    //        return $this->request->getActiveFilters();
    //    }

    public function estimatedTotalHits(): int
    {
        return $this->originalResults->first()['estimatedTotalHits'];
    }

    public function getSortingOptions(): Collection
    {
        return $this->request->getSortingOptions()->map(function ($value, $key) {
            return new SortingOption($this, $key, $value);
        });
    }

    public function getFacets(): Collection
    {
        return $this->request->getAvailableFacets()
            ->map(function ($name, $property) {
                return new Facet($this, $property, $name);
            })
            ->filter(function (Facet $facet) {
                return $facet->getFilters()->count() > 0;
            })
            ->values();
    }

    public function getResults()
    {
        if ($this->results) {
            return $this->results;
        }

        if ($this->estimatedTotalHits() === 0) {
            return collect()->paginateMeilisearchResults($this->estimatedTotalHits(), $this->request->getPerPage());
        }

        $hits = collect($this->originalResults->first()['hits']);

        if ($hits->count() === 0) {
            return collect();
        }

        if (config('database.default') === 'pgsql') {
            $products = $this->baseQuery
                ->whereIn('id', $hits->pluck('id'))
                ->orderByRaw('position(id::text in \''.$hits->pluck('id')->implode(',').'\')')
                ->get();
        } else {
            $products = $this->baseQuery
                ->whereIn('id', $hits->pluck('id'))
                ->orderByRaw('FIELD(id, '.$hits->pluck('id')->implode(',').')')
                ->get();
        }

        //        $products = $this->baseQuery
        //            ->whereIn('id', $hits->pluck('id'))
        //            ->orderByRaw('FIELD(id, '.$hits->pluck('id')->implode(',').')')
        //            ->get();

        $this->results = $products->paginateMeilisearchResults($this->estimatedTotalHits(), $this->request->getPerPage());

        return $this->results;
    }
}
