<?php

namespace App\Http\Controllers;

use App\Models\Achievement;
use App\Models\Aircraft;
use App\Models\Alliance;
use App\Models\Continent;
use App\Models\Country;
use App\Models\User;
use App\Models\UserFlight;
use App\Http\Resources\UserFlightResource;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
use Inertia\Inertia;

class UserProfileController extends Controller
{
    public function currentUserCanEditProfile(User $profileUser){
        return auth()->check() && (auth()->id() === $profileUser->id || auth()->user()->hasRole('admin'));
    }

    public function index(){
        if (auth()->check()) {
            $user = auth()->user();
            $defaultPage = $user->resolved_settings['default_login_page'];

            $route = match ($defaultPage) {
                'feed_first' => $user->following()->count() > 0 ? 'feed' : 'profile.view',
                'feed' => 'feed',
                'profile' => 'profile.view',
                'dashboard' => 'dashboard',
            };

            $args = $route == 'profile.view' ? $user->name : null;

            return redirect()->route($route, $args);
        }
        return redirect()->route('splash');
    }

    public function profileData(User $user, string $view, ?int $selectedFlightId = null) : array {
        return [
            'user' => $user,
            'canView' =>  Gate::allows('viewProfileData', $user),
            'canEdit' => $this->currentUserCanEditProfile($user),
            'initialView' => $view,
            'selectedFlightId' => $selectedFlightId,
            'followStatus' => auth()->check() ? auth()->user()->followStatus($user) : 'none',
            'flightCount' => $user->departedFlights()->count(),
        ];
    }

    public function departureBoard(User $user, ?UserFlight $flight = null){
        $profileData = $this->profileData($user, 'board', $flight?->id);
        return Inertia::render('UserProfile', $profileData);
    }

    public function map(User $user){
        $profileData = $this->profileData($user, 'map');
        return Inertia::render('UserProfile', $profileData);
    }

    public function boardingPasses(User $user){
        $profileData = $this->profileData($user, 'passes');
        return Inertia::render('UserProfile', $profileData);
    }

    public function view(User $user, ?string $page = null)
    {
        $loggedInUser = auth()->user();
        $defaultView = $page ?: ($loggedInUser ? $loggedInUser->resolved_settings['default_profile_view'] : 'map');

        return match($defaultView) {
            'boarding-passes' => $this->boardingPasses($user),
            'map' => $this->map($user),
            'departure-board' => $this->departureBoard($user),
            'achievements' => redirect()->route('profile.achievements', $user->name),
        };

    }

    public function flight(User $user, UserFlight $userFlight)
    {
        if($userFlight->user_id !== $user->id){
            abort(404);
        }

        return Inertia::render('UserFlight', [
            'flightCount' => $user->departedFlights()->count(),
            'flight' => $userFlight->snapshot($userFlight->id),
            'canEdit' => $this->currentUserCanEditProfile($user),
            'canView' => Gate::allows('viewProfileData', $user),
            'user' => $user,
            'followStatus' => auth()->check() ? auth()->user()->followStatus($user) : 'none',
        ]);
    }


    public function achievements(User $user)
    {
        $canView =  Gate::allows('viewProfileData', $user);

        $achievements = Achievement::with(['category', 'difficulty'])
            ->get()
            ->groupBy(fn(Achievement $a) => $a->category->name)
            ->map(fn($group) => $group->sortBy('sort_order')->values());

        $userAchievements = $user->achievements()
            ->with('achievement')
            ->select(['achievement_id', 'progress'])
            ->orderBy('achievement_id')
            ->get()
            ->keyBy('achievement_id');

        $unlockedByCategory = $achievements->map(fn($group) =>
            $group->filter(fn($a) => $userAchievements->get($a->id)?->unlocked)->count()
        );

        $unlockedCount = $userAchievements->filter(fn($ua) => $ua->unlocked)->count();
        return Inertia::render('UserAchievements', [
            'canView'          => $canView,
            'user'             => $user,
            'canEdit'          => auth()->id() === $user->id,
            'followStatus' => auth()->check() ? auth()->user()->followStatus($user) : 'none',
            'achievements'     => $canView ? $achievements : [],
            'userAchievements' => $canView ? $userAchievements : [],
            'loggedInUser'     => auth()->user(),
            'unlockedCount' => $unlockedCount,
            'unlockedByCategory' => $unlockedByCategory,
            'totalAchievements' => $achievements->flatten()->count(),
        ]);
    }

    public function copyFlight(UserFlight $flight)
    {
        $loggedInUser = auth()->user();

        $exists = UserFlight::where('user_id', $loggedInUser->id)
            ->where('departure_airport_id', $flight->departure_airport_id)
            ->where('arrival_airport_id', $flight->arrival_airport_id)
            ->exists();

        if ($exists) {
            return back()->withErrors(['flight' => 'You already have a flight logged between these airports on this date.']);
        }

        $newFlight = $flight->replicate();
        $newFlight->user_id = $loggedInUser->id;
        $newFlight->save();

        return redirect()->route('flights.edit', ['flight' => $newFlight->id]);
    }

    public function achievement(User $user, Achievement $achievement)
    {
        $regions = match($achievement->internal_name){
            'fun_challenges.australian_states' => Country::whereCode('AU')->first()->sortedRegions(),
            'fun_challenges.chinese_provinces' =>  Country::whereCode('CN')->first()->sortedRegions(),
            'fun_challenges.canadian_provinces' =>  Country::whereCode('CA')->first()->sortedRegions(),
            'fun_challenges.brazilian_states' =>  Country::whereCode('BR')->first()->sortedRegions(),
            'fun_challenges.us_states' => Country::whereCode('US')->first()->sortedRegions(),
            default => [],
        };

        $allianceInternalName = match($achievement->internal_name){
            'airlines_alliances.all_star_alliance' => 'star_alliance',
            'airlines_alliances.all_oneworld'      => 'oneworld',
            'airlines_alliances.all_skyteam'       => 'skyteam',
            'airlines_alliances.all_vanilla_alliance'       => 'vanilla_alliance',
            default => null,
        };

        $continents = match($achievement->internal_name){
            'countries_continents.all_continent_pairs_one_way', 'countries_continents.all_continent_pairs_both_ways' => Continent::all()->toArray(),
            default => [],
        };

        $alliance = null;
        $airlines = [];

        if ($allianceInternalName) {
            $alliance = Alliance::where('internal_name', $allianceInternalName)
                ->with('airlines')
                ->firstOrFail();
            $airlines = $alliance->airlines()->with(['country', 'mergedFrom'])->orderBy('name')->get();
        }

        $aircraftFamilies = match($achievement->internal_name){
            'aircraft.all_boeing_7x7' => Aircraft::BOEING_FAMILIES,
            'aircraft.all_airbus_a3xx' => Aircraft::AIRBUS_FAMILIES,
            'aircraft.all_boeing_737' => Aircraft::BOEING_737_VARIANTS,
            default => [],
        };

        $canView = Gate::allows('viewProfileData', $user);

        return Inertia::render('Profile/UserAchievement', [
            'user'            => $user,
            'achievement'     => $achievement,
            'loggedInUser'    => auth()->user(),
            'userAchievement' => $canView ? $user->achievements()->where('achievement_id', $achievement->id)->first() : null,
            'followStatus' => auth()->check() ? auth()->user()->followStatus($user) : 'none',
            'regions'         => $regions,
            'alliance'        => $alliance,
            'airlines'        => $airlines,
            'continents'      => $continents,
            'aircraft_families' => $aircraftFamilies,
            'achievementCount' => $user->unlockedAchievements()->count(),
            'canView' => $canView,
        ]);
    }
}
