<?php
/**
 * Authentication and Authorization System
 * Handle user login, logout, and permissions
 */

namespace Core;

class Auth {
    private static $db;
    
    public static function init() {
        self::$db = DB::getInstance();
    }
    
    /**
     * Authenticate user with email and password
     */
    public static function login($email, $password) {
        self::init();
        
        $user = self::$db->fetchOne(
            "SELECT * FROM users WHERE email = ? AND active = 1",
            [$email]
        );
        
        if (!$user || !password_verify($password, $user['password_hash'])) {
            return false;
        }
        
        // Set session data
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['user_role'] = $user['role'];
        $_SESSION['user_name'] = $user['name'];
        $_SESSION['user_email'] = $user['email'];
        $_SESSION['last_activity'] = time();
        
        // Log successful login
        self::logActivity($user['id'], 'login', 'User logged in');
        
        return $user;
    }
    
    /**
     * Logout user
     */
    public static function logout() {
        if (isset($_SESSION['user_id'])) {
            self::logActivity($_SESSION['user_id'], 'logout', 'User logged out');
        }
        
        session_destroy();
        return true;
    }
    
    /**
     * Check if user is authenticated
     */
    public static function check() {
        if (!isset($_SESSION['user_id'])) {
            return false;
        }
        
        // Check session timeout
        if (isset($_SESSION['last_activity']) && 
            (time() - $_SESSION['last_activity']) > SESSION_LIFETIME) {
            self::logout();
            return false;
        }
        
        $_SESSION['last_activity'] = time();
        return true;
    }
    
    /**
     * Get current authenticated user
     */
    public static function user() {
        if (!self::check()) {
            return null;
        }
        
        self::init();
        
        return self::$db->fetchOne(
            "SELECT id, role, name, email, phone, lat, lng, address FROM users WHERE id = ?",
            [$_SESSION['user_id']]
        );
    }
    
    /**
     * Check if user has specific role
     */
    public static function hasRole($role) {
        if (!self::check()) {
            return false;
        }
        
        return $_SESSION['user_role'] === $role;
    }
    
    /**
     * Check if user has any of the given roles
     */
    public static function hasAnyRole($roles) {
        if (!self::check()) {
            return false;
        }
        
        return in_array($_SESSION['user_role'], $roles);
    }
    
    /**
     * Require authentication
     */
    public static function requireAuth() {
        if (!self::check()) {
            if (self::isApiRequest()) {
                http_response_code(401);
                header('Content-Type: application/json');
                echo json_encode(['error' => 'Authentication required']);
            } else {
                header('Location: /login');
            }
            exit();
        }
        
        return $_SESSION['user_id'];
    }
    
    /**
     * Require specific role
     */
    public static function requireRole($role) {
        $userId = self::requireAuth();
        
        if (!self::hasRole($role)) {
            if (self::isApiRequest()) {
                http_response_code(403);
                header('Content-Type: application/json');
                echo json_encode(['error' => 'Insufficient permissions']);
            } else {
                header('Location: /unauthorized');
            }
            exit();
        }
        
        return $userId;
    }
    
    /**
     * Create new user account
     */
    public static function register($userData) {
        self::init();
        
        // Check if email already exists
        if (self::$db->exists('users', 'email = ?', [$userData['email']])) {
            throw new \Exception('Email already registered');
        }
        
        // Hash password
        $userData['password_hash'] = password_hash($userData['password'], HASH_ALGO);
        unset($userData['password']);
        
        // Set defaults
        $userData['id'] = self::generateUuid();
        $userData['active'] = true;
        $userData['created_at'] = date('Y-m-d H:i:s');
        
        self::$db->beginTransaction();
        
        try {
            // Insert user
            $userId = self::$db->insert('users', $userData);
            
            // Create role-specific records
            if ($userData['role'] === 'pharmacy') {
                self::createPharmacyProfile($userData['id'], $userData);
            } elseif ($userData['role'] === 'courier') {
                self::createCourierProfile($userData['id'], $userData);
            }
            
            self::$db->commit();
            
            self::logActivity($userData['id'], 'register', 'User account created');
            
            return $userData['id'];
            
        } catch (\Exception $e) {
            self::$db->rollback();
            throw $e;
        }
    }
    
    /**
     * Create pharmacy profile
     */
    private static function createPharmacyProfile($userId, $userData) {
        $pharmacy = [
            'id' => self::generateUuid(),
            'user_id' => $userId,
            'name' => $userData['name'],
            'lat' => $userData['lat'],
            'lng' => $userData['lng'],
            'address' => $userData['address'],
            'verified' => false,
            'created_at' => date('Y-m-d H:i:s')
        ];
        
        self::$db->insert('pharmacies', $pharmacy);
        
        // Create wallet
        self::$db->insert('wallets', [
            'id' => self::generateUuid(),
            'owner_type' => 'PHARMACY',
            'owner_id' => $pharmacy['id'],
            'balance' => 0,
            'updated_at' => date('Y-m-d H:i:s')
        ]);
    }
    
    /**
     * Create courier profile
     */
    private static function createCourierProfile($userId, $userData) {
        $courier = [
            'id' => self::generateUuid(),
            'user_id' => $userId,
            'vehicle_type' => $userData['vehicle_type'] ?? 'motorcycle',
            'lat' => $userData['lat'],
            'lng' => $userData['lng'],
            'active' => true,
            'available' => true,
            'created_at' => date('Y-m-d H:i:s')
        ];
        
        self::$db->insert('couriers', $courier);
        
        // Create wallet
        self::$db->insert('wallets', [
            'id' => self::generateUuid(),
            'owner_type' => 'COURIER',
            'owner_id' => $courier['id'],
            'balance' => 0,
            'updated_at' => date('Y-m-d H:i:s')
        ]);
    }
    
    /**
     * Update user password
     */
    public static function updatePassword($userId, $newPassword) {
        self::init();
        
        $hashedPassword = password_hash($newPassword, HASH_ALGO);
        
        return self::$db->update(
            'users',
            ['password_hash' => $hashedPassword],
            'id = ?',
            [$userId]
        );
    }
    
    /**
     * Generate password reset token
     */
    public static function generateResetToken($email) {
        self::init();
        
        $user = self::$db->fetchOne("SELECT id FROM users WHERE email = ?", [$email]);
        
        if (!$user) {
            return false;
        }
        
        $token = bin2hex(random_bytes(32));
        $expires = date('Y-m-d H:i:s', strtotime('+1 hour'));
        
        // Store token (you'd need a password_resets table)
        // For now, just return the token
        
        return $token;
    }
    
    /**
     * Log user activity
     */
    private static function logActivity($userId, $action, $description) {
        self::init();
        
        $activity = [
            'id' => self::generateUuid(),
            'user_id' => $userId,
            'action' => $action,
            'description' => $description,
            'ip_address' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'unknown',
            'created_at' => date('Y-m-d H:i:s')
        ];
        
        // You'd need a user_activities table for this
        // For now, just log to file
        $logFile = LOG_PATH . 'auth.log';
        $logMessage = "[{$activity['created_at']}] {$userId}: {$action} - {$description}" . PHP_EOL;
        file_put_contents($logFile, $logMessage, FILE_APPEND | LOCK_EX);
    }
    
    /**
     * Check if current request is API request
     */
    private static function isApiRequest() {
        return strpos($_SERVER['REQUEST_URI'], '/api/') !== false;
    }
    
    /**
     * Generate UUID v4
     */
    private static function generateUuid() {
        return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
            mt_rand(0, 0xffff), mt_rand(0, 0xffff),
            mt_rand(0, 0xffff),
            mt_rand(0, 0x0fff) | 0x4000,
            mt_rand(0, 0x3fff) | 0x8000,
            mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
        );
    }
}
?>
