import json
import pytest
from DataCache_v3 import DataCache
from Users import Users


@pytest.fixture
def data_cache():
    """Create a fresh DataCache for each test."""
    return DataCache()


@pytest.fixture
def users(data_cache):
    """Create a Users instance with the data cache."""
    return Users(data_cache=data_cache)


class TestUsers:
    """Tests for the Users class."""

    def test_create_guest(self, users):
        """Test creating a guest user."""
        result = users.create_guest()
        print(f'\n Test result: {result}')
        assert isinstance(result, str)
        assert result.startswith('guest_')

    def test_create_unique_guest_name(self, users):
        """Test creating unique guest names."""
        result = users.create_unique_guest_name()
        print(f'\n Test result: {result}')
        assert isinstance(result, str)
        assert result.startswith('guest_')

    def test_user_attr_is_taken(self, users):
        """Test checking if user attribute is taken."""
        # Create a test user first
        users.create_guest()

        # Check for a name that doesn't exist
        result = users.user_attr_is_taken('user_name', 'nonexistent_user_12345')
        print(f'\n Test result for nonexistent: {result}')
        assert isinstance(result, bool)
        assert result is False

    def test_scramble_text(self, users):
        """Test text scrambling (for password hashing)."""
        original = 'SomeText'
        result = users.scramble_text(original)
        print(f'\n Test result: {result}')
        assert isinstance(result, str)
        assert result != original  # Should be different from original

    def test_create_new_user(self, users):
        """Test creating a new user with credentials."""
        import random
        username = f'test_user_{random.randint(1000, 9999)}'
        result = users.create_new_user(
            username=username,
            email=f'{username}@email.com',
            password='test_password123'
        )
        print(f'\n Test result: {result}')
        assert result is True

    def test_load_or_create_user_creates_guest(self, users):
        """Test that load_or_create_user creates a guest if user doesn't exist."""
        result = users.load_or_create_user(None)
        print(f'\n Test result: {result}')
        assert isinstance(result, str)
        assert result.startswith('guest_')

    def test_get_id_after_create(self, users):
        """Test getting user ID after creation."""
        guest_name = users.create_guest()
        result = users.get_id(guest_name)
        print(f'\n Test result: {result}')
        assert result is not None
        assert isinstance(result, int)

    def test_get_username_by_id(self, users):
        """Test getting username by ID."""
        guest_name = users.create_guest()
        user_id = users.get_id(guest_name)
        result = users.get_username(user_id)
        print(f'\n Test result: {result}')
        assert result == guest_name

    def test_is_logged_in_false(self, users):
        """Test that a new guest is not logged in."""
        guest_name = users.create_guest()
        result = users.is_logged_in(guest_name)
        print(f'\n Test result: {result}')
        assert isinstance(result, bool)

    def test_validate_password(self, users):
        """Test password validation."""
        import random
        username = f'test_user_{random.randint(1000, 9999)}'
        password = 'correct_password123'
        users.create_new_user(username=username, email=f'{username}@test.com', password=password)

        # Should return True for correct password
        result = users.validate_password(username=username, password=password)
        print(f'\n Test result correct password: {result}')
        assert result is True

        # Should return False for wrong password
        result = users.validate_password(username=username, password='wrong_password')
        print(f'\n Test result wrong password: {result}')
        assert result is False

    def test_get_chart_view(self, users):
        """Test getting chart view settings."""
        guest_name = users.create_guest()

        # Get specific property
        result = users.get_chart_view(user_name=guest_name, prop='timeframe')
        print(f'\n Test result timeframe: {result}')

        # Get all chart view settings
        result = users.get_chart_view(user_name=guest_name)
        print(f'\n Test result all: {result}')
        # Result can be None or a dict, both are valid

    def test_log_out_all_users(self, users):
        """Test logging out all users."""
        result = users.log_out_all_users()
        print(f'\n Test result: {result}')
        # Should complete without error

    def test_save_and_get_indicators(self, users, data_cache):
        """Test saving and retrieving indicators."""
        # Create the indicators cache if it doesn't exist
        if 'indicators' not in data_cache.caches:
            data_cache.create_cache('indicators', cache_type='row')

        guest_name = users.create_guest()

        # Get indicators (may be empty initially)
        result = users.get_indicators(guest_name)
        print(f'\n Test result get: {result}')
        # Result can be None or a DataFrame, both are valid
