<?php

namespace App\Services;

use App\Models\User;
use App\Models\ActivityLog;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Carbon\Carbon;

class AuthService
{
    public function attemptLogin(string $email, string $password, string $ip): array
    {
        $key = 'login:' . $ip . ':' . $email;

        if (RateLimiter::tooManyAttempts($key, 5)) {
            $seconds = RateLimiter::availableIn($key);
            return ['success' => false, 'error' => "Too many attempts. Try again in {$seconds}s.", 'locked' => true];
        }

        $user = User::where('email', $email)->first();

        if (!$user || !Hash::check($password, $user->password)) {
            RateLimiter::hit($key, 300);
            $this->logAttempt($email, $ip, false);
            return ['success' => false, 'error' => 'Invalid credentials.'];
        }

        if (!$user->is_active) {
            return ['success' => false, 'error' => 'Account is deactivated.'];
        }

        RateLimiter::clear($key);
        $this->logAttempt($email, $ip, true);

        $user->update(['last_login_at' => now(), 'last_login_ip' => $ip]);
        ActivityLog::record('login', 'User', $user->id);

        if ($user->two_fa_enabled) {
            $this->sendTwoFaCode($user);
            return ['success' => true, 'requires_2fa' => true, 'user_id' => $user->id];
        }

        return ['success' => true, 'requires_2fa' => false, 'user' => $user];
    }

    public function sendTwoFaCode(User $user): void
    {
        $code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
        $user->update([
            'two_fa_code'       => Hash::make($code),
            'two_fa_expires_at' => Carbon::now()->addMinutes(10),
        ]);

        // Send via email
        \Mail::raw("Your EduSmart verification code is: {$code}. Valid for 10 minutes.", function ($m) use ($user) {
            $m->to($user->email)->subject('Your 2FA Code - EduSmart');
        });
    }

    public function verifyTwoFa(int $userId, string $code): bool
    {
        $user = User::findOrFail($userId);

        if (!$user->two_fa_code || Carbon::now()->isAfter($user->two_fa_expires_at)) {
            return false;
        }

        if (!Hash::check($code, $user->two_fa_code)) {
            return false;
        }

        $user->update(['two_fa_code' => null, 'two_fa_expires_at' => null]);
        return true;
    }

    private function logAttempt(string $email, string $ip, bool $success): void
    {
        try {
            \DB::table('login_attempts')->insert([
                'email'        => $email,
                'ip_address'   => $ip,
                'successful'   => $success,
                'attempted_at' => now(),
            ]);
        } catch (\Exception $e) {
            // Table may not exist, skip silently
        }
    }
}
