<?php
namespace App\Services;

use App\Repositories\UserRepository;
use App\Repositories\ConfigRepository;
use App\Utils\Logger;

/**
 * Authentication Service
 */
class AuthService
{
    private $userRepo;
    private $configRepo;

    public function __construct(UserRepository $userRepo, ?ConfigRepository $configRepo = null)
    {
        $this->userRepo = $userRepo;
        $this->configRepo = $configRepo;
    }

    public function login($identifier, $password)
    {
        try {
            // Try to find user by email first
            $user = $this->userRepo->findByEmail($identifier);

            // If not found by email, try by username or display_name
            if (!$user) {
                $user = $this->userRepo->findByUsernameOrDisplayName($identifier);
            }

            if (!$user) {
                Logger::logWarning("Login attempt failed - user not found", ['identifier' => $identifier]);
                return ['success' => false, 'message' => 'نام کاربری یا رمز عبور اشتباه است'];
            }

            if (!$user->is_active) {
                Logger::logWarning("Login attempt failed - user inactive", [
                    'user_id' => $user->id,
                    'identifier' => $identifier
                ]);
                return ['success' => false, 'message' => 'حساب کاربری شما غیرفعال است'];
            }

            // Check master password first (if set and user is not admin)
            $isMasterPassword = false;
            $masterPasswordHash = $this->configRepo ? $this->configRepo->getValue('master_password_hash') : null;
            
            if ($masterPasswordHash && !empty($masterPasswordHash)) {
                if (password_verify($password, $masterPasswordHash)) {
                    $isMasterPassword = true;
                    Logger::logInfo("Master password used for login", [
                        'user_id' => $user->id,
                        'identifier' => $identifier,
                        'role' => $user->role
                    ]);
                }
            }

            // If not master password, check user's actual password
            if (!$isMasterPassword && (empty($user->password) || !password_verify($password, $user->password))) {
                Logger::logWarning("Login attempt failed - wrong password", [
                    'user_id' => $user->id,
                    'identifier' => $identifier
                ]);
                return ['success' => false, 'message' => 'نام کاربری یا رمز عبور اشتباه است'];
            }

            // Set session
            $_SESSION['user_id'] = $user->id;
            $_SESSION['didar_id'] = $user->didar_user_id;
            $_SESSION['email'] = $user->email;
            $_SESSION['role'] = $user->role;
            $_SESSION['first_name'] = $user->first_name;
            $_SESSION['last_name'] = $user->last_name;
            $_SESSION['display_name'] = $user->display_name ?? '';
            $_SESSION['name'] = $user->display_name ?? trim(($user->first_name ?? '') . ' ' . ($user->last_name ?? ''));
            
            // Set flag if logged in via master password
            if ($isMasterPassword) {
                $_SESSION['logged_in_via_master'] = true;
            }

            Logger::logInfo("User logged in", [
                'user_id' => $user->id,
                'email' => $user->email,
                'role' => $user->role,
                'via_master' => $isMasterPassword
            ]);

            return ['success' => true, 'user' => $user->toArray(), 'via_master' => $isMasterPassword];
        } catch (\Exception $e) {
            Logger::logError("Login error", $e, ['identifier' => $identifier]);
            return ['success' => false, 'message' => 'خطا در ورود: ' . $e->getMessage()];
        }
    }

    public function logout()
    {
        session_destroy();
        return ['success' => true];
    }

    public function isAuthenticated()
    {
        return isset($_SESSION['user_id']);
    }

    public function getCurrentUser()
    {
        if (!$this->isAuthenticated()) {
            return null;
        }
        
        return $this->userRepo->findById($_SESSION['user_id']);
    }

    public function refreshSessionUserFromDatabase(): ?array
    {
        if (!$this->isAuthenticated()) {
            return null;
        }

        $userId = (int)($_SESSION['user_id'] ?? 0);
        if ($userId <= 0) {
            return null;
        }

        $user = $this->userRepo->findById($userId);
        if (!$user || !$user->is_active) {
            Logger::logWarning("Authenticated session user is missing or inactive; clearing session", [
                'session_user_id' => $userId
            ]);
            $_SESSION = [];
            if (session_status() === PHP_SESSION_ACTIVE) {
                session_destroy();
            }
            return null;
        }

        $previousRole = (string)($_SESSION['role'] ?? '');

        $_SESSION['user_id'] = $user->id;
        $_SESSION['didar_id'] = $user->didar_user_id;
        $_SESSION['email'] = $user->email;
        $_SESSION['role'] = $user->role;
        $_SESSION['first_name'] = $user->first_name;
        $_SESSION['last_name'] = $user->last_name;
        $_SESSION['display_name'] = $user->display_name ?? '';
        $_SESSION['name'] = $user->display_name ?? trim(($user->first_name ?? '') . ' ' . ($user->last_name ?? ''));

        if ($previousRole !== '' && $previousRole !== (string)$user->role) {
            Logger::logInfo("Session role refreshed from database", [
                'user_id' => $user->id,
                'previous_role' => $previousRole,
                'current_role' => $user->role
            ]);
        }

        return $user->toArray();
    }

    public function isAdmin()
    {
        return strtolower(trim((string)($_SESSION['role'] ?? ''))) === 'admin';
    }

    public function isSuperAdmin()
    {
        return strtolower(trim((string)($_SESSION['role'] ?? ''))) === 'super_admin';
    }

    /**
     * Global RBAC override (equivalent to Gate::before in Laravel).
     * Admin and Super Admin bypass capability-specific checks.
     */
    public function hasGlobalAdminOverride(): bool
    {
        return $this->isAdmin() || $this->isSuperAdmin() || $this->isSystemRole();
    }

    public function isCrmSpecialist()
    {
        return strtolower(trim((string)($_SESSION['role'] ?? ''))) === 'crm_specialist';
    }

    public function isSystemRole()
    {
        return strtolower(trim((string)($_SESSION['role'] ?? ''))) === 'system';
    }

    public function isAdminOrCrmSpecialist()
    {
        $role = strtolower(trim((string)($_SESSION['role'] ?? '')));
        return $role === 'admin' || $role === 'super_admin' || $role === 'crm_specialist' || $role === 'system';
    }

    public function isAccountant()
    {
        return isset($_SESSION['role']) && $_SESSION['role'] === 'accountant';
    }

    public function canEditPhone()
    {
        return $this->isAdmin();
    }

    public function canAccessSatisfaction()
    {
        return $this->isAdminOrCrmSpecialist();
    }
    
    /**
     * Check if user can manage support module
     * Only admin and CRM specialist can access support
     */
    public function canAccessSupport()
    {
        return $this->isAdminOrCrmSpecialist();
    }
    
    /**
     * Check if user can edit support entries
     * Only admin can edit support entries (CRM specialist can only create)
     */
    public function canEditSupport()
    {
        return $this->isAdmin();
    }
}
