import sys
import os
import time
import pytest
from api_hook_client import ApiHookClient
from simulation.workflow_sim import WorkflowSimulator

# Ensure project root is in path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))

class BaseSimulation:
    def __init__(self, client: ApiHookClient = None):
        if client is None:
            self.client = ApiHookClient()
        else:
            self.client = client
        
        self.sim = WorkflowSimulator(self.client)
        self.project_path = None

    def setup(self, project_name="SimProject"):
        print(f"\n[BaseSim] Connecting to GUI...")
        if not self.client.wait_for_server(timeout=5):
            raise RuntimeError("Could not connect to GUI. Ensure it is running with --enable-test-hooks")

        print("[BaseSim] Resetting session...")
        self.client.click("btn_reset")
        time.sleep(0.5)

        git_dir = os.path.abspath(".")
        self.project_path = os.path.abspath(f"tests/temp_{project_name.lower()}.toml")
        if os.path.exists(self.project_path):
            os.remove(self.project_path)

        print(f"[BaseSim] Scaffolding Project: {project_name}")
        self.sim.setup_new_project(project_name, git_dir, self.project_path)
        
        # Standard test settings
        self.client.set_value("auto_add_history", True)
        self.client.set_value("current_provider", "gemini")
        self.client.set_value("current_model", "gemini-2.5-flash-lite")
        time.sleep(0.2)

    def teardown(self):
        if self.project_path and os.path.exists(self.project_path):
            # We keep it for debugging if it failed, but usually we'd clean up
            # os.remove(self.project_path)
            pass
        print("[BaseSim] Teardown complete.")

    def get_value(self, tag):
        return self.client.get_value(tag)

    def wait_for_event(self, event_type, timeout=5):
        return self.client.wait_for_event(event_type, timeout)

    def assert_panel_visible(self, panel_tag, msg=None):
        # This assumes we have a hook to check panel visibility or just check if an element in it exists
        # For now, we'll check if we can get a value from an element that should be in that panel
        # or use a specific hook if available.
        # Actually, let's just check if get_indicator_state or similar works for generic tags.
        pass

    def wait_for_element(self, tag, timeout=2):
        start = time.time()
        while time.time() - start < timeout:
            try:
                # If we can get_value without error, it's likely there
                self.client.get_value(tag)
                return True
            except:
                time.sleep(0.1)
        return False

def run_sim(sim_class):
    """Helper to run a simulation class standalone."""
    sim = sim_class()
    try:
        sim.setup()
        sim.run()
        print(f"\n[SUCCESS] {sim_class.__name__} completed successfully.")
    except Exception as e:
        print(f"\n[FAILURE] {sim_class.__name__} failed: {e}")
        import traceback
        traceback.print_exc()
        sys.exit(1)
    finally:
        sim.teardown()
