<?php

namespace App\Http\Resources\SearchProfiles;

use App\Enums\FilterTypeEnum;
use App\Models\BuildingType;
use App\Models\City;
use App\Models\Cpv;
use App\Models\Country;
use App\Models\Department;
use App\Models\ProcedureType;
use Illuminate\Http\Resources\Json\JsonResource;

class SearchProfileResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param \Illuminate\Http\Request $request
     * @return array
     */

    public function toArray($request)
    {
        $filtersDetail = [];
        switch ($this->type) {
            case FilterTypeEnum::COMPETITIONS->value:
                $filtersDetail = $this->competitionsFilter();
                break;
            case FilterTypeEnum::RESULTS->value:
                $filtersDetail = $this->resultsFilter();
                break;
        }
        return [
            'id' => $this->id,
            'name' => $this->name,
            'type' => $this->type,
            'filters' => $this->filters,
            'filtersDetail' => $filtersDetail,
            'emailUpdates' => $this->email_updates,
        ];
    }

    private function competitionsFilter()
    {
        $filtersDetail = [];
        if (isset($this->filters['typeOfService'])) {
            $departments = Department::full()
                ->whereIn('id', $this->filters['typeOfService'])
                ->get();
            $filtersDetail['typeOfService'] = $departments->map(function ($department) {
                return [
                    'id' => $department->id,
                    'title' => $department->title,
                ];
            });
        }
        if (isset($this->filters['typeOfAnnouncement'])) {
            $filtersDetail['typeOfAnnouncement'] = $this->mapProcedureTypes($this->filters['typeOfAnnouncement']);
        }
        if (isset($this->filters['countries'])) {
            $filtersDetail['countries'] = $this->mapCountries($this->filters['countries']);
        }
        if (isset($this->filters['locations'])) {
            $filtersDetail['locations'] = $this->mapLocations($this->filters['locations']);
        }

        if (isset($this->filters['cpvs'])) {
            $cpvs = Cpv::full()
                ->whereIn('id', $this->filters['cpvs'])
                ->get();
            $filtersDetail['cpvs'] = $cpvs->map(function ($cpv) {
                return [
                    'id' => $cpv->id,
                    'title' => "{$cpv->code} - {$cpv->title}",
                ];
            });
        }

        if (isset($this->filters['search'])) {
            $filtersDetail['search'] = $this->filters['search'];
        }

        if (isset($this->filters['publicationDate'])) {
            $filtersDetail['publicationDate'] = $this->filters['publicationDate'];
        }

        if (isset($this->filters['deadlineExpiry'])) {
            $filtersDetail['deadlineExpiry'] = $this->filters['deadlineExpiry'];
        }

        return $filtersDetail;
    }

    private function resultsFilter()
    {
        $filtersDetail = [];
        if (isset($this->filters['typeOfAnnouncement'])) {
            $filtersDetail['typeOfAnnouncement'] = $this->mapProcedureTypes($this->filters['typeOfAnnouncement']);
        }

        if (isset($this->filters['typeOfBuilding'])) {
            $buildingTypes = BuildingType::full()
                ->whereIn('id', $this->filters['typeOfBuilding'])
                ->get();
            $filtersDetail['typeOfBuilding'] = $buildingTypes->map(function ($buildingType) {
                return [
                    'id' => $buildingType->id,
                    'title' => $buildingType->title,
                ];
            });
        }

        if (isset($this->filters['countries'])) {
            $filtersDetail['countries'] = $this->mapCountries($this->filters['countries']);
        }

        if (isset($this->filters['locations'])) {
            $filtersDetail['locations'] = $this->mapLocations($this->filters['locations']);
        }

        if (isset($this->filters['resultDate'])) {
            $filtersDetail['resultDate'] = $this->filters['resultDate'];
        }

        if (isset($this->filters['search'])) {
            $filtersDetail['search'] = $this->filters['search'];
        }

        return $filtersDetail;
    }

    private function mapProcedureTypes(array $ids)
    {
        return ProcedureType::full()
            ->whereIn('id', $ids)
            ->get()
            ->map(function ($procedureType) {
                return [
                    'id' => $procedureType->id,
                    'title' => $procedureType->title,
                ];
            });
    }

    private function mapCountries(array $ids)
    {
        return Country::full()
            ->whereIn('id', $ids)
            ->get()
            ->map(function ($country) {
                return [
                    'id' => $country->id,
                    'title' => $country->common_name,
                ];
            });
    }

    private function mapLocations(array $locations)
    {
        $cities = City::full()
            ->with('state.country')
            ->whereIn('id', array_map(function ($location) {
                return $location['id'];
            }, $locations))
            ->get();

        return $cities->map(function ($city) use($locations) {
            $location = array_filter($locations, function ($location) use ($city) {
                return $location['id'] == $city->id;
            });
            $location = array_shift($location);
            return [
                'id' => $city->id,
                'city' => $city->title,
                'stateId' => $city->state->id,
                'state' => $city->state->title,
                'countryId' => $city->state->country->id,
                'country' => $city->state->country->common_name,
                'radius' => $location['radius'],
            ];
        });
    }
}
