<?php

namespace App\Http\Livewire\MainPage;

use App\Http\Livewire\Calls\ProfileCalls;
use App\Models\Call;
use App\Models\Locations\City;
use App\Models\Locations\Country;
use App\Models\Locations\Division;
use App\Models\Locations\Location;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Livewire\Component;

class CallCardFull extends Component
{
    public $call = null;
    public int $postNr;
    public bool $related;
    public bool $random;

    public function mount(int $postNr, bool $related, bool $random = false, Request $request): void
    {
        $this->postNr  = $postNr;
        $this->related = $related;
        $this->random  = $random;

        $profile = getActiveProfile();

        if ($profile) {
            \App\Helpers\ProfileAuthorizationHelper::authorize($profile);
        }

        $location = $profile && $profile->locations ? $profile->locations()->first() : null;

        // Resolve location filter arrays (same pattern as EventCardFull)
        $locationCityIds     = [];
        $locationDivisionIds = [];
        $locationCountryIds  = [];

        if ($location) {
            if (!$location->division && !$location->city) {
                $country = Location::find($location->id)->country;
                if ($related) {
                    $locationCountryIds = Country::pluck('id')->toArray();
                } else {
                    $locationCountryIds = $country ? [$country->id] : [];
                }
            } elseif ($location->division && !$location->city) {
                $divisionId = Location::find($location->id)->division->id;
                if ($related) {
                    $locationDivisionIds = Division::find($divisionId)->parent->divisions->pluck('id')->toArray();
                } else {
                    $locationDivisionIds = [$divisionId];
                }
            } elseif ($location->city) {
                $cityId = Location::find($location->id)->city->id;
                if ($related) {
                    $locationCityIds = City::find($cityId)->parent->cities->pluck('id')->toArray();
                } else {
                    $locationCityIds = [$cityId];
                }
            }
        }

        $locale = App::getLocale();

        $query = Call::with([
                'tag.contexts.category.translations',
                'tag.contexts.category.ancestors.translations',
                'translations',
                'location.city.translations',
                'location.country.translations',
                'callable.locations.city.translations',
                'callable.locations.division.translations',
                'callable.locations.country.translations',
                'loveReactant.reactionCounters',
            ])
            ->where('is_public', true)
            ->where('is_paused', false)
            ->where('is_suppressed', false)
            ->whereNull('deleted_at')
            ->where(fn ($q) => $q->whereNull('till')->orWhere('till', '>=', now()));

        // Apply location filter when a profile location is known
        if ($locationCityIds || $locationDivisionIds || $locationCountryIds) {
            $query->whereHas('location', function ($q) use ($locationCityIds, $locationDivisionIds, $locationCountryIds) {
                $q->where(function ($q) use ($locationCityIds, $locationDivisionIds, $locationCountryIds) {
                    if ($locationCityIds) {
                        $q->orWhereIn('city_id', $locationCityIds);
                    }
                    if ($locationDivisionIds) {
                        $q->orWhereIn('division_id', $locationDivisionIds);
                    }
                    if ($locationCountryIds) {
                        $q->orWhereIn('country_id', $locationCountryIds);
                    }
                });
            });
        }

        if ($random) {
            $query->inRandomOrder();
            $call = $query->first();
        } else {
            $query->orderBy('till');
            $calls = $query->get();
            $call  = $calls->count() > $postNr ? $calls[$postNr] : null;
        }

        if (!$call) {
            return;
        }

        $translation = $call->translations->firstWhere('locale', $locale)
            ?? $call->translations->first();

        $tag         = $call->tag;
        $tagContext  = $tag?->contexts->first();
        $tagCategory = $tagContext?->category;
        $tagColor    = $tagCategory?->relatedColor ?? 'gray';
        $tagName     = $tag?->translation?->name ?? $tag?->name;

        $locationStr = null;
        if ($call->location) {
            $loc   = $call->location;
            $parts = [];
            if ($loc->city) {
                $cityName = optional($loc->city->translations->first())->name;
                if ($cityName) $parts[] = $cityName;
            }
            if ($loc->country) {
                if ($loc->country->code === 'XX') {
                    $parts[] = __('Location not specified');
                } elseif ($loc->country->code) {
                    $parts[] = strtoupper($loc->country->code);
                }
            }
            $locationStr = $parts ? implode(', ', $parts) : null;
        }

        $tagCategories = [];
        if ($tagCategory) {
            $ancestors = $tagCategory->ancestorsAndSelf()->get()->reverse();
            foreach ($ancestors as $cat) {
                $catName = $cat->translations->firstWhere('locale', $locale)?->name
                    ?? $cat->translations->first()?->name
                    ?? '';
                if ($catName) {
                    $tagCategories[] = [
                        'name'  => $catName,
                        'color' => $cat->relatedColor ?? 'gray',
                    ];
                }
            }
        }

        $this->call = [
            'id'                => $call->id,
            'model'             => Call::class,
            'title'             => $tagName ?? '',
            'excerpt'           => $translation?->content ?? '',
            'photo'             => $call->callable?->profile_photo_url ?? '',
            'location'          => $locationStr,
            'tag_color'         => $tagColor,
            'tag_categories'    => $tagCategories,
            'callable_name'     => $call->callable?->name ?? '',
            'callable_location' => ProfileCalls::buildCallableLocation($call->callable),
            'till'              => $call->till,
            'expiry_badge_text' => ProfileCalls::buildExpiryBadgeText($call->till),
            'like_count'        => $call->loveReactant?->reactionCounters->firstWhere('reaction_type_id', 3)?->count ?? 0,
            'score'             => 0,
        ];
    }

    public function render()
    {
        return view('livewire.main-page.call-card-full');
    }
}
