<?php

namespace App\Http\Controllers;

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

class CallController extends Controller
{
    public function showById($id)
    {
        $call = Call::withTrashed()->with([
            'callable',
            'translations' => function ($query) {
                $query->where('locale', App::getLocale());
            },
            'tag.contexts.category.translations',
            'tag.contexts.category.ancestors.translations',
            'location.city.translations',
            'location.district.translations',
            'location.country.translations',
            'location.division.translations',
            'loveReactant.reactionCounters',
        ])->findOrFail($id);

        $activeProfileType = session('activeProfileType');
        $activeProfileId   = session('activeProfileId');
        $isAdmin    = $activeProfileType === \App\Models\Admin::class;
        $isCallable = $activeProfileType === $call->callable_type
            && (int) $activeProfileId === (int) $call->callable_id;

        // Deleted calls are only visible to admins and the callable itself
        $isDeleted = $call->trashed();
        if ($isDeleted && !$isAdmin && !$isCallable) {
            return view('calls.unavailable');
        }

        // Blocked calls are only visible to admins and the callable itself
        if ($call->is_suppressed && !$isAdmin && !$isCallable) {
            return view('calls.unavailable');
        }

        // Paused calls are only visible to admins and the callable itself
        if ($call->is_paused && !$isAdmin && !$isCallable) {
            return view('calls.unavailable');
        }

        // Guests cannot view private calls
        if (!$call->is_public && !Auth::check()) {
            return redirect()->route('login')
                ->with('status', __('This call is private. Please log in to view it.'));
        }

        // Expired calls are only visible to the owner and admins
        $isExpired = $call->till !== null && $call->till->isPast();
        if ($isExpired && !$isCallable && !$isAdmin) {
            return view('calls.unavailable');
        }

        $locale = App::getLocale();

        // Build category hierarchy
        $tagCategory = $call->tag?->contexts->first()?->category;
        $tagColor    = $tagCategory?->relatedColor ?? 'gray';
        $tagCategories = [];
        if ($tagCategory) {
            foreach ($tagCategory->ancestorsAndSelf()->get()->reverse() as $cat) {
                $name = $cat->translations->firstWhere('locale', $locale)?->name
                    ?? $cat->translations->first()?->name
                    ?? '';
                if ($name) {
                    $tagCategories[] = ['name' => $name, 'color' => $cat->relatedColor ?? 'gray'];
                }
            }
        }

        // Build callable profile's location short string (city first, fallback to division or country)
        $callableLocation = null;
        if ($call->callable && method_exists($call->callable, 'locations')) {
            $firstLoc = $call->callable->locations()->with(['city.translations', 'division.translations', 'country.translations'])->first();
            if ($firstLoc) {
                $cCity     = optional($firstLoc->city?->translations->first())->name;
                $cDivision = optional($firstLoc->division?->translations->first())->name;
                $cCountry  = optional($firstLoc->country?->translations->first())->name;
                $callableLocation = $cCity ?? $cDivision ?? $cCountry ?: null;
            }
        }

        // Build call exchange location: "City District, Division, COUNTRY_CODE"
        $callLocation = null;
        if ($call->location) {
            $loc = $call->location;
            $parts = [];
            $cityPart = null;
            if ($loc->city) {
                $cityPart = optional($loc->city->translations->first())->name;
            }
            if ($loc->district) {
                $districtName = optional($loc->district->translations->first())->name;
                $cityPart = $cityPart ? $cityPart . ' ' . $districtName : $districtName;
            }
            if ($cityPart) $parts[] = $cityPart;
            if ($loc->division) {
                $divisionName = optional($loc->division->translations->first())->name;
                if ($divisionName) $parts[] = $divisionName;
            }
            if ($loc->country && $loc->country->code !== 'XX') {
                $parts[] = strtoupper($loc->country->code);
            } elseif ($loc->country && $loc->country->code === 'XX') {
                $parts[] = __('Location not specified');
            }
            $callLocation = $parts ? implode(', ', $parts) : null;
        }

        // Determine whether to show the expiry badge (within configured warning window)
        $expiryWarningDays = timebank_config('calls.expiry_warning_days', 7);
        $expiryBadgeText = null;
        if ($call->till && $expiryWarningDays !== null) {
            $daysLeft = (int) now()->startOfDay()->diffInDays($call->till->startOfDay(), false);
            if ($daysLeft <= $expiryWarningDays) {
                if ($daysLeft <= 0) {
                    $expiryBadgeText = __('Expires today');
                } elseif ($daysLeft === 1) {
                    $expiryBadgeText = __('Expires tomorrow');
                } else {
                    $expiryBadgeText = __('Expires in :days days', ['days' => $daysLeft]);
                }
            }
        }

        $callableType = $call->callable ? strtolower(class_basename($call->callable)) : null;
        $viewName = Auth::check() ? 'calls.show' : 'calls.show-guest';
        return view($viewName, compact('call', 'tagColor', 'tagCategories', 'callableType', 'callableLocation', 'callLocation', 'expiryBadgeText', 'isExpired', 'isDeleted', 'isAdmin'));
    }

    public function manage()
    {
        $activeProfileType = getActiveProfileType();
        $allowedTypes = [
            'User', 'Organization', 'Bank', 'Admin',
        ];

        if (!$activeProfileType || !in_array($activeProfileType, $allowedTypes)) {
            abort(403, __('You do not have access to this page.'));
        }

        return view('calls.manage');
    }
}
