<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Jobs\SyncDiscordRoleForUser;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\DB;
use Laravel\Socialite\Facades\Socialite;

class DiscordAuthController extends Controller
{
    public function redirect(): RedirectResponse
    {
        return Socialite::driver('discord')
            ->scopes(['identify', 'guilds.members.read'])
            ->redirect();
    }

    public function callback(): RedirectResponse
    {
        $discordUser = Socialite::driver('discord')->user();

        $user = DB::transaction(function () use ($discordUser) {
            $user = User::query()->firstOrNew(['discord_id' => $discordUser->getId()]);

            $isNew = ! $user->exists;

            $user->name = $discordUser->getNickname() ?? $discordUser->getName() ?? $discordUser->getEmail() ?? 'Player';
            $user->email = $discordUser->getEmail() ?? $discordUser->getId().'@discord.local';
            $user->discord_avatar = $discordUser->getAvatar();
            $user->save();

            if ($isNew) {
                $user->assignRole('player');
            }

            return $user;
        });

        // session_regenerate_id() equivalent, closing the session-fixation
        // gap present in the legacy `go_login`/`login` actions.
        request()->session()->regenerate();

        auth()->login($user, remember: true);

        SyncDiscordRoleForUser::dispatch($user);

        if ($user->two_factor_confirmed_at !== null) {
            return redirect()->route('two-factor.challenge');
        }

        return redirect()->intended(route('dashboard'));
    }
}
