import pytest
import base64
from PIL import Image
import tempfile
import os

from loops.prompted_image import PromptedImage


@pytest.fixture
def fake_jpeg_image():
    """Generate a temporary JPEG file containing a simple image."""
    with tempfile.NamedTemporaryFile(mode='wb', suffix='.jpg', delete=False) as tmp_file:
        jpeg_path = tmp_file.name
        
        # Create a simple 100x100 red image
        img = Image.new('RGB', (100, 100), color='red')
        img.save(jpeg_path, 'JPEG')
        
    yield jpeg_path
    
    # Cleanup
    if os.path.exists(jpeg_path):
        os.unlink(jpeg_path)


def test_read_returns_correct_structure(fake_jpeg_image):
    """Test that read() returns the correct LangChain-compatible structure."""
    inspiration = PromptedImage(fake_jpeg_image)
    result = inspiration.read()
    
    # Check structure
    assert isinstance(result, dict)
    assert "type" in result
    assert "image_url" in result
    assert result["type"] == "image_url"
    assert isinstance(result["image_url"], dict)
    assert "url" in result["image_url"]


def test_read_returns_base64_encoded_image(fake_jpeg_image):
    """Test that read() returns valid base64-encoded image data."""
    inspiration = PromptedImage(fake_jpeg_image)
    result = inspiration.read()
    
    # Extract the base64 data
    url = result["image_url"]["url"]
    assert url.startswith("data:image/jpeg;base64,")
    
    # Extract and decode the base64 part
    base64_data = url.split(",")[1]
    decoded_data = base64.b64decode(base64_data)
    
    # Verify it's valid image data by checking it can be read
    assert len(decoded_data) > 0
    
    # Compare with original file
    with open(fake_jpeg_image, "rb") as f:
        original_data = f.read()
    
    assert decoded_data == original_data


def test_read_nonexistent_file():
    """Test that read() raises FileNotFoundError for non-existent files."""
    inspiration = PromptedImage("/nonexistent/path/to/image.jpg")
    
    with pytest.raises(FileNotFoundError):
        inspiration.read()


def test_read_with_different_jpeg_path(fake_jpeg_image):
    """Test that PromptedImage works with different file paths."""
    # Create another temporary JPEG
    with tempfile.NamedTemporaryFile(mode='wb', suffix='.jpeg', delete=False) as tmp_file:
        jpeg_path = tmp_file.name
        img = Image.new('RGB', (50, 50), color='blue')
        img.save(jpeg_path, 'JPEG')
    
    try:
        inspiration = PromptedImage(jpeg_path)
        result = inspiration.read()
        
        assert result["type"] == "image_url"
        assert "data:image/jpeg;base64," in result["image_url"]["url"]
    finally:
        if os.path.exists(jpeg_path):
            os.unlink(jpeg_path)


def test_read_can_be_called_multiple_times(fake_jpeg_image):
    """Test that read() can be called multiple times on the same instance."""
    inspiration = PromptedImage(fake_jpeg_image)
    
    result1 = inspiration.read()
    result2 = inspiration.read()
    
    # Both calls should return the same data
    assert result1 == result2
    assert result1["image_url"]["url"] == result2["image_url"]["url"]
