<?php

namespace App;

use App\Http\Requests\SearchRequest;
use Illuminate\Support\Collection;
use Mtc\MercuryDataModels\BodyStyleType;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Enquiry;
use Mtc\MercuryDataModels\Form;
use Mtc\MercuryDataModels\FuelType;
use Mtc\MercuryDataModels\GlobalContent;
use Mtc\MercuryDataModels\Menu;
use Mtc\MercuryDataModels\NewCar;
use Mtc\MercuryDataModels\Page;
use Mtc\MercuryDataModels\TransmissionType;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleModel;
use Mtc\MercuryDataModels\VehicleOffer;

class AdminSearchRepository
{
    public function search(SearchRequest $request)
    {
        $type = $request->input('type') ?? 'all';
        return collect([

            'enquiries' => in_array($type, ['all', 'enquiry']) ? $this->enquiries($request) : null,
            'vehicles' => in_array($type, ['all', 'vehicle']) ? $this->vehicles($request) : null,
            'pages' => in_array($type, ['all', 'page']) ? $this->pages($request) : null,
            'offers' => in_array($type, ['all', 'offer']) ? $this->offers($request) : null,
            'new-car' => in_array($type, ['all', 'new-car']) ? $this->newCars($request) : null,
            'global' => in_array($type, ['all', 'global']) ? $this->globalContent($request) : null,
            'menu' => in_array($type, ['all', 'global']) ? $this->menus($request) : null,
            'dealership' => in_array($type, ['all', 'global']) ? $this->dealerships($request) : null,
            'form' => in_array($type, ['all', 'global']) ? $this->form($request) : null,
        ])
            ->filter()
            ->flatten(1)
            ->unique();
    }

    public function getSectionFilters(string $type): array
    {
        return match ($type) {
            'vehicles' => $this->getVehicleSectionFilters(),
            'valuations'  => $this->getValuationSectionFilters(),
            default => [],
        };
    }

    public function getValuationSectionFilters(): array
    {
        return [
            [
                'value' => 'created_at',
                'name' => 'Date requested',
                'range' => true,
                'range_type' => 'date',
                'min' => null,
                'max' =>  null,
            ],
        ];
    }
    public function getVehicleSectionFilters(): array
    {
        return [
            [
                'value' => 'status',
                'name' => 'Status',
                'choices' => [
                    [
                        'id' => 'draft',
                        'name' => 'Draft/Unpublished',
                        'type' => 'status',
                    ],
                    [
                        'id' => 'is_published',
                        'name' => 'Published',
                        'type' => 'status',
                    ],
                    [
                        'id' => 'featured',
                        'name' => 'Featured',
                        'type' => 'status',
                    ],
                    [
                        'id' => 'is_reserved',
                        'name' => 'Reserved',
                        'type' => 'status',
                    ],
                    [
                        'id' => 'is_sold',
                        'name' => 'Sold',
                        'type' => 'status',
                    ],
                    [
                        'id' => 'deleted_at',
                        'name' => 'Archived',
                        'type' => 'status',
                    ],
                ],
            ],
            [
                'value' => 'type',
                'name' => 'Vehicle Type',
                'choices' => collect(VehicleType::cases())->map(fn(VehicleType $value) => [
                    'id' => $value->value,
                    'name' => $value->name,
                    'type' => 'type',
                ])
            ],
            [
                'value' => 'condition',
                'name' => 'Condition',
                'choices' => [
                    [
                        'id' => 'used',
                        'name' => 'Used',
                        'type' => 'age_type',
                    ],
                    [
                        'id' => 'is_demo',
                        'name' => 'Ex-Demo',
                        'type' => 'age_type',
                    ],
                    [
                        'id' => 'is_new',
                        'name' => 'New',
                        'type' => 'age_type',
                    ],
                ],
            ],
            [
                'value' => 'make_id',
                'name' => 'Make',
                'choices' => VehicleMake::query()
                    ->whereHas('vehicles', fn($query) => $query->withTrashed())
                    ->select(['name', 'id'])
                    ->get()
                    ->map(function ($entry) {
                        $entry['type'] = 'make_id';
                        $entry->setVisible(['name', 'id', 'type']);
                        return $entry;
                    })
                    ->prepend(['name' => '(Empty)', 'id' => 'null']),
            ],
            [
                'value' => 'model_id',
                'name' => 'Model',
                'choices' => VehicleModel::query()
                    ->whereHas('vehicles', fn($query) => $query->withTrashed())
                    ->select(['name', 'id'])
                    ->get()
                    ->map(function ($entry) {
                        $entry['type'] = 'model_id';
                        $entry->setVisible(['name', 'id', 'type']);
                        return $entry;
                    })
                    ->prepend(['name' => '(Empty)', 'id' => 'null']),
            ],
            [
                'value' => 'dealership_id',
                'name' => 'Location',
                'choices' => Dealership::query()
                    ->select(['name', 'id'])
                    ->get()
                    ->map(function ($entry) {
                        $entry['type'] = 'dealership_id';
                        $entry->setVisible(['name', 'id', 'type']);
                        return $entry;
                    })
                    ->prepend(['name' => '(Empty)', 'id' => 'null']),
            ],
            [
                'value' => 'price',
                'name' => 'Price',
                'range' => true,
                'min' => null,
                'max' =>  null,
            ],
            [
                'value' => 'fuel_type_id',
                'name' => 'Fuel Type',
                'choices' => FuelType::query()
                    ->whereHas('vehicles', fn($query) => $query->withTrashed())
                    ->select(['name', 'id'])
                    ->get()
                    ->map(function ($entry) {
                        $entry['type'] = 'fuel_type_id';
                        $entry->setVisible(['name', 'id', 'type']);
                        return $entry;
                    })
                    ->prepend(['name' => '(Empty)', 'id' => 'null']),
            ],
            [
                'value' => 'transmission_id',
                'name' => 'Transmission',
                'choices' => TransmissionType::query()
                    ->whereHas('vehicles', fn($query) => $query->withTrashed())
                    ->select(['name', 'id'])
                    ->get()
                    ->map(function ($entry) {
                        $entry['type'] = 'transmission_id';
                        $entry->setVisible(['name', 'id', 'type']);
                        return $entry;
                    })
                    ->prepend(['name' => '(Empty)', 'id' => 'null']),
            ],
            [
                'value' => 'body_style_id',
                'name' => 'Body Style/Type',
                'choices' => BodyStyleType::query()
                    ->whereHas('vehicles', fn($query) => $query->withTrashed())
                    ->select(['name', 'id'])
                    ->get()
                    ->map(function ($entry) {
                        $entry['type'] = 'body_style_id';
                        $entry->setVisible(['name', 'id', 'type']);
                        return $entry;
                    })
                    ->prepend(['name' => '(Empty)', 'id' => 'null']),
            ],
            [
                'value' => 'image_count',
                'name' => 'Image Count',
                'range' => true,
                'min' => null,
                'max' =>  null,
            ],
        ];
    }

    private function enquiries(SearchRequest $request): Collection
    {
        return Enquiry::query()
            ->where('title', 'like', $request->getTerm())
            ->get();
    }

    private function vehicles(SearchRequest $request): Collection
    {
        return Vehicle::query()
            ->whereFullText('search_content', $request->getTerm())
            ->orWhere('vrm_condensed', $request->getTerm(false))
            ->orWhere('registration_number', $request->getTerm(false))
            ->get();
    }

    private function pages(SearchRequest $request): Collection
    {
        return Page::query()
            ->with('categories')
            ->whereFullText('search_content', $request->getTerm())
            ->orWhere('title', 'like', $request->getTerm())
            ->get();
    }

    private function newCars(SearchRequest $request): Collection
    {
        return NewCar::query()
            ->whereFullText('search_content', $request->getTerm())
            ->orWhere('name', 'like', $request->getTerm())
            ->get();
    }

    private function offers(SearchRequest $request): Collection
    {
        return VehicleOffer::query()
            ->whereFullText('search_content', $request->getTerm())
            ->orWhere('name', 'like', $request->getTerm())
            ->get();
    }

    private function globalContent(SearchRequest $request): Collection
    {
        return GlobalContent::query()
            ->where('name', 'like', $request->getTerm())
            ->get();
    }

    private function menus(SearchRequest $request): Collection
    {
        return Menu::query()
            ->where('title', 'like', $request->getTerm())
            ->get();
    }

    private function dealerships(SearchRequest $request): Collection
    {
        return Dealership::query()
            ->where('name', 'like', $request->getTerm())
            ->get();
    }

    private function form(SearchRequest $request): Collection
    {
        return Form::query()
            ->where('name', 'like', $request->getTerm())
            ->get();
    }
}
