import os
import pytest
from datetime import datetime

from strands import Agent
from strands.session.session_repository import Session, SessionAgent, SessionMessage
from supabase_strands import SupabaseSessionManager


@pytest.fixture
def supabase_url():
    """Get Supabase URL from environment."""
    url = os.getenv("SUPABASE_URL")
    if not url:
        pytest.skip("SUPABASE_URL not set")
    return url


@pytest.fixture
def supabase_key():
    """Get Supabase key from environment."""
    key = os.getenv("SUPABASE_KEY")
    if not key:
        pytest.skip("SUPABASE_KEY not set")
    return key


@pytest.fixture
def session_manager(supabase_url, supabase_key):
    """Create session manager with real Supabase connection."""
    session_id = f"test-{datetime.utcnow().timestamp()}"
    manager = SupabaseSessionManager(
        session_id=session_id,
        supabase_url=supabase_url,
        supabase_key=supabase_key,
    )
    yield manager
    # Cleanup
    try:
        manager.delete_session(session_id)
    except:
        pass


def test_session_lifecycle(session_manager):
    """Test complete session lifecycle."""
    session = Session(
        session_id=session_manager.session_id,
        session_type="AGENT",
        created_at=datetime.utcnow().isoformat(),
        updated_at=datetime.utcnow().isoformat(),
    )
    
    # Create
    created = session_manager.create_session(session)
    assert created.session_id == session.session_id
    
    # Read
    read = session_manager.read_session(session.session_id)
    assert read is not None
    assert read.session_id == session.session_id
    
    # Delete
    session_manager.delete_session(session.session_id)
    deleted = session_manager.read_session(session.session_id)
    assert deleted is None


def test_agent_persistence(session_manager):
    """Test agent state persistence."""
    # Create session first
    session = Session(
        session_id=session_manager.session_id,
        session_type="AGENT",
        created_at=datetime.utcnow().isoformat(),
        updated_at=datetime.utcnow().isoformat(),
    )
    session_manager.create_session(session)
    
    # Create agent
    agent = SessionAgent(
        agent_id="test-agent",
        state={"counter": 1},
        conversation_manager_state={},
        _internal_state={},
        created_at=datetime.utcnow().isoformat(),
        updated_at=datetime.utcnow().isoformat(),
    )
    session_manager.create_agent(session_manager.session_id, agent)
    
    # Read agent
    read_agent = session_manager.read_agent(session_manager.session_id, "test-agent")
    assert read_agent is not None
    assert read_agent.state["counter"] == 1
    
    # Update agent
    agent.state["counter"] = 2
    session_manager.update_agent(session_manager.session_id, agent)
    
    # Verify update
    updated_agent = session_manager.read_agent(session_manager.session_id, "test-agent")
    assert updated_agent.state["counter"] == 2


def test_message_persistence(session_manager):
    """Test message persistence."""
    # Setup session and agent
    session = Session(
        session_id=session_manager.session_id,
        session_type="AGENT",
        created_at=datetime.utcnow().isoformat(),
        updated_at=datetime.utcnow().isoformat(),
    )
    session_manager.create_session(session)
    
    agent = SessionAgent(
        agent_id="test-agent",
        state={},
        conversation_manager_state={},
        _internal_state={},
        created_at=datetime.utcnow().isoformat(),
        updated_at=datetime.utcnow().isoformat(),
    )
    session_manager.create_agent(session_manager.session_id, agent)
    
    # Create messages
    msg1 = SessionMessage(
        message_id=0,
        message={"role": "user", "content": "Hello"},
        redact_message=None,
        created_at=datetime.utcnow().isoformat(),
        updated_at=datetime.utcnow().isoformat(),
    )
    msg2 = SessionMessage(
        message_id=1,
        message={"role": "assistant", "content": "Hi there"},
        redact_message=None,
        created_at=datetime.utcnow().isoformat(),
        updated_at=datetime.utcnow().isoformat(),
    )
    
    session_manager.create_message(session_manager.session_id, "test-agent", msg1)
    session_manager.create_message(session_manager.session_id, "test-agent", msg2)
    
    # List messages
    messages = session_manager.list_messages(session_manager.session_id, "test-agent")
    assert len(messages) == 2
    assert messages[0].message["content"] == "Hello"
    assert messages[1].message["content"] == "Hi there"


def test_multi_shot_conversation(supabase_url, supabase_key):
    """Test multi-shot conversation persistence across agent instances."""
    session_id = f"multishot-{datetime.utcnow().timestamp()}"
    
    # First conversation
    manager1 = SupabaseSessionManager(
        session_id=session_id,
        supabase_url=supabase_url,
        supabase_key=supabase_key,
    )
    agent1 = Agent(session_manager=manager1)
    response1 = agent1("Remember this number: 42")
    
    # Second conversation - new agent instance, same session
    manager2 = SupabaseSessionManager(
        session_id=session_id,
        supabase_url=supabase_url,
        supabase_key=supabase_key,
    )
    agent2 = Agent(session_manager=manager2)
    response2 = agent2("What number did I tell you to remember?")
    
    # Verify conversation history persisted
    messages = manager2.list_messages(session_id, agent2.agent_id)
    assert len(messages) >= 2
    
    # Cleanup
    manager2.delete_session(session_id)
