import json
import os
import uuid
from typing import List, Optional, Any
from pydantic import BaseModel, Field, field_validator
from pathlib import Path
from .paths import get_path_manager


class TodoItem(BaseModel):
    """Todo item model"""

    content: str = Field(..., description="Brief description of the task")
    status: str = Field(
        default="pending", description="Current status: pending, in_progress, completed, cancelled"
    )
    priority: str = Field(
        default="medium", description="Priority level: high, medium, low"
    )
    id: str = Field(default_factory=lambda: str(uuid.uuid4())[:8], description="Unique identifier for the todo item")
    activeForm: Optional[str] = Field(default=None, description="Active form of the task description")

    @field_validator('id', mode='before')
    @classmethod
    def convert_id_to_string(cls, v: Any) -> str:
        """将 id 转换为字符串，兼容 LLM 传递整数的情况"""
        if v is None:
            return str(uuid.uuid4())[:8]
        return str(v)


class TodoManager:
    """Manage todo lists for sessions"""

    def __init__(self, storage_subdir: str = "todos"):
        """
        Initialize TodoManager.

        Args:
            storage_subdir: Subdirectory under data directory for todos
        """
        path_manager = get_path_manager()
        self.storage_dir = path_manager.get_data_dir() / storage_subdir
        self.storage_dir.mkdir(parents=True, exist_ok=True)

    def _get_todo_file(self, session_id: str) -> Path:
        """Get the todo file path for a session"""
        return self.storage_dir / f"{session_id}.json"

    async def update(self, session_id: str, todos: List[TodoItem]) -> None:
        """Update todo list for a session"""
        todo_file = self._get_todo_file(session_id)
        with open(todo_file, "w", encoding="utf-8") as f:
            json.dump([todo.model_dump() for todo in todos], f, indent=2)

    async def get(self, session_id: str) -> List[TodoItem]:
        """Get todo list for a session"""
        todo_file = self._get_todo_file(session_id)
        if not todo_file.exists():
            return []

        try:
            with open(todo_file, "r", encoding="utf-8") as f:
                data = json.load(f)
                return [TodoItem(**item) for item in data]
        except Exception:
            return []

    def get_active_count(self, todos: List[TodoItem]) -> int:
        """Get count of active (non-completed) todos"""
        return len([t for t in todos if t.status != "completed"])
