<?php

namespace App\Services;

use App\Models\TwoFactorToken;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use PragmaRX\Google2FA\Google2FA;

class TwoFactorAuthService
{
    /**
     * مثيل من Google2FA.
     *
     * @var \PragmaRX\Google2FA\Google2FA
     */
    protected $google2fa;

    /**
     * إنشاء مثيل جديد من الخدمة.
     *
     * @return void
     */
    public function __construct()
    {
        $this->google2fa = new Google2FA();
    }

    /**
     * إنشاء سر المصادقة الثنائية للمستخدم.
     *
     * @param \App\Models\User $user
     * @return string
     */
    public function generateSecretKey(User $user)
    {
        $secretKey = $this->google2fa->generateSecretKey();

        $user->two_factor_secret = encrypt($secretKey);
        $user->save();

        return $secretKey;
    }

    /**
     * إنشاء رموز الاسترداد للمستخدم.
     *
     * @param \App\Models\User $user
     * @param int $count
     * @return array
     */
    public function generateRecoveryCodes(User $user, $count = 8)
    {
        $recoveryCodes = [];

        for ($i = 0; $i < $count; $i++) {
            $recoveryCodes[] = $this->generateRecoveryCode();
        }

        $user->two_factor_recovery_codes = encrypt(json_encode($recoveryCodes));
        $user->save();

        return $recoveryCodes;
    }

    /**
     * إنشاء رمز استرداد واحد.
     *
     * @return string
     */
    protected function generateRecoveryCode()
    {
        return bin2hex(random_bytes(8));
    }

    /**
     * التحقق من رمز المصادقة الثنائية.
     *
     * @param \App\Models\User $user
     * @param string $code
     * @return bool
     */
    public function verifyCode(User $user, $code)
    {
        if (!$user->two_factor_secret) {
            return false;
        }

        $secretKey = decrypt($user->two_factor_secret);

        return $this->google2fa->verifyKey($secretKey, $code);
    }

    /**
     * التحقق من رمز الاسترداد.
     *
     * @param \App\Models\User $user
     * @param string $code
     * @return bool
     */
    public function verifyRecoveryCode(User $user, $code)
    {
        if (!$user->two_factor_recovery_codes) {
            return false;
        }

        $recoveryCodes = json_decode(decrypt($user->two_factor_recovery_codes), true);

        $index = array_search($code, $recoveryCodes);

        if ($index !== false) {
            // إزالة الرمز المستخدم
            unset($recoveryCodes[$index]);
            $user->two_factor_recovery_codes = encrypt(json_encode(array_values($recoveryCodes)));
            $user->save();

            return true;
        }

        return false;
    }

    /**
     * إنشاء رمز مصادقة ثنائية مؤقت للمستخدم.
     *
     * @param \App\Models\User $user
     * @param int $expiresInMinutes
     * @return \App\Models\TwoFactorToken
     */
    public function generateToken(User $user, $expiresInMinutes = 10)
    {
        return $user->generateTwoFactorToken($expiresInMinutes);
    }

    /**
     * التحقق من رمز المصادقة الثنائية المؤقت.
     *
     * @param \App\Models\User $user
     * @param string $token
     * @return bool
     */
    public function verifyToken(User $user, $token)
    {
        return $user->verifyTwoFactorToken($token);
    }

    /**
     * تفعيل المصادقة الثنائية للمستخدم.
     *
     * @param \App\Models\User $user
     * @param string $code
     * @return bool
     */
    public function enable(User $user, $code)
    {
        if ($this->verifyCode($user, $code)) {
            $user->two_factor_enabled = true;
            $user->two_factor_confirmed_at = now();
            $user->save();

            // تسجيل النشاط
            \App\Models\ActivityLog::log(
                'enable_2fa',
                'تم تفعيل المصادقة الثنائية للمستخدم ' . $user->name,
                $user
            );

            return true;
        }

        return false;
    }

    /**
     * تعطيل المصادقة الثنائية للمستخدم.
     *
     * @param \App\Models\User $user
     * @return bool
     */
    public function disable(User $user)
    {
        $user->two_factor_enabled = false;
        $user->two_factor_confirmed_at = null;
        $user->save();

        // تسجيل النشاط
        \App\Models\ActivityLog::log(
            'disable_2fa',
            'تم تعطيل المصادقة الثنائية للمستخدم ' . $user->name,
            $user
        );

        return true;
    }

    /**
     * إنشاء رابط QR للمصادقة الثنائية.
     *
     * @param \App\Models\User $user
     * @param string $secretKey
     * @return string
     */
    public function getQrCodeUrl(User $user, $secretKey = null)
    {
        if (!$secretKey) {
            $secretKey = decrypt($user->two_factor_secret);
        }

        $companyName = config('app.name');

        return $this->google2fa->getQRCodeUrl($companyName, $user->email, $secretKey);
    }
}
