<?php

namespace App\Http\Livewire\MainPage;

use App\Models\Category;
use App\Models\Locations\City;
use App\Models\Locations\Country;
use App\Models\Locations\Division;
use App\Models\Locations\Location;
use App\Models\News;
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\App;
use Livewire\Component;

class ImageCardFull extends Component
{
    public $author;
    public $post = [];
    public $posts;
    public $media;
    public $postNr;
    public $related;
    public bool $random = false;


    public function mount(Request $request, $postNr, $related, $random = null)
    {
        $this->postNr = $postNr;
        $this->related = $related;

        if ($random) {
            $this->random = true;
        }


        $profile = getActiveProfile();

        // SECURITY: If a profile is active, validate the user has access to it
        // This prevents session manipulation while allowing public access (null profile)
        if ($profile) {
            \App\Helpers\ProfileAuthorizationHelper::authorize($profile);
        }

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

        $skipLocationFilter = false;

        if ($location) {
            // If no division and no city as location set
            if (!$location->division && !$location->city) {
                $categoryable_id = Location::find($location->id)->country->id;
                $categoryable_type = Country::class;
                // Include also all other countries if $related is set in view
                if ($related) {
                    $categoryable_id = Country::pluck('id');
                } else {
                    $categoryable_id = [$categoryable_id];
                }
                // Division without city is set as location
            } elseif ($location->division && !$location->city) {
                $categoryable_id = Location::find($location->id)->division->id;
                $categoryable_type = Division::class;
                // Include also all other divisions in the same country if $related is set in view
                if ($related) {
                    $categoryable_id = Division::find($categoryable_id)->parent->divisions->pluck('id');
                } else {
                    $categoryable_id = [$categoryable_id];
                }
                // City is set as location
            } elseif ($location->city) {
                $categoryable_id = Location::find($location->id)->city->id;
                $categoryable_type = City::class;
                // Include also all other cities in the same division if $related is set in view
                if ($related) {
                    $categoryable_id = City::find($categoryable_id)->parent->cities->pluck('id');
                } else {
                    $categoryable_id = [$categoryable_id];
                }
            }
            // No matching location is set - skip location filtering
        } else {
            $skipLocationFilter = true;
            $categoryable_id = [];
            $categoryable_type = '';
        }


        // TODO: check what happens when multiple locations per user are used!

        $locale = App::getLocale();
        $categoryTypes = ['App\Models\ImagePost', 'App\Models\ImagePost\\' . $locale];

        $post =
            Post::with([
                'postable' => function ($query) {
                    $query->select(['id', 'name']);
                },
                'category' => function ($query) use ($categoryable_id, $categoryable_type, $skipLocationFilter, $categoryTypes) {
                    $query->whereIn('type', $categoryTypes);
                    if (!$skipLocationFilter && !empty($categoryable_id)) {
                        $query->where(function ($query) use ($categoryable_id, $categoryable_type) {
                            $query->where(function ($query) use ($categoryable_id, $categoryable_type) {
                                $query
                                    ->whereIn('categoryable_id', $categoryable_id)
                                    ->where('categoryable_type', $categoryable_type);
                            })->orWhere(function ($query) {
                                // Also include categories with no location set
                                $query->whereNull('categoryable_id')
                                      ->whereNull('categoryable_type');
                            });
                        });
                    }
                },
                'translations' => function ($query) {
                    $query->where('locale', App::getLocale());
                },
                'author',
                'media',
                ])
                ->whereHas('category', function ($query) use ($categoryable_id, $categoryable_type, $skipLocationFilter, $categoryTypes) {
                    $query->whereIn('type', $categoryTypes);
                    if (!$skipLocationFilter && !empty($categoryable_id)) {
                        $query->where(function ($query) use ($categoryable_id, $categoryable_type) {
                            $query->where(function ($query) use ($categoryable_id, $categoryable_type) {
                                $query
                                    ->whereIn('categoryable_id', $categoryable_id)
                                    ->where('categoryable_type', $categoryable_type);
                            })->orWhere(function ($query) {
                                // Also include categories with no location set
                                $query->whereNull('categoryable_id')
                                      ->whereNull('categoryable_type');
                            });
                        });
                    }
                })
                ->whereHas('translations', function ($query) {
                    $query
                    ->where('locale', App::getLocale())
                    ->whereDate('from', '<=', now())
                    ->where(function ($query) {
                        $query->whereDate('till', '>', now())->orWhereNull('till');
                    })
                    ->orderBy('updated_at', 'desc');
                });

        // Apply random or sorted ordering
        if ($this->random) {
            $post = $post->inRandomOrder()->get();
        } else {
            $post = $post->get()->sortByDesc(function ($query) {
                if (isset($query->translations)) {
                    return $query->translations->first()->updated_at;
                };
            })->values();       // Use values() method to reset the collection keys after sortBy
        }

        $lastNr = $post->count() - 1;

        if ($postNr > $lastNr || $post->isEmpty()) {
            $post = null;
            $this->post = null;
        } else {
            $post = $post[$postNr];
        }

        if ($post && isset($post->translations) && $post->translations->isNotEmpty()) {
            $translation = $post->translations->first();
            $this->post = $translation;
            $this->post['slug'] = $translation->slug;
            $this->post['from'] = $translation->from;

            $category = Category::find($post->category_id);
            $categoryTranslation = $category ? $category->translations->where('locale', App::getLocale())->first() : null;
            $this->post['category'] = $categoryTranslation ? $categoryTranslation->name : '';

            $this->post['author'] = $post->author ? $post->author->name : timebank_config('posts.site-content-writer');
            $this->post['author_id'] = $post->author ? $post->author->id : null;
            $this->post['author_profile_photo_path'] = $post->author && $post->author->profile_photo_path ? $post->author->profile_photo_path : null;
            $this->post['post_id'] = $post->id;

            if ($post->media && $post->media->isNotEmpty()) {
                $this->media = Post::find($post->id)->getFirstMedia('posts');

                // Get media owner and caption
                $this->post['media_owner'] = $this->media->getCustomProperty('owner', '');
                $captionKey = 'caption-' . App::getLocale();
                $this->post['media_caption'] = $this->media->getCustomProperty($captionKey, '');
            }
        }
    }


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