"""
Daily Routine Automation Service
Handles scheduling and execution of daily trading routines
"""

from datetime import datetime, time
from typing import List, Dict, Optional
from sqlalchemy.orm import Session
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from app.models.models import DailyRoutine, RoutineExecution, Notification
from app.services.ai_analysis import analyze_trade
from app.services.news_service import fetch_news
from app.models.models import Trade, Simulation


class RoutineTask:
    """Base class for routine tasks"""

    def __init__(self, task_name: str):
        self.task_name = task_name

    async def execute(self, db: Session) -> Dict:
        """Execute the task and return results"""
        raise NotImplementedError


class MarketBriefTask(RoutineTask):
    """Generate daily market brief"""

    def __init__(self):
        super().__init__("market_brief")

    async def execute(self, db: Session) -> Dict:
        """Generate market brief with current price and news"""
        try:
            news = await fetch_news()
            return {
                "success": True,
                "task": self.task_name,
                "data": {
                    "news_articles": len(news.get("articles", [])),
                    "overall_sentiment": news.get("overall_sentiment"),
                    "timestamp": datetime.utcnow().isoformat()
                }
            }
        except Exception as e:
            return {
                "success": False,
                "task": self.task_name,
                "error": str(e)
            }


class ReviewPlanTask(RoutineTask):
    """Review trading plan for the day"""

    def __init__(self):
        super().__init__("review_plan")

    async def execute(self, db: Session) -> Dict:
        """Review and validate trading plan"""
        try:
            # In future, this would validate actual trading plans
            return {
                "success": True,
                "task": self.task_name,
                "data": {
                    "plan_status": "active",
                    "timestamp": datetime.utcnow().isoformat()
                }
            }
        except Exception as e:
            return {
                "success": False,
                "task": self.task_name,
                "error": str(e)
            }


class ChecklistTask(RoutineTask):
    """Initialize daily checklist"""

    def __init__(self):
        super().__init__("checklist")

    async def execute(self, db: Session) -> Dict:
        """Initialize checklist for the day"""
        try:
            from app.models.models import DailyChecklist
            from datetime import date

            # Check if checklist already exists
            existing = db.query(DailyChecklist).filter(
                DailyChecklist.checklist_date == date.today()
            ).first()

            if not existing:
                checklist = DailyChecklist(
                    checklist_date=date.today(),
                    checklist_type="morning",
                    items=[
                        {"id": "1", "title": "Check Economic Calendar", "completed": False},
                        {"id": "2", "title": "Scan Market News", "completed": False},
                        {"id": "3", "title": "Analyze Market Sentiment", "completed": False},
                        {"id": "4", "title": "Identify Key Levels", "completed": False},
                        {"id": "5", "title": "Create Trading Plan", "completed": False},
                    ]
                )
                db.add(checklist)
                db.commit()

            return {
                "success": True,
                "task": self.task_name,
                "data": {
                    "checklist_created": existing is None,
                    "timestamp": datetime.utcnow().isoformat()
                }
            }
        except Exception as e:
            return {
                "success": False,
                "task": self.task_name,
                "error": str(e)
            }


class PerformanceReviewTask(RoutineTask):
    """Review daily trading performance"""

    def __init__(self):
        super().__init__("performance_review")

    async def execute(self, db: Session) -> Dict:
        """Calculate and review daily performance metrics"""
        try:
            # Get today's trades
            from datetime import date, datetime as dt
            today = date.today()

            trades = db.query(Trade).filter(
                db.func.date(Trade.timestamp) == today
            ).all()

            daily_pnl = sum(trade.pnl or 0 for trade in trades)
            winning_trades = sum(1 for trade in trades if (trade.pnl or 0) > 0)
            losing_trades = sum(1 for trade in trades if (trade.pnl or 0) < 0)

            return {
                "success": True,
                "task": self.task_name,
                "data": {
                    "trades_count": len(trades),
                    "daily_pnl": daily_pnl,
                    "winning_trades": winning_trades,
                    "losing_trades": losing_trades,
                    "timestamp": datetime.utcnow().isoformat()
                }
            }
        except Exception as e:
            return {
                "success": False,
                "task": self.task_name,
                "error": str(e)
            }


class RoutineService:
    """Service for managing and executing daily routines"""

    # Task registry
    TASK_REGISTRY = {
        "market_brief": MarketBriefTask,
        "review_plan": ReviewPlanTask,
        "checklist": ChecklistTask,
        "performance_review": PerformanceReviewTask,
    }

    @staticmethod
    def get_task(task_name: str) -> Optional[RoutineTask]:
        """Get task instance by name"""
        task_class = RoutineService.TASK_REGISTRY.get(task_name)
        if task_class:
            return task_class()
        return None

    @staticmethod
    async def execute_routine(
        routine: DailyRoutine,
        db: Session
    ) -> RoutineExecution:
        """Execute a complete routine with all its tasks"""

        tasks_completed = []
        failed_tasks = []

        for task_name in (routine.tasks or []):
            task = RoutineService.get_task(task_name)
            if task:
                result = await task.execute(db)
                if result["success"]:
                    tasks_completed.append(task_name)
                else:
                    failed_tasks.append(task_name)

        # Determine completion status
        if not failed_tasks:
            status = "completed"
        elif len(tasks_completed) > 0:
            status = "partial"
        else:
            status = "failed"

        # Create execution record
        execution = RoutineExecution(
            routine_id=routine.id,
            completion_status=status,
            tasks_completed=tasks_completed,
            execution_notes=f"Completed: {len(tasks_completed)}/{len(routine.tasks or [])} tasks"
        )

        db.add(execution)
        db.commit()
        db.refresh(execution)

        return execution

    @staticmethod
    def parse_time(time_str: str) -> time:
        """Parse time string HH:MM format"""
        try:
            hours, minutes = map(int, time_str.split(":"))
            return time(hour=hours, minute=minutes)
        except:
            return time(9, 0)  # Default to 9:00

    @staticmethod
    def should_run_routine(routine: DailyRoutine) -> bool:
        """Check if routine should run now"""
        if not routine.enabled:
            return False

        routine_time = RoutineService.parse_time(routine.scheduled_time)
        current_time = datetime.now().time()

        # Allow 5-minute window for execution
        time_diff = (
            datetime.combine(datetime.today(), current_time) -
            datetime.combine(datetime.today(), routine_time)
        ).total_seconds()

        return 0 <= time_diff <= 300  # 5 minutes


class RoutineScheduler:
    """Scheduler for automated routine execution"""

    def __init__(self):
        self.scheduler: Optional[AsyncIOScheduler] = None

    async def initialize(self):
        """Initialize the scheduler"""
        from apscheduler.schedulers.asyncio import AsyncIOScheduler
        self.scheduler = AsyncIOScheduler()
        self.scheduler.start()

        # Add job to check and run routines every minute
        self.scheduler.add_job(
            self.check_and_run_routines,
            "interval",
            minutes=1,
            id="routine_checker"
        )

    async def check_and_run_routines(self, db: Session = None):
        """Check if any routines should run and execute them"""
        if not db:
            from app.db.database import SessionLocal
            db = SessionLocal()

        try:
            routines = db.query(DailyRoutine).filter(
                DailyRoutine.enabled == True
            ).all()

            for routine in routines:
                if RoutineService.should_run_routine(routine):
                    await RoutineService.execute_routine(routine, db)
        finally:
            db.close()

    async def shutdown(self):
        """Shutdown the scheduler"""
        if self.scheduler:
            self.scheduler.shutdown()


# Global scheduler instance
routine_scheduler = RoutineScheduler()
