<?php
// app/Core/Auth.php - Authentication & Authorization
// UPDATED VERSION with getUserId() and other fixes

class Auth {
    
    // Check if user is logged in
    public static function check() {
        return isset($_SESSION['user_id']) && $_SESSION['user_id'] > 0;
    }
    
    public static function isLoggedIn() {
        return self::check();
    }
    
    // Get current user ID
    public static function id() {
        return $_SESSION['user_id'] ?? null;
    }
    
    // Alias for id() - used in many places
    public static function getUserId() {
        return self::id();
    }
    
    // Get current user type
    public static function userType() {
        return $_SESSION['user_type'] ?? null;
    }
    
    // Alias for userType()
    public static function getUserType() {
        return self::userType();
    }
    
    // Get user role (alias for userType)
    public static function getUserRole() {
        return self::userType();
    }
    
    // Require specific user role
    public static function requireRole($role) {
        self::require();
        if (self::userType() !== $role) {
            flash('error', 'Access denied. Insufficient privileges.', 'danger');
            redirect('/auth/login.php');
        }
    }
    
    // Get current user email
    public static function email() {
        return $_SESSION['user_email'] ?? null;
    }
    
    // Get full user data
    public static function user() {
        if (!self::check()) {
            return null;
        }
        
        $db = Database::getInstance();
        $sql = "SELECT id, email, user_type, status, created_at FROM users WHERE id = ?";
        return $db->fetch($sql, [self::id()]);
    }
    
    // Check if user is admin
    public static function isAdmin() {
        return self::check() && self::userType() === 'admin';
    }
    
    // Check if user is vendor
    public static function isVendor() {
        return self::check() && self::userType() === 'vendor';
    }
    
    // Check if user is customer
    public static function isCustomer() {
        return self::check() && self::userType() === 'customer';
    }
    
    // Require authentication
    public static function require() {
        if (!self::check()) {
            flash('error', 'Please login to continue', 'warning');
            redirect('/auth/login.php');
        }
    }

    // Require login (alias for require method)
    public static function requireLogin($user_type = null) {
        self::require();
        
        if ($user_type && self::userType() !== $user_type) {
            flash('error', 'Access denied. ' . ucfirst($user_type) . ' account required.', 'danger');
            redirect('/auth/login.php');
        }
    }
    
    // Require admin
    public static function requireAdmin() {
        self::require();
        if (!self::isAdmin()) {
            flash('error', 'Access denied. Admin privileges required.', 'danger');
            redirect('/auth/login.php');
        }
    }
    
    // Require vendor
    public static function requireVendor() {
        self::require();
        if (!self::isVendor()) {
            flash('error', 'Access denied. Vendor account required.', 'danger');
            redirect('/auth/login.php');
        }
    }
    
    // Require customer
    public static function requireCustomer() {
        self::require();
        if (!self::isCustomer()) {
            flash('error', 'Access denied. Customer account required.', 'danger');
            redirect('/auth/login.php');
        }
    }
    
    // Login user
    public static function login($user_id, $user_type, $email) {
        // Regenerate session ID for security
        session_regenerate_id(true);
        
        // Set session data
        $_SESSION['user_id'] = $user_id;
        $_SESSION['user_type'] = $user_type;
        $_SESSION['user_email'] = $email;
        $_SESSION['login_time'] = time();
        $_SESSION['last_activity'] = time();
        
        // Update last login
        $db = Database::getInstance();
        $sql = "UPDATE users SET last_login = NOW() WHERE id = ?";
        $db->execute($sql, [$user_id]);
        
        return true;
    }
    
    // Logout user
    public static function logout() {
        // Unset all session variables
        $_SESSION = array();
        
        // Destroy session cookie
        if (isset($_COOKIE[session_name()])) {
            setcookie(session_name(), '', time() - 3600, '/');
        }
        
        // Destroy session
        session_destroy();
        
        // Redirect to login
        redirect('../');
    }
    
    // Check session timeout
    public static function checkTimeout() {
        if (self::check()) {
            $timeout = defined('SESSION_LIFETIME') ? SESSION_LIFETIME : 7200; // 2 hours default
            $last_activity = $_SESSION['last_activity'] ?? 0;
            
            if (time() - $last_activity > $timeout) {
                self::logout();
            }
            
            $_SESSION['last_activity'] = time();
        }
    }
    
    // Attempt login
    public static function attempt($email, $password) {
        $db = Database::getInstance();
        
        // Find user by email
        $sql = "SELECT * FROM users WHERE email = ? LIMIT 1";
        $user = $db->fetch($sql, [$email]);
        
        if (!$user) {
            return ['success' => false, 'message' => 'Invalid email or password'];
        }
        
        // Check if account is active
        if ($user['status'] !== 'active') {
            $message = $user['status'] === 'suspended' 
                ? 'Your account has been suspended. Please contact support.'
                : 'Your account is not active. Please verify your email or contact support.';
            return ['success' => false, 'message' => $message];
        }
        
        // Verify password
        if (!password_verify($password, $user['password'])) {
            return ['success' => false, 'message' => 'Invalid email or password'];
        }
        
        // Check if vendor is approved
        if ($user['user_type'] === 'vendor') {
            $vendor_sql = "SELECT approval_status FROM vendors WHERE user_id = ?";
            $vendor = $db->fetch($vendor_sql, [$user['id']]);
            
            if ($vendor && $vendor['approval_status'] !== 'approved') {
                $message = $vendor['approval_status'] === 'pending'
                    ? 'Your vendor account is pending your registration confirmation and/or admin approval.'
                    : 'Your vendor account has been rejected. Please contact support.';
                return ['success' => false, 'message' => $message];
            }
        }
        
        // Check email verification if required
        $require_verification = defined('REQUIRE_EMAIL_VERIFICATION') ? REQUIRE_EMAIL_VERIFICATION : false;
        if ($require_verification && !$user['email_verified']) {
            return ['success' => false, 'message' => 'Please verify your email address before logging in.'];
        }
        
        // Login successful
        self::login($user['id'], $user['user_type'], $user['email']);
        
        return ['success' => true, 'user_type' => $user['user_type']];
    }
    
    // Get redirect URL based on user type
    public static function getRedirectUrl() {
        if (self::isAdmin()) {
            return '../admin/index.php';
        } elseif (self::isVendor()) {
            return '../vendor/index.php';
        } elseif (self::isCustomer()) {
            return '../customer/index.php';
        }
        return '/index.php';
    }
    
    // Check if user owns resource
    public static function owns($user_id) {
        return self::check() && self::id() == $user_id;
    }
    
    // Generate password reset token
    public static function generateResetToken($user_id) {
        $token = bin2hex(random_bytes(32));
        $expires = date('Y-m-d H:i:s', strtotime('+1 hour'));
        
        $db = Database::getInstance();
        $sql = "UPDATE users SET reset_token = ?, reset_token_expires = ? WHERE id = ?";
        
        if ($db->execute($sql, [$token, $expires, $user_id])) {
            return $token;
        }
        
        return false;
    }
    
    // Validate reset token
    public static function validateResetToken($token) {
        $db = Database::getInstance();
        $sql = "SELECT id, email FROM users 
                WHERE reset_token = ? 
                AND reset_token_expires > NOW()
                LIMIT 1";
        
        return $db->fetch($sql, [$token]);
    }
    
    // Reset password
    public static function resetPassword($token, $new_password) {
        $user = self::validateResetToken($token);
        
        if (!$user) {
            return false;
        }
        
        $hashed = password_hash($new_password, PASSWORD_DEFAULT);
        
        $db = Database::getInstance();
        $sql = "UPDATE users 
                SET password = ?, reset_token = NULL, reset_token_expires = NULL 
                WHERE id = ?";
        
        return $db->execute($sql, [$hashed, $user['id']]);
    }

    /**
     * Require customer with redirect back
     * Stores current page for redirect after login
     */
    public static function requireCustomerWithRedirect() {
        if (!self::check() || !self::isCustomer()) {
            // Store current page URL for redirect after login
            $current_url = $_SERVER['REQUEST_URI'] ?? '';
            
            // Don't store if already on auth pages
            if (strpos($current_url, '/auth/') === false) {
                $_SESSION['redirect_after_login'] = $current_url;
            }
            
            flash('error', 'Please login to continue', 'warning');
            redirect('/auth/login.php');
        }
    }
    
    /**
     * Store current page for redirect after login
     * Use this before redirecting to login
     */
    public static function setRedirectAfterLogin($url = null) {
        if ($url === null) {
            // Auto-detect current URL
            $url = $_SERVER['REQUEST_URI'] ?? '';
        }
        
        // Security: only store relative URLs
        if (strpos($url, 'http') === false && strpos($url, '//') === false) {
            // Exclude auth pages
            if (strpos($url, '/auth/') === false) {
                $_SESSION['redirect_after_login'] = $url;
            }
        }
    }
    
    /**
     * Get and clear redirect URL
     */
    public static function getRedirectAfterLogin($default = '/index.php') {
        $redirect = $_SESSION['redirect_after_login'] ?? $default;
        unset($_SESSION['redirect_after_login']);
        return $redirect;
    }

}