"""
Task Manager for breaking down and executing coding tasks
"""
from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum
import asyncio
from pathlib import Path
import json

class TaskStatus(Enum):
    PENDING = "pending"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    FAILED = "failed"

@dataclass
class Task:
    id: str
    description: str
    dependencies: List[str]
    status: TaskStatus
    solution: Optional[Dict] = None
    error: Optional[str] = None

class TaskManager:
    def __init__(self, workspace_path: str):
        self.workspace_path = Path(workspace_path)
        self.tasks: Dict[str, Task] = {}
        self.todo_file = self.workspace_path / "TODO.md"
        self._load_existing_tasks()
        
    def _load_existing_tasks(self):
        """Load existing tasks from TODO.md"""
        if self.todo_file.exists():
            content = self.todo_file.read_text()
            # Parse markdown TODO file
            # This is a simple implementation - could be enhanced
            for line in content.split("\n"):
                if line.startswith("- [ ]"):
                    task_desc = line[5:].strip()
                    self._create_task(task_desc)
                elif line.startswith("- [x]"):
                    task_desc = line[5:].strip()
                    task = self._create_task(task_desc)
                    task.status = TaskStatus.COMPLETED
                    
    def _create_task(self, description: str) -> Task:
        """Create a new task"""
        task_id = f"task_{len(self.tasks) + 1}"
        task = Task(
            id=task_id,
            description=description,
            dependencies=[],
            status=TaskStatus.PENDING
        )
        self.tasks[task_id] = task
        return task
        
    async def create_task_list(self, request: str, analysis: Dict) -> List[str]:
        """Create list of tasks from request analysis"""
        tasks = []
        
        # Convert high-level actions into concrete tasks
        for action in analysis.get("actions", []):
            task_desc = self._convert_action_to_task(action)
            task = self._create_task(task_desc)
            tasks.append(task.id)
            
        # Add file-specific tasks
        for file in analysis.get("files", []):
            task_desc = f"Modify file: {file}"
            task = self._create_task(task_desc)
            tasks.append(task.id)
            
        # Add dependency tasks
        for dep in analysis.get("dependencies", []):
            task_desc = f"Add dependency: {dep}"
            task = self._create_task(task_desc)
            tasks.append(task.id)
            
        # Update TODO.md
        self._update_todo_file()
        
        return tasks
        
    def _convert_action_to_task(self, action: str) -> str:
        """Convert high-level action to concrete task"""
        # This could be enhanced with LLM to better break down actions
        return action
        
    def _update_todo_file(self):
        """Update TODO.md with current tasks"""
        content = "# TODO\n\n"
        
        # Add pending tasks
        content += "## Pending\n"
        for task in self.tasks.values():
            if task.status == TaskStatus.PENDING:
                content += f"- [ ] {task.description}\n"
                
        # Add completed tasks
        content += "\n## Completed\n"
        for task in self.tasks.values():
            if task.status == TaskStatus.COMPLETED:
                content += f"- [x] {task.description}\n"
                
        # Add failed tasks
        content += "\n## Failed\n"
        for task in self.tasks.values():
            if task.status == TaskStatus.FAILED:
                content += f"- [!] {task.description}\n"
                if task.error:
                    content += f"  - Error: {task.error}\n"
                    
        self.todo_file.write_text(content)
        
    def get_next_task(self) -> Optional[Task]:
        """Get next task to execute"""
        for task in self.tasks.values():
            if task.status == TaskStatus.PENDING:
                # Check if all dependencies are completed
                deps_completed = all(
                    self.tasks[dep].status == TaskStatus.COMPLETED
                    for dep in task.dependencies
                )
                if deps_completed:
                    return task
        return None
        
    async def execute_task(self, task: Task, solution: Dict) -> bool:
        """Execute a task with given solution"""
        task.status = TaskStatus.IN_PROGRESS
        
        try:
            # Apply code changes
            for change in solution.get("code_changes", []):
                await self._apply_code_change(change)
                
            # Run tests if specified
            for test in solution.get("tests", []):
                await self._run_test(test)
                
            # Run validation steps
            for step in solution.get("validation", []):
                await self._validate_step(step)
                
            task.status = TaskStatus.COMPLETED
            self._update_todo_file()
            return True
            
        except Exception as e:
            task.status = TaskStatus.FAILED
            task.error = str(e)
            self._update_todo_file()
            return False
            
    async def _apply_code_change(self, change: str):
        """Apply a code change"""
        # This would implement the actual file modifications
        pass
        
    async def _run_test(self, test: str):
        """Run a test case"""
        # This would implement test execution
        pass
        
    async def _validate_step(self, step: str):
        """Run a validation step"""
        # This would implement validation
        pass
        
    def mark_complete(self, task: Task):
        """Mark task as complete"""
        task.status = TaskStatus.COMPLETED
        self._update_todo_file()
        
    def mark_failed(self, task: Task, error: Optional[str] = None):
        """Mark task as failed"""
        task.status = TaskStatus.FAILED
        task.error = error
        self._update_todo_file()
        
    def is_complete(self) -> bool:
        """Check if all tasks are completed"""
        return all(
            task.status in [TaskStatus.COMPLETED, TaskStatus.FAILED]
            for task in self.tasks.values()
        )
