"""Global todo task management using SQLite"""

import sqlite3
from dataclasses import dataclass
from datetime import datetime
from typing import Optional, List
from enum import Enum


class TaskStatus(Enum):
    PENDING = "pending"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    CANCELLED = "cancelled"


@dataclass
class TodoTask:
    id: int
    title: str
    description: str
    status: TaskStatus
    priority: int
    created_at: str
    updated_at: str
    completed_at: Optional[str] = None


class GlobalTodoTask:
    def __init__(self):
        self._db_path = None
        self._conn = None
        self._init_db()
    
    def _get_db_path(self) -> str:
        if self._db_path is None:
            from diona.project.storage import get_storage_instance
            storage = get_storage_instance()
            self._db_path = storage.get_path("agent", "global_todotask.db", storage_type="user")
        return self._db_path
    
    def _get_connection(self) -> sqlite3.Connection:
        if self._conn is None:
            self._conn = sqlite3.connect(self._get_db_path())
            self._conn.row_factory = sqlite3.Row
        return self._conn
    
    def _init_db(self):
        conn = self._get_connection()
        cursor = conn.cursor()
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS todo_tasks (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                title TEXT NOT NULL,
                description TEXT DEFAULT '',
                status TEXT DEFAULT 'pending',
                priority INTEGER DEFAULT 0,
                created_at TEXT NOT NULL,
                updated_at TEXT NOT NULL,
                completed_at TEXT
            )
        """)
        conn.commit()
    
    def add_task(self, title: str, description: str = "", priority: int = 0) -> TodoTask:
        """Add a new todo task"""
        now = datetime.now().isoformat()
        conn = self._get_connection()
        cursor = conn.cursor()
        cursor.execute(
            "INSERT INTO todo_tasks (title, description, status, priority, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)",
            (title, description, TaskStatus.PENDING.value, priority, now, now)
        )
        conn.commit()
        task_id = cursor.lastrowid
        return self.get_task(task_id)
    
    def get_task(self, task_id: int) -> Optional[TodoTask]:
        """Get a task by ID"""
        conn = self._get_connection()
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM todo_tasks WHERE id = ?", (task_id,))
        row = cursor.fetchone()
        if row:
            return TodoTask(
                id=row["id"],
                title=row["title"],
                description=row["description"],
                status=TaskStatus(row["status"]),
                priority=row["priority"],
                created_at=row["created_at"],
                updated_at=row["updated_at"],
                completed_at=row["completed_at"]
            )
        return None
    
    def list_tasks(self, status: Optional[TaskStatus] = None, limit: int = 100) -> List[TodoTask]:
        """List all tasks, optionally filtered by status"""
        conn = self._get_connection()
        cursor = conn.cursor()
        
        if status:
            cursor.execute(
                "SELECT * FROM todo_tasks WHERE status = ? ORDER BY priority DESC, created_at DESC LIMIT ?",
                (status.value, limit)
            )
        else:
            cursor.execute(
                "SELECT * FROM todo_tasks ORDER BY priority DESC, created_at DESC LIMIT ?",
                (limit,)
            )
        
        rows = cursor.fetchall()
        return [
            TodoTask(
                id=row["id"],
                title=row["title"],
                description=row["description"],
                status=TaskStatus(row["status"]),
                priority=row["priority"],
                created_at=row["created_at"],
                updated_at=row["updated_at"],
                completed_at=row["completed_at"]
            )
            for row in rows
        ]
    
    def update_task_status(self, task_id: int, status: TaskStatus) -> bool:
        """Update task status"""
        conn = self._get_connection()
        cursor = conn.cursor()
        
        now = datetime.now().isoformat()
        completed_at = now if status == TaskStatus.COMPLETED else None
        
        cursor.execute(
            "UPDATE todo_tasks SET status = ?, updated_at = ?, completed_at = ? WHERE id = ?",
            (status.value, now, completed_at, task_id)
        )
        conn.commit()
        return cursor.rowcount > 0
    
    def update_task(self, task_id: int, title: str = None, description: str = None, priority: int = None) -> bool:
        """Update task details"""
        conn = self._get_connection()
        cursor = conn.cursor()
        
        updates = []
        params = []
        
        if title is not None:
            updates.append("title = ?")
            params.append(title)
        if description is not None:
            updates.append("description = ?")
            params.append(description)
        if priority is not None:
            updates.append("priority = ?")
            params.append(priority)
        
        if not updates:
            return False
        
        updates.append("updated_at = ?")
        params.append(datetime.now().isoformat())
        params.append(task_id)
        
        cursor.execute(f"UPDATE todo_tasks SET {', '.join(updates)} WHERE id = ?", params)
        conn.commit()
        return cursor.rowcount > 0
    
    def delete_task(self, task_id: int) -> bool:
        """Delete a task"""
        conn = self._get_connection()
        cursor = conn.cursor()
        cursor.execute("DELETE FROM todo_tasks WHERE id = ?", (task_id,))
        conn.commit()
        return cursor.rowcount > 0
    
    def mark_pending(self, task_id: int) -> bool:
        """Mark task as pending"""
        return self.update_task_status(task_id, TaskStatus.PENDING)
    
    def mark_in_progress(self, task_id: int) -> bool:
        """Mark task as in progress"""
        return self.update_task_status(task_id, TaskStatus.IN_PROGRESS)
    
    def mark_completed(self, task_id: int) -> bool:
        """Mark task as completed"""
        return self.update_task_status(task_id, TaskStatus.COMPLETED)
    
    def mark_cancelled(self, task_id: int) -> bool:
        """Mark task as cancelled"""
        return self.update_task_status(task_id, TaskStatus.CANCELLED)
    
    def get_pending_tasks(self, limit: int = 100) -> List[TodoTask]:
        """Get all pending tasks"""
        return self.list_tasks(TaskStatus.PENDING, limit)
    
    def get_completed_tasks(self, limit: int = 100) -> List[TodoTask]:
        """Get all completed tasks"""
        return self.list_tasks(TaskStatus.COMPLETED, limit)
    
    def get_stats(self) -> dict:
        """Get task statistics"""
        conn = self._get_connection()
        cursor = conn.cursor()
        
        cursor.execute("SELECT status, COUNT(*) as count FROM todo_tasks GROUP BY status")
        stats = {"total": 0}
        for row in cursor.fetchall():
            stats[row["status"]] = row["count"]
            stats["total"] += row["count"]
        
        return stats


_todo_task: Optional[GlobalTodoTask] = None


def get_global_todo_task() -> GlobalTodoTask:
    """Get the global todo task instance"""
    global _todo_task
    if _todo_task is None:
        _todo_task = GlobalTodoTask()
    return _todo_task
