<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Models\User;
use App\Models\UserTrustedDevice;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;

class AuthenticatedSessionController extends Controller
{
    /**
     * Display the login view
     */
    public function create(): View
    {
        return view('auth.login');
    }

    /**
     * Handle an incoming authentication request
     */
    public function store(LoginRequest $request): RedirectResponse
    {
        // Batch common auth settings
        $settings = [
            '2fa_enabled' => get_setting('two_factor_auth', false),
            'allow_remember' => get_setting('session_allow_remember_me', true),
            'remember_duration' => get_setting('session_remember_me_duration', 30),
            'single_session' => get_setting('session_single_session', false),
        ];

        $credentials = $request->only('email', 'password');
        $remember = $settings['allow_remember'] && $request->boolean('remember');

        // Check if 2FA is enabled globally
        if ($settings['2fa_enabled']) {
            if (Auth::validate($credentials)) {
                $user = User::where('email', $request->email)->first();

                // Check Trust Device bypass (Secure check)
                $cookieValue = $request->cookie('2fa_trust_device');
                $trustedBypass = false;

                if ($cookieValue && str_contains($cookieValue, '|')) {
                    $parts = explode('|', $cookieValue, 2);

                    if (count($parts) === 2 && ! empty($parts[0]) && ! empty($parts[1])) {
                        [$uuid, $secret] = $parts;

                        $trust = UserTrustedDevice::where('user_id', $user->id)
                            ->where('device_id', $uuid)
                            ->where('expires_at', '>', now())
                            ->first();

                        if ($trust && hash_equals($trust->token, hash('sha256', $secret))) {
                            $trustedBypass = true;
                        }
                    }
                }

                if ($trustedBypass) {
                    Auth::attempt($credentials, $remember);
                    $request->session()->regenerate();
                    $user->update(['last_session_id' => session()->getId()]);

                    return redirect()->intended(route('dashboard', absolute: false));
                }

                // Generate & Send OTP
                TwoFactorController::generateAndSendOtp($user);
                session(['auth.2fa_remember' => $remember]);

                return redirect()->route('2fa.index');
            }
        }

        // Authenticate user credentials normally
        $request->authenticate();
        $request->session()->regenerate();

        /** @var User $user */
        $user = Auth::user();
        $user->update(['last_session_id' => session()->getId()]);

        // Custom duration Remember Me
        if ($remember) {
            $minutes = 60 * 24 * $settings['remember_duration'];
            cookie()->queue(
                cookie(
                    name: Auth::getRecallerName(),
                    value: cookie()->get(Auth::getRecallerName()),
                    minutes: $minutes,
                    httpOnly: true,
                    secure: app()->environment('production'),
                )
            );
        }

        // SINGLE SESSION ENFORCEMENT
        if ($settings['single_session']) {
            Auth::logoutOtherDevices($request->password);
        }

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

    /**
     * Destroy an authenticated session
     */
    public function destroy(Request $request): RedirectResponse
    {
        Auth::guard('web')->logout();

        // Invalidate session for security
        $request->session()->invalidate();

        // Regenerate CSRF token
        $request->session()->regenerateToken();

        // Redirect to homepage
        return redirect('/');
    }
}
