import pytest
import time
from src.api_hook_client import ApiHookClient

@pytest.mark.integration
def test_undo_redo_lifecycle(live_gui):
 client = ApiHookClient()
 client.click("btn_reset")
 time.sleep(2)
 
 assert client.wait_for_server(timeout=15), "Hook server did not start"

 # 1. Set initial state
 print("Setting initial state...")
 client.set_value('temperature', 0.5)
 client.set_value('ai_input', "Initial Input")

 # Wait for settle and first push (S_init -> S0)
 time.sleep(3.0)

 # 2. Change state
 print("Modifying state...")
 client.set_value('temperature', 1.5)
 client.set_value('ai_input', "Modified Input")

 # Wait for settle and second push (S0 -> S1)
 time.sleep(3.0)

 # Verify current state
 temp = client.get_value('temperature')
 ai_in = client.get_value('ai_input')
 print(f"Current state: temp={temp}, ai_input={ai_in}")
 assert temp == 1.5
 assert ai_in == "Modified Input"

 # 3. Undo (S1 -> S0)
 print("Sending Undo...")
 client.click('btn_undo')
 time.sleep(2.0)
 
 assert client.get_value('ai_input') == "Initial Input"
 assert client.get_value('temperature') == 0.5

 # 4. Redo (S0 -> S1)
 print("Sending Redo...")
 client.click('btn_redo')
 time.sleep(2.0)
 
 assert client.get_value('ai_input') == "Modified Input"
 assert client.get_value('temperature') == 1.5

@pytest.mark.integration
def test_undo_redo_discussion_mutation(live_gui):
 client = ApiHookClient()
 client.click("btn_reset")
 time.sleep(2)
 
 assert client.wait_for_server(timeout=15)

 # Get initial entries count
 initial_entries = client.get_value('disc_entries')
 initial_count = len(initial_entries)
 print(f"Initial entries: {initial_count}")

 # 1. Add an entry (we simulate this by appending to disc_entries)
 # Wait for settle
 time.sleep(2.0)

 new_entries = initial_entries + [{"role": "User", "content": "New Entry", "collapsed": False, "ts": "2026-03-11 12:00:00"}]
 client.set_value('disc_entries', new_entries)

 # Wait for debounce
 time.sleep(2.0)
 assert len(client.get_value('disc_entries')) == initial_count + 1

 # 2. Undo the addition
 print("Undoing entry addition...")
 client.click('btn_undo')
 time.sleep(2.0)
 assert len(client.get_value('disc_entries')) == initial_count

 # 3. Redo the addition
 print("Redoing entry addition...")
 client.click('btn_redo')
 time.sleep(2.0)
 assert len(client.get_value('disc_entries')) == initial_count + 1

@pytest.mark.integration
def test_undo_redo_context_mutation(live_gui):
 client = ApiHookClient()
 client.click("btn_reset")
 time.sleep(2)
 
 assert client.wait_for_server(timeout=15)

 # Get initial files
 initial_files = client.get_value('ui_file_paths')
 initial_count = len(initial_files)

 # 1. Add a file
 time.sleep(2.0)
 new_files = initial_files + ["test_undo.py"]
 client.set_value('ui_file_paths', new_files)
 
 time.sleep(2.0)
 assert len(client.get_value('ui_file_paths')) == initial_count + 1
 assert "test_undo.py" in client.get_value('ui_file_paths')

 # 2. Undo addition
 print("Undoing file addition...")
 client.click('btn_undo')
 time.sleep(2.0)
 assert len(client.get_value('ui_file_paths')) == initial_count
 assert "test_undo.py" not in client.get_value('ui_file_paths')

 # 3. Redo addition
 print("Redoing file addition...")
 client.click('btn_redo')
 time.sleep(2.0)
 assert len(client.get_value('ui_file_paths')) == initial_count + 1
 assert "test_undo.py" in client.get_value('ui_file_paths')
