<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Property;
use App\Models\Epigraph;
use App\Http\Requests\Api\SearchData;

class SearchController extends Controller
{
    public function show(SearchData $request)
    {
        $data = $request->validated();
        $q = array_key_exists('q', $data) ? $data['q'] : "";
        if ($q !== "") {
            $q = fulltext_search_term($q, true, false);
            $properties = Property::full()
                ->selectRaw('properties.*, property_languages.*, website_objects.*, website_objects_lang.*, MATCH(title, description, popup_description, searchable_address) AGAINST (? IN BOOLEAN MODE) as score', [$q])
                ->with([
                    'accesses' => function ($query) {
                        $query->full()->accessFilters();
                    },
                    'images' => function ($query) {
                        $query->full()->orderBy('id', 'asc')->with('image');
                    },
                    'location' => function ($query) {
                        $query->full();
                    }
                ])
                ->whereRaw('MATCH(title, description, popup_description, searchable_address) AGAINST (? IN BOOLEAN MODE)', [$q])
                ->get();
            $epigraphs = Epigraph::full()
                ->selectRaw('epigraphs.*, epigraph_languages.*, website_objects.*, website_objects_lang.*, MATCH(title, description, present_location) AGAINST (? IN BOOLEAN MODE) as score', [$q])
                ->with([
                    'properties' => function ($query) {
                        $query->full()->select('id')
                        ->with([
                            'images' => function ($query) {
                                $query->full()->orderBy('website_objects.position', 'asc')->with('image');
                            }
                        ]);
                    },
                    'location' => function ($query) {
                        $query->full();
                    },
                    'images' => function ($query) {
                        $query->full();
                    }
                ])
                ->whereRaw('MATCH(title, description, present_location) AGAINST (? IN BOOLEAN MODE)', [$q])
                ->get();
            
            $cleanProperties = $this->formatProperties($properties);
            $cleanEpigraphs = $this->formatEpigraphs($epigraphs);
            $mergedItems = array_merge($cleanProperties, $cleanEpigraphs);
            if (count($mergedItems) > 0) {
                $this->array_sort_by_column($mergedItems, 'score', 'desc');
                return response()->json($mergedItems);
            } else {
                return response()->json();
            }
        } else {
            return response()->json();
        }
    }

    private function formatProperties($properties)
    {
        $cleanProperties = [];
        foreach ($properties as $property) {
            $imageLegend = $property->images->first();
            if (!is_null($imageLegend) && !is_null($imageLegend->image)) {
                $image = getImage($imageLegend->image, '260x170');
            } else {
                $image = null;
            }
            
            $out = [
                "id"           => $property->id,
                "title"        => $property->frontend_title,
                "slug"         => $property->lang_slug,
                "address"      => $property->searchable_address,
                "isAccessible" => $property->accesses->count() > 0,
                "score"        => $property->score,
                "local"        => $property->location ? $property->location->title : "",
                "type"         => "property",
            ];
            if (!is_null($image)) {
                $out['image'] = $image;
            }
            $cleanProperties[] = $out;
        }
        return $cleanProperties;
    }
    
    private function formatEpigraphs($epigraphs)
    {
        $cleanEpigraphs = [];
        foreach ($epigraphs as $epigraph) {
            if (count($epigraph->properties) > 0) {
                $imageLegend = $epigraph->images->first();
                if (!is_null($imageLegend) && !is_null($imageLegend->image)) {
                    $image = getImage($imageLegend->image, '260x170');
                } else {
                    $image = null;
                }
            } else {
                $image = null;
            }
            $out = [
                "id"           => $epigraph->id,
                "title"        => $epigraph->epigraph_title,
                "slug"         => $epigraph->lang_slug,
                "isAccessible" => false,
                "image"        => $image,
                "address"      => $epigraph->present_location,
                "properties"   => $epigraph->properties->pluck("id")->toArray(),
                "score"        => $epigraph->score,
                "local"        => $epigraph->location ? $epigraph->location->title : "",
                "type"         => "epigraph",
            ];
            if (!is_null($image)) {
                $out['image'] = $image;
            }
            $cleanEpigraphs[] = $out;
        }
        return $cleanEpigraphs;
    }

    private function array_sort_by_column(&$array, $column, $dir = 'asc')
    {
        foreach ($array as $a) {
            $sortCol[$a[$column]][] = $a;
        }
        ksort($sortCol);
        $newArr = [];
        foreach ($sortCol as $col) {
            foreach ($col as $row) {
                $newArr[] = $row;
            }
        }
        
        if ($dir == 'desc') {
            $array = array_reverse($newArr);
        } else {
            $array = $newArr;
        }
    }
}
