from sqlalchemy import Column, String, Integer, ForeignKey, DateTime, Enum, JSON, Boolean, Text
from sqlalchemy.orm import relationship
import uuid
import datetime
from app.db.database import Base

class AgentTemplate(Base):
    __tablename__ = 'agent_templates'

    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    name = Column(String, nullable=False)
    description = Column(String, nullable=True)
    system_prompt_path = Column(String, nullable=True)
    user_id = Column(String, ForeignKey('users.id'), nullable=True, index=True)
    max_loop_iterations = Column(Integer, default=20)

    @property
    def system_prompt_content(self):
        """Helper to return the prompt content, aliasing system_prompt_path for now."""
        return self.system_prompt_path

    @system_prompt_content.setter
    def system_prompt_content(self, value):
        self.system_prompt_path = value
    
    # Co-Worker Loop Settings
    co_worker_quality_gate = Column(Boolean, default=False)
    rework_threshold = Column(Integer, default=80) 
    max_rework_attempts = Column(Integer, default=3)

    instances = relationship("AgentInstance", back_populates="template")

class AgentInstance(Base):
    __tablename__ = 'agent_instances'

    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    user_id = Column(String, ForeignKey('users.id'), nullable=True, index=True)
    template_id = Column(String, ForeignKey('agent_templates.id'), nullable=False, index=True)
    session_id = Column(Integer, ForeignKey('sessions.id'), nullable=True, index=True)
    mesh_node_id = Column(String, nullable=True, index=True) # Just use string or connect to agent_nodes.node_id if needed
    status = Column(String, default='idle', index=True) # Enum: active, idle, listening, error_suspended
    current_workspace_jail = Column(String, nullable=True)
    last_heartbeat = Column(DateTime, default=datetime.datetime.utcnow)
    
    # Execution Metrics
    total_runs = Column(Integer, default=0)
    successful_runs = Column(Integer, default=0)
    total_tokens_accumulated = Column(Integer, default=0)
    total_input_tokens = Column(Integer, default=0)
    total_output_tokens = Column(Integer, default=0)
    total_running_time_seconds = Column(Integer, default=0)
    tool_call_counts = Column(JSON, default=dict)
    last_reasoning = Column(Text, nullable=True) # Real-time thought stream
    last_error = Column(String, nullable=True) # Diagnostic message if status="error_suspended"
    
    # Co-Worker State
    evaluation_status = Column(String, nullable=True) # "evaluating", "reworking", "passed"
    current_rework_attempt = Column(Integer, default=0)
    latest_quality_score = Column(Integer, nullable=True)


    template = relationship("AgentTemplate", back_populates="instances")
    session = relationship("Session", primaryjoin="AgentInstance.session_id == Session.id")
    triggers = relationship("AgentTrigger", back_populates="instance", cascade="all, delete-orphan")
    
class AgentTrigger(Base):
    __tablename__ = 'agent_triggers'

    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    instance_id = Column(String, ForeignKey('agent_instances.id'), nullable=False, index=True)
    trigger_type = Column(String, nullable=False) # Enum: webhook, cron, interval, manual
    cron_expression = Column(String, nullable=True)
    interval_seconds = Column(Integer, nullable=True) # For interval trigger
    default_prompt = Column(String, nullable=True) # Predefined prompt for any trigger
    webhook_secret = Column(String, nullable=True)
    webhook_mapping_schema = Column(JSON, default=dict)
    
    instance = relationship("AgentInstance", back_populates="triggers")
