<?php

namespace App\Controllers;

use App\Models\ActivityLogModel;
use App\Models\CompanyModel;
use App\Models\LoginOtpModel;
use App\Models\TrustedDeviceModel;
use App\Models\UserModel;

/**
 * تسجيل دخول لوحة الأدمن (سوبر أدمن أو مدير شركة).
 * يشمل تأكيد الدخول بالبريد (كود 6 أرقام) عند الدخول من جهاز/متصفح جديد
 * لم يُستخدم قبل كده لنفس الحساب.
 */
class AuthController extends BaseController
{
    private const DEVICE_COOKIE = 'erp_trusted_device';

    public function showLogin()
    {
        return view('admin/auth/login');
    }

    public function login()
    {
        $model = new UserModel();
        $email = $this->request->getPost('email');
        $password = $this->request->getPost('password');

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

        if (! $user || ! password_verify($password, $user['password'])) {
            return redirect()->back()->with('error', lang('App.login_failed'));
        }

        // منع دخول الحساب المنتهية صلاحيته (السوبر أدمن مستثنى دائماً)
        if (! $user['is_super_admin'] && $model->isExpired($user)) {
            return redirect()->back()->with('error', 'انتهت صلاحية حسابك بتاريخ ' . $user['expires_at'] . '. يرجى التواصل مع إدارة النظام لتجديد الاشتراك.');
        }

        // هل الجهاز/المتصفح ده موثوق بالفعل لنفس المستخدم؟
        $deviceToken = $this->request->getCookie(self::DEVICE_COOKIE);
        $trustedModel = new TrustedDeviceModel();

        if ($trustedModel->isTrusted((int) $user['id'], $deviceToken)) {
            return $this->completeLogin($user);
        }

        // جهاز جديد: ابعت كود تأكيد بالبريد واحفظ حالة "دخول معلّق" مؤقتة
        $otpModel = new LoginOtpModel();
        $code = $otpModel->generate((int) $user['id']);

        $this->sendOtpEmail($user, $code);

        session()->set([
            'pending_2fa_user_id' => $user['id'],
            'pending_2fa_email' => $user['email'],
        ]);

        return redirect()->to('/admin/verify-code');
    }

    /** شاشة إدخال كود التأكيد */
    public function showVerify()
    {
        if (! session()->get('pending_2fa_user_id')) {
            return redirect()->to('/admin/login');
        }

        return view('admin/auth/verify', ['email' => session()->get('pending_2fa_email')]);
    }

    /** التحقق من الكود المُدخل */
    public function verify()
    {
        $userId = session()->get('pending_2fa_user_id');
        if (! $userId) {
            return redirect()->to('/admin/login');
        }

        $code = trim((string) $this->request->getPost('code'));
        $otpModel = new LoginOtpModel();

        if (! $otpModel->verify((int) $userId, $code)) {
            return redirect()->back()->with('error', 'الكود غير صحيح أو منتهي الصلاحية. اطلب كود جديد لو احتجت.');
        }

        $user = (new UserModel())->find($userId);
        if (! $user) {
            return redirect()->to('/admin/login');
        }

        // اعتبر الجهاز ده موثوق من دلوقتي (ما يطلبش كود تاني منه)
        $trustedModel = new TrustedDeviceModel();
        $token = $trustedModel->trust((int) $user['id'], (string) $this->request->getUserAgent());

        // كوكي لمدة 90 يوم
        $this->response->setCookie(self::DEVICE_COOKIE, $token, 60 * 60 * 24 * 90, '', '/', '', false, true);

        session()->remove(['pending_2fa_user_id', 'pending_2fa_email']);

        return $this->completeLogin($user);
    }

    /** إعادة إرسال كود جديد لنفس الجلسة المعلّقة */
    public function resendCode()
    {
        $userId = session()->get('pending_2fa_user_id');
        if (! $userId) {
            return redirect()->to('/admin/login');
        }

        $user = (new UserModel())->find($userId);
        if (! $user) {
            return redirect()->to('/admin/login');
        }

        $code = (new LoginOtpModel())->generate((int) $userId);
        $this->sendOtpEmail($user, $code);

        return redirect()->back()->with('message', 'تم إرسال كود جديد لبريدك الإلكتروني.');
    }

    /** إتمام الدخول فعلياً بعد نجاح كلمة المرور (والتأكيد لو لزم) */
    private function completeLogin(array $user)
    {
        $activeCompanyId = $user['company_id'];
        if ($user['is_super_admin'] && ! $activeCompanyId) {
            $firstCompany = (new CompanyModel())->orderBy('id', 'ASC')->first();
            $activeCompanyId = $firstCompany['id'] ?? null;
        }

        session()->set([
            'admin_user_id' => $user['id'],
            'admin_name' => $user['name'],
            'company_id' => $user['company_id'],
            'active_company_id' => $activeCompanyId,
            'is_super_admin' => (bool) $user['is_super_admin'],
        ]);

        (new ActivityLogModel())->record($activeCompanyId, $user['id'], $user['name'], 'login', 'تسجيل دخول للوحة التحكم');

        return redirect()->to('/admin/dashboard');
    }

    private function sendOtpEmail(array $user, string $code): void
    {
        $email = \Config\Services::email();
        $email->setTo($user['email']);
        $email->setSubject('كود تأكيد الدخول - ' . $code);
        $email->setMessage(
            "مرحباً {$user['name']},\n\n" .
            "تم رصد محاولة دخول من جهاز أو متصفح جديد لحسابك.\n\n" .
            "كود التأكيد: {$code}\n\n" .
            "هذا الكود صالح لمدة 10 دقائق فقط.\n" .
            "لو مكنتش أنت اللي بتحاول تدخل، تجاهل هذه الرسالة وغيّر كلمة مرورك فوراً."
        );
        $email->send();
    }

    /**
     * تبديل الشركة النشطة - متاح للسوبر أدمن فقط.
     */
    public function switchCompany($companyId)
    {
        if (! session()->get('is_super_admin')) {
            return redirect()->to('/admin/dashboard');
        }

        $company = (new CompanyModel())->find($companyId);
        if ($company) {
            session()->set('active_company_id', (int) $companyId);
        }

        return redirect()->back();
    }

    public function logout()
    {
        if (session()->get('admin_user_id')) {
            (new ActivityLogModel())->record(
                session()->get('active_company_id'), session()->get('admin_user_id'), session()->get('admin_name'), 'logout', 'تسجيل خروج'
            );
        }
        session()->remove(['admin_user_id', 'admin_name', 'company_id', 'active_company_id', 'is_super_admin']);
        return redirect()->to('/admin/login');
    }
}
