"""Scheduler for running agents periodically"""
import time
import logging
from datetime import datetime
from sqlalchemy.orm import Session
from app.core.db.database import SessionLocal
from app.core.config import settings
from app.agents.data_ingest_agent import DataIngestAgent
from app.agents.feature_agent import FeatureAgent
from app.agents.training_agent import TrainingAgent
from app.agents.prediction_agent import PredictionAgent
from app.agents.backtest_agent import BacktestAgent
from app.agents.quality_agent import QualityAgent

logger = logging.getLogger(__name__)


class Scheduler:
    """Simple scheduler for agents"""
    
    def __init__(self):
        self.running = False
        self.last_ingest = None
        self.last_features = None
        self.last_predict = None
        self.last_training = None
    
    def run_ingest(self):
        """Run ingest agent"""
        db = SessionLocal()
        try:
            logger.info("Running ingest agent")
            agent = DataIngestAgent(db)
            agent.run()
            self.last_ingest = datetime.now()
        except Exception as e:
            logger.error(f"Error running ingest: {e}", exc_info=True)
        finally:
            db.close()
    
    def run_features(self):
        """Run feature agent"""
        db = SessionLocal()
        try:
            logger.info("Running feature agent")
            agent = FeatureAgent(db)
            agent.run()
            self.last_features = datetime.now()
        except Exception as e:
            logger.error(f"Error running features: {e}", exc_info=True)
        finally:
            db.close()
    
    def run_training(self):
        """Run training agent"""
        if not settings.training_enabled:
            return
        
        db = SessionLocal()
        try:
            logger.info("Running training agent")
            agent = TrainingAgent(db)
            agent.run()
            self.last_training = datetime.now()
        except Exception as e:
            logger.error(f"Error running training: {e}", exc_info=True)
        finally:
            db.close()
    
    def run_predict(self):
        """Run prediction agent"""
        db = SessionLocal()
        try:
            logger.info("Running prediction agent")
            agent = PredictionAgent(db)
            agent.run()
            self.last_predict = datetime.now()
        except Exception as e:
            logger.error(f"Error running predict: {e}", exc_info=True)
        finally:
            db.close()
    
    def should_run_ingest(self) -> bool:
        """Check if ingest should run"""
        if self.last_ingest is None:
            return True
        elapsed = (datetime.now() - self.last_ingest).total_seconds() / 60
        return elapsed >= settings.ingest_interval_minutes
    
    def should_run_features(self) -> bool:
        """Check if features should run"""
        if self.last_features is None:
            return True
        elapsed = (datetime.now() - self.last_features).total_seconds() / 3600
        return elapsed >= settings.features_interval_hours
    
    def should_run_training(self) -> bool:
        """Check if training should run"""
        if not settings.training_enabled:
            return False
        if self.last_training is None:
            return True
        elapsed = (datetime.now() - self.last_training).total_seconds() / 3600
        return elapsed >= settings.training_schedule_hours
    
    def should_run_predict(self) -> bool:
        """Check if predict should run"""
        if self.last_predict is None:
            return True
        elapsed = (datetime.now() - self.last_predict).total_seconds() / 60
        return elapsed >= settings.predict_interval_minutes
    
    def run(self):
        """Run scheduler loop"""
        self.running = True
        logger.info("Scheduler started")
        
        while self.running:
            try:
                # Run ingest
                if self.should_run_ingest():
                    self.run_ingest()
                
                # Run features
                if self.should_run_features():
                    self.run_features()
                
                # Run training
                if self.should_run_training():
                    self.run_training()
                
                # Run predict
                if self.should_run_predict():
                    self.run_predict()
                
                # Sleep for 1 minute
                time.sleep(60)
                
            except KeyboardInterrupt:
                logger.info("Scheduler stopped by user")
                self.running = False
            except Exception as e:
                logger.error(f"Scheduler error: {e}", exc_info=True)
                time.sleep(60)
    
    def stop(self):
        """Stop scheduler"""
        self.running = False


if __name__ == "__main__":
    scheduler = Scheduler()
    try:
        scheduler.run()
    except KeyboardInterrupt:
        scheduler.stop()

