<?php

namespace App\Http\Livewire\Calls;

use App\Models\Call;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;

class ProfileCalls
{
    public static function getCallsForProfile($profile, bool $showPrivate = false): Collection
    {
        $calls = 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('callable_type', get_class($profile))
            ->where('callable_id', $profile->id)
            ->when(!$showPrivate, fn ($q) => $q->where('is_public', true))
            ->where('is_paused', false)
            ->where('is_suppressed', false)
            ->whereNull('deleted_at')
            ->where(fn ($q) => $q->whereNull('till')->orWhere('till', '>=', now()))
            ->orderBy('till')
            ->get();

        $locale = App::getLocale();

        return $calls->map(function (Call $model) use ($locale) {
            $translation = $model->translations->firstWhere('locale', $locale)
                ?? $model->translations->first();

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

            $locationStr = null;
            if ($model->location) {
                $loc   = $model->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',
                        ];
                    }
                }
            }

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

    public static function buildCallableLocation($callable): ?string
    {
        if (!$callable || !method_exists($callable, 'locations')) {
            return null;
        }

        $firstLoc = $callable->locations->first();
        if (!$firstLoc) {
            return null;
        }

        $cCity     = optional($firstLoc->city?->translations->first())->name;
        $cDivision = optional($firstLoc->division?->translations->first())->name;
        $cCountry  = optional($firstLoc->country?->translations->first())->name;

        return $cCity ?? $cDivision ?? $cCountry ?? null;
    }

    public static function buildExpiryBadgeText($till): ?string
    {
        if (!$till) {
            return null;
        }

        $expiryWarningDays = timebank_config('calls.expiry_warning_days', 7);
        if ($expiryWarningDays === null) {
            return null;
        }

        $daysLeft = (int) now()->startOfDay()->diffInDays(\Carbon\Carbon::parse($till)->startOfDay(), false);

        if ($daysLeft > $expiryWarningDays) {
            return null;
        }

        if ($daysLeft <= 0) {
            return __('Expires today');
        } elseif ($daysLeft === 1) {
            return __('Expires tomorrow');
        } else {
            return __('Expires in :days days', ['days' => $daysLeft]);
        }
    }
}
