<?php

namespace App\Http\Controllers\Auth;

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

class GoogleAuthController extends Controller
{
    /**
     * Check if Google login is enabled
     */
    private function isGoogleLoginEnabled(): bool
    {
        return DB::table('settings')->where('key', 'google_login_enabled')->value('value') === '1';
    }

    /**
     * Configure Socialite with database settings
     */
    private function configureGoogleOAuth(): void
    {
        $clientId = DB::table('settings')->where('key', 'google_client_id')->value('value');
        $clientSecret = DB::table('settings')->where('key', 'google_client_secret')->value('value');
        $redirectUri = DB::table('settings')->where('key', 'google_redirect_uri')->value('value');

        if ($clientId) {
            config(['services.google.client_id' => $clientId]);
        }
        if ($clientSecret) {
            config(['services.google.client_secret' => $clientSecret]);
        }
        if ($redirectUri) {
            config(['services.google.redirect' => $redirectUri]);
        }
    }

    /**
     * Redirect to Google OAuth page
     */
    public function redirect(): RedirectResponse
    {
        if (!$this->isGoogleLoginEnabled()) {
            return redirect()->route('login')->with('error', 'Google login is currently disabled.');
        }

        $this->configureGoogleOAuth();

        return Socialite::driver('google')->redirect();
    }

    /**
     * Check if activation is required
     */
    private function isActivationRequired(): bool
    {
        return DB::table('settings')->where('key', 'activation_required')->value('value') === '1';
    }

    /**
     * Handle Google OAuth callback
     */
    public function callback(): RedirectResponse
    {
        if (!$this->isGoogleLoginEnabled()) {
            return redirect()->route('login')->with('error', 'Google login is currently disabled.');
        }

        $this->configureGoogleOAuth();

        try {
            $googleUser = Socialite::driver('google')->user();
            
            // Check if user exists with this google_id
            $user = User::where('google_id', $googleUser->getId())->first();
            $isNewUser = false;
            
            if (!$user) {
                // Check if user exists with this email
                $user = User::where('email', $googleUser->getEmail())->first();
                
                if ($user) {
                    // Link Google account to existing user
                    $user->update(['google_id' => $googleUser->getId()]);
                } else {
                    // Create new user (without password)
                    $user = $this->createUser($googleUser);
                    $isNewUser = true;
                }
            }
            
            // Check if user is activated
            if (!$user->is_activated) {
                // Resend activation email and redirect to pending page
                $activationController = new ActivationController();
                $activationController->sendActivationEmail($user);
                
                session(['activation_email' => $user->email]);
                
                return redirect()->route('activation.pending');
            }
            
            // For users who are activated but don't have password yet (Google OAuth users)
            if (empty($user->passwd) && $user->password_setup_token) {
                return redirect()->route('password.setup', ['token' => $user->password_setup_token]);
            }
            
            // Log the user in
            Auth::login($user, true);
            
            // Redirect based on role
            if ($user->role === 'admin') {
                return redirect()->route('admin.dashboard');
            }
            
            return redirect()->route('dashboard');
            
        } catch (\Exception $e) {
            \Log::error('Google OAuth error: ' . $e->getMessage(), [
                'exception' => get_class($e),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'trace' => $e->getTraceAsString(),
            ]);
            return redirect()->route('login')->with('error', 'Failed to authenticate with Google: ' . $e->getMessage());
        }
    }

    /**
     * Create a new user from Google data
     */
    private function createUser($googleUser): User
    {
        $name = $this->generateUniqueUsername($googleUser->getName());
        $activationRequired = $this->isActivationRequired();

        // Use pw.sql adduser stored procedure (handles userid: 1024, 1040, 1056, ...)
        DB::statement(
            'CALL adduser(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
            [
                $name,
                '', // Empty password for Google OAuth users
                '',
                '',
                $googleUser->getName(),
                '',
                $googleUser->getEmail(),
                '',
                '',
                '',
                '',
                '',
                '',
                0,
                '2000-01-01',
                '',
                '',
            ]
        );

        // Update with Laravel-specific columns
        $updateData = [
            'google_id' => $googleUser->getId(),
            'role' => 'player',
            'photo' => $googleUser->getAvatar(),
            'is_activated' => !$activationRequired,
        ];

        if ($activationRequired) {
            $updateData['activation_token'] = Str::random(64);
            $updateData['activation_sent_at'] = now();
        } else {
            $updateData['password_setup_token'] = Str::random(64);
            $updateData['password_setup_expires_at'] = now()->addHours(24);
        }

        User::where('name', $name)->update($updateData);

        return User::where('name', $name)->first();
    }

    /**
     * Generate a unique username
     */
    private function generateUniqueUsername(string $name): string
    {
        // Remove all non-alphanumeric characters and convert to lowercase
        $baseUsername = strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $name));
        $username = $baseUsername;
        $counter = 1;
        
        while (User::where('name', $username)->exists()) {
            $username = $baseUsername . $counter;
            $counter++;
        }
        
        return $username;
    }
}
