<?php
/**
 * GlowSpace User Authentication System
 * Handles user registration, login, logout, password management
 */

require_once __DIR__ . '/db.php';

class Auth {
    private static $instance = null;

    private function __construct() {
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
        
        // Initialize CSRF token if not exists
        if (empty($_SESSION['csrf_token'])) {
            $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        }
    }

    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    // ============================================
    // USER REGISTRATION
    // ============================================

    public function register($fullName, $email, $password) {
        // Validate inputs
        if (empty($fullName) || empty($email) || empty($password)) {
            return ['success' => false, 'message' => 'All fields are required'];
        }

        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            return ['success' => false, 'message' => 'Invalid email address'];
        }

        if (strlen($password) < 6) {
            return ['success' => false, 'message' => 'Password must be at least 6 characters'];
        }

        // Check if email already exists
        $existing = db()->fetchOne("SELECT id FROM users WHERE email = ?", [$email]);
        if ($existing) {
            return ['success' => false, 'message' => 'Email already registered'];
        }

        // Hash password
        $passwordHash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 10]);

        // Generate verification token
        $verificationToken = bin2hex(random_bytes(32));

        // Insert user
        $userId = Database::getInstance()->insert('users', [
            'email' => $email,
            'password' => $passwordHash,
            'full_name' => $fullName,
            'verification_token' => $verificationToken,
            'status' => 'active',
            'email_verified' => false
        ]);

        if ($userId) {
            // Create user profile
            Database::getInstance()->insert('user_profiles', [
                'user_id' => $userId
            ]);

            // Log activity
            logActivity('user_registered', "User registered: $email", $userId);

            return ['success' => true, 'message' => 'Registration successful! You can now login.'];
        }

        return ['success' => false, 'message' => 'Registration failed. Please try again.'];
    }

    // ============================================
    // USER LOGIN
    // ============================================

    public function login($email, $password, $remember = false) {
        if (empty($email) || empty($password)) {
            return ['success' => false, 'message' => 'Email and password are required'];
        }

        // Find user by email
        $user = db()->fetchOne("SELECT * FROM users WHERE email = ? AND status = 'active'", [$email]);

        if (!$user) {
            return ['success' => false, 'message' => 'Invalid email or password'];
        }

        // Verify password
        if (!password_verify($password, $user['password'])) {
            return ['success' => false, 'message' => 'Invalid email or password'];
        }

        // Set session
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['user_email'] = $user['email'];
        $_SESSION['user_name'] = $user['full_name'];
        $_SESSION['logged_in'] = true;
        $_SESSION['login_time'] = time();

        // Update last login
        db()->query("UPDATE users SET last_login = NOW() WHERE id = ?", [$user['id']]);

        // Handle remember me
        if ($remember) {
            $token = bin2hex(random_bytes(32));
            $hash = hash('sha256', $token);
            
            // Store token in database
            Database::getInstance()->insert('user_tokens', [
                'user_id' => $user['id'],
                'token' => $hash,
                'expires_at' => date('Y-m-d H:i:s', time() + REMEMBER_ME_LIFETIME)
            ]);

            // Set cookie
            setcookie('remember_token', $token, time() + REMEMBER_ME_LIFETIME, '/', '', false, true);
        }

        // Log activity
        logActivity('user_login', "User logged in: $email", $user['id']);

        // Sync cart from database to session
        $this->syncCartFromDatabase($user['id']);

        return ['success' => true, 'message' => 'Login successful!'];
    }

    // ============================================
    // USER LOGOUT
    // ============================================

    public function logout() {
        $userId = $_SESSION['user_id'] ?? null;

        // Clear remember me token
        if (isset($_COOKIE['remember_token'])) {
            $token = hash('sha256', $_COOKIE['remember_token']);
            db()->query("DELETE FROM user_tokens WHERE token = ?", [$token]);
            setcookie('remember_token', '', time() - 3600, '/', '', false, true);
        }

        // Sync cart to database before logout
        if ($userId) {
            $this->syncCartToDatabase($userId);
        }

        // Destroy session
        $_SESSION = [];
        session_destroy();

        // Log activity
        if ($userId) {
            logActivity('user_logout', "User logged out", $userId);
        }

        return ['success' => true, 'message' => 'Logged out successfully'];
    }

    // ============================================
    // CHECK IF USER IS LOGGED IN
    // ============================================

    public function isLoggedIn() {
        if (isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === true) {
            // Check session expiry
            if (isset($_SESSION['login_time']) && (time() - $_SESSION['login_time']) < SESSION_LIFETIME) {
                return true;
            }
        }

        // Check remember me token
        if (isset($_COOKIE['remember_token'])) {
            return $this->loginWithRememberToken($_COOKIE['remember_token']);
        }

        return false;
    }

    // ============================================
    // LOGIN WITH REMEMBER TOKEN
    // ============================================

    private function loginWithRememberToken($token) {
        $hash = hash('sha256', $token);
        
        $userToken = db()->fetchOne(
            "SELECT ut.*, u.id, u.email, u.full_name, u.password, u.status 
             FROM user_tokens ut 
             JOIN users u ON ut.user_id = u.id 
             WHERE ut.token = ? AND ut.expires_at > NOW() AND u.status = 'active'",
            [$hash]
        );

        if ($userToken) {
            $_SESSION['user_id'] = $userToken['id'];
            $_SESSION['user_email'] = $userToken['email'];
            $_SESSION['user_name'] = $userToken['full_name'];
            $_SESSION['logged_in'] = true;
            $_SESSION['login_time'] = time();

            // Update last login
            db()->query("UPDATE users SET last_login = NOW() WHERE id = ?", [$userToken['id']]);

            // Sync cart
            $this->syncCartFromDatabase($userToken['id']);

            return true;
        }

        return false;
    }

    // ============================================
    // GET CURRENT USER
    // ============================================

    public function getCurrentUser() {
        if (!$this->isLoggedIn()) {
            return null;
        }

        $userId = $_SESSION['user_id'];
        $user = db()->fetchOne("SELECT * FROM users WHERE id = ?", [$userId]);

        if ($user) {
            // Get user profile
            $profile = db()->fetchOne("SELECT * FROM user_profiles WHERE user_id = ?", [$userId]);
            if ($profile) {
                $user['profile'] = $profile;
            }

            // Get user stats
            $stats = $this->getUserStats($userId);
            $user['stats'] = $stats;
        }

        return $user;
    }

    // ============================================
    // GET USER STATISTICS
    // ============================================

    private function getUserStats($userId) {
        $stats = [
            'total_orders' => 0,
            'completed_orders' => 0,
            'pending_orders' => 0,
            'cancelled_orders' => 0,
            'wishlist_count' => 0,
            'cart_count' => 0
        ];

        // Order stats
        $orderStats = db()->fetchOne(
            "SELECT 
                COUNT(*) as total,
                SUM(CASE WHEN status = 'delivered' THEN 1 ELSE 0 END) as completed,
                SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending,
                SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) as cancelled
            FROM orders WHERE user_id = ?",
            [$userId]
        );

        if ($orderStats) {
            $stats['total_orders'] = (int)$orderStats['total'];
            $stats['completed_orders'] = (int)$orderStats['completed'];
            $stats['pending_orders'] = (int)$orderStats['pending'];
            $stats['cancelled_orders'] = (int)$orderStats['cancelled'];
        }

        // Wishlist count
        $wishlistCount = db()->fetchOne("SELECT COUNT(*) as count FROM wishlist WHERE user_id = ?", [$userId]);
        $stats['wishlist_count'] = (int)$wishlistCount['count'];

        // Cart count
        $cartCount = db()->fetchOne("SELECT SUM(quantity) as count FROM cart WHERE user_id = ?", [$userId]);
        $stats['cart_count'] = (int)($cartCount['count'] ?? 0);

        return $stats;
    }

    // ============================================
    // CHANGE PASSWORD
    // ============================================

    public function changePassword($currentPassword, $newPassword) {
        $user = $this->getCurrentUser();
        
        if (!$user) {
            return ['success' => false, 'message' => 'User not logged in'];
        }

        // Verify current password
        if (!password_verify($currentPassword, $user['password'])) {
            return ['success' => false, 'message' => 'Current password is incorrect'];
        }

        if (strlen($newPassword) < 6) {
            return ['success' => false, 'message' => 'New password must be at least 6 characters'];
        }

        // Hash new password
        $newPasswordHash = password_hash($newPassword, PASSWORD_BCRYPT, ['cost' => 10]);

        // Update password
        $result = db()->query("UPDATE users SET password = ? WHERE id = ?", [$newPasswordHash, $user['id']]);

        if ($result) {
            // Clear all remember tokens
            db()->query("DELETE FROM user_tokens WHERE user_id = ?", [$user['id']]);

            // Log activity
            logActivity('password_changed', "User changed password", $user['id']);

            return ['success' => true, 'message' => 'Password changed successfully'];
        }

        return ['success' => false, 'message' => 'Failed to change password'];
    }

    // ============================================
    // REQUEST PASSWORD RESET
    // ============================================

    public function requestPasswordReset($email) {
        $user = db()->fetchOne("SELECT * FROM users WHERE email = ? AND status = 'active'", [$email]);

        if (!$user) {
            return ['success' => false, 'message' => 'Email not found'];
        }

        // Generate reset token
        $resetToken = bin2hex(random_bytes(32));
        $resetExpires = date('Y-m-d H:i:s', time() + 3600); // 1 hour

        // Update user
        db()->query(
            "UPDATE users SET reset_token = ?, reset_expires = ? WHERE id = ?",
            [$resetToken, $resetExpires, $user['id']]
        );

        // Log activity
        logActivity('password_reset_requested', "Password reset requested: $email", $user['id']);

        // In a real implementation, send email here
        // For now, return the token (for development)
        return [
            'success' => true,
            'message' => 'Password reset link sent to your email',
            'reset_token' => $resetToken // Remove this in production
        ];
    }

    // ============================================
    // RESET PASSWORD
    // ============================================

    public function resetPassword($token, $newPassword) {
        if (strlen($newPassword) < 6) {
            return ['success' => false, 'message' => 'Password must be at least 6 characters'];
        }

        // Find user with valid reset token
        $user = db()->fetchOne(
            "SELECT * FROM users WHERE reset_token = ? AND reset_expires > NOW() AND status = 'active'",
            [$token]
        );

        if (!$user) {
            return ['success' => false, 'message' => 'Invalid or expired reset token'];
        }

        // Hash new password
        $passwordHash = password_hash($newPassword, PASSWORD_BCRYPT, ['cost' => 10]);

        // Update password and clear reset token
        db()->query(
            "UPDATE users SET password = ?, reset_token = NULL, reset_expires = NULL WHERE id = ?",
            [$passwordHash, $user['id']]
        );

        // Clear all remember tokens
        db()->query("DELETE FROM user_tokens WHERE user_id = ?", [$user['id']]);

        // Log activity
        logActivity('password_reset', "Password reset completed", $user['id']);

        return ['success' => true, 'message' => 'Password reset successful! You can now login.'];
    }

    // ============================================
    // CART SYNC FUNCTIONS
    // ============================================

    private function syncCartFromDatabase($userId) {
        // Get cart from database
        $dbCart = db()->fetchAll("SELECT * FROM cart WHERE user_id = ?", [$userId]);

        // Merge with session cart
        if (!isset($_SESSION['cart'])) {
            $_SESSION['cart'] = [];
        }

        foreach ($dbCart as $item) {
            $cartKey = $item['product_id'] . '_' . $item['size'];
            if (!isset($_SESSION['cart'][$cartKey])) {
                $_SESSION['cart'][$cartKey] = [
                    'id' => $item['product_id'],
                    'title' => $item['product_title'],
                    'image' => $item['product_image'],
                    'price' => $item['price'],
                    'original_price' => $item['original_price'],
                    'size' => $item['size'],
                    'qty' => $item['quantity']
                ];
            }
        }
    }

    private function syncCartToDatabase($userId) {
        if (!isset($_SESSION['cart']) || empty($_SESSION['cart'])) {
            // Clear database cart
            db()->query("DELETE FROM cart WHERE user_id = ?", [$userId]);
            return;
        }

        // Clear existing cart
        db()->query("DELETE FROM cart WHERE user_id = ?", [$userId]);

        // Insert session cart items
        foreach ($_SESSION['cart'] as $item) {
            Database::getInstance()->insert('cart', [
                'user_id' => $userId,
                'product_id' => $item['id'],
                'product_title' => $item['title'],
                'product_image' => $item['image'],
                'price' => $item['price'],
                'original_price' => $item['original_price'],
                'size' => $item['size'],
                'quantity' => $item['qty']
            ]);
        }
    }

    // ============================================
    // CSRF PROTECTION
    // ============================================

    public function getCsrfToken() {
        return $_SESSION['csrf_token'] ?? '';
    }

    public function validateCsrfToken($token) {
        return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
    }

    public function regenerateCsrfToken() {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        return $_SESSION['csrf_token'];
    }

    // ============================================
    // REQUIRE LOGIN
    // ============================================

    public function requireLogin() {
        if (!$this->isLoggedIn()) {
            $_SESSION['redirect_after_login'] = $_SERVER['REQUEST_URI'] ?? '/';
            header('Location: /login.php');
            exit;
        }
    }

    // ============================================
    // DELETE ACCOUNT
    // ============================================

    public function deleteAccount($password) {
        $user = $this->getCurrentUser();
        
        if (!$user) {
            return ['success' => false, 'message' => 'User not logged in'];
        }

        // Verify password
        if (!password_verify($password, $user['password'])) {
            return ['success' => false, 'message' => 'Incorrect password'];
        }

        // Soft delete (set status to inactive)
        db()->query("UPDATE users SET status = 'inactive', email = CONCAT(email, '_deleted_', id) WHERE id = ?", [$user['id']]);

        // Logout
        $this->logout();

        // Log activity
        logActivity('account_deleted', "User deleted account", $user['id']);

        return ['success' => true, 'message' => 'Account deleted successfully'];
    }
}

// Global auth instance
function auth() {
    return Auth::getInstance();
}
