<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\SocialAccount;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Laravel\Socialite\Facades\Socialite;

class SocialAuthController extends Controller
{
    /**
     * Supported OAuth providers.
     * Add new providers here to enable them.
     *
     * @var array<string>
     */
    protected array $supportedProviders = [
        'google',
        // 'facebook',
        // 'microsoft',
        // 'github',
    ];

    /**
     * Redirect to OAuth provider.
     */
    public function redirect(string $provider): RedirectResponse
    {
        if (! $this->isProviderSupported($provider)) {
            return redirect()->route('login')
                ->withErrors(['error' => 'Proveedor de autenticación no soportado.']);
        }

        return Socialite::driver($provider)->redirect();
    }

    /**
     * Handle callback from OAuth provider.
     */
    public function callback(string $provider): RedirectResponse
    {
        if (! $this->isProviderSupported($provider)) {
            return redirect()->route('login')
                ->withErrors(['error' => 'Proveedor de autenticación no soportado.']);
        }

        try {
            $socialUser = Socialite::driver($provider)->user();
        } catch (\Exception $e) {
            Log::error('Social auth error', [
                'provider' => $provider,
                'error' => $e->getMessage(),
            ]);

            return redirect()->route('login')
                ->withErrors(['error' => 'Error al autenticar con '.ucfirst($provider).'. Por favor, intenta de nuevo.']);
        }

        // Find or create user
        $user = $this->findOrCreateUser($socialUser, $provider);

        // Link social account if not already linked
        $this->linkSocialAccount($user, $socialUser, $provider);

        // Log in the user
        Auth::login($user, remember: true);

        // Redirect based on role
        return $this->redirectUser($user);
    }

    /**
     * Find existing user or create a new one.
     */
    protected function findOrCreateUser($socialUser, string $provider): User
    {
        // First, check if we have a social account linked
        $socialAccount = SocialAccount::where('provider', $provider)
            ->where('provider_id', $socialUser->getId())
            ->first();

        if ($socialAccount) {
            return $socialAccount->user;
        }

        // Check if user exists with same email
        $user = User::where('email', $socialUser->getEmail())->first();

        if ($user) {
            return $user;
        }

        // Create new user
        return User::create([
            'name' => $socialUser->getName() ?? $socialUser->getNickname() ?? 'Usuario',
            'email' => $socialUser->getEmail(),
            'email_verified_at' => now(), // Email from OAuth is considered verified
            'password' => Hash::make(Str::random(32)), // Random password since they use OAuth
            'avatar' => $socialUser->getAvatar(),
        ]);
    }

    /**
     * Link social account to user.
     */
    protected function linkSocialAccount(User $user, $socialUser, string $provider): void
    {
        $user->socialAccounts()->updateOrCreate(
            [
                'provider' => $provider,
                'provider_id' => $socialUser->getId(),
            ],
            [
                'provider_token' => $socialUser->token,
                'provider_refresh_token' => $socialUser->refreshToken ?? null,
                'token_expires_at' => $socialUser->expiresIn
                    ? now()->addSeconds($socialUser->expiresIn)
                    : null,
            ]
        );
    }

    /**
     * Redirect user based on their role.
     */
    protected function redirectUser(User $user): RedirectResponse
    {
        if ($user->hasRole('admin')) {
            return redirect('/admin/dashboard');
        }

        // Curator and regular users go to home
        return redirect('/');
    }

    /**
     * Check if provider is supported.
     */
    protected function isProviderSupported(string $provider): bool
    {
        return in_array($provider, $this->supportedProviders);
    }
}
