"""
Mail Database - Inbox Task Operations.
"""

import uuid
from typing import Optional, List, Dict
from datetime import datetime, timedelta

from .mail_db_pool import get_pool


async def create_task(
    user_id: str,
    tenant_id: str,
    title: str,
    description: Optional[str] = None,
    priority: str = "medium",
    deadline: Optional[datetime] = None,
    email_id: Optional[str] = None,
    account_id: Optional[str] = None,
    source_email_subject: Optional[str] = None,
    source_sender: Optional[str] = None,
    source_sender_type: Optional[str] = None,
    ai_extracted: bool = False,
    confidence_score: Optional[float] = None,
) -> Optional[str]:
    """Create a new inbox task."""
    pool = await get_pool()
    if pool is None:
        return None

    task_id = str(uuid.uuid4())
    try:
        async with pool.acquire() as conn:
            await conn.execute(
                """
                INSERT INTO inbox_tasks
                (id, user_id, tenant_id, title, description, priority, deadline,
                 email_id, account_id, source_email_subject, source_sender,
                 source_sender_type, ai_extracted, confidence_score)
                VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
                """,
                task_id, user_id, tenant_id, title, description, priority, deadline,
                email_id, account_id, source_email_subject, source_sender,
                source_sender_type, ai_extracted, confidence_score
            )
        return task_id
    except Exception as e:
        print(f"Failed to create task: {e}")
        return None


async def get_tasks(
    user_id: str,
    status: Optional[str] = None,
    priority: Optional[str] = None,
    include_completed: bool = False,
    limit: int = 50,
    offset: int = 0,
) -> List[Dict]:
    """Get tasks for a user."""
    pool = await get_pool()
    if pool is None:
        return []

    try:
        async with pool.acquire() as conn:
            conditions = ["user_id = $1"]
            params = [user_id]
            param_idx = 2

            if not include_completed:
                conditions.append("status != 'completed'")

            if status:
                conditions.append(f"status = ${param_idx}")
                params.append(status)
                param_idx += 1

            if priority:
                conditions.append(f"priority = ${param_idx}")
                params.append(priority)
                param_idx += 1

            where_clause = " AND ".join(conditions)
            params.extend([limit, offset])

            query = f"""
                SELECT * FROM inbox_tasks
                WHERE {where_clause}
                ORDER BY
                    CASE priority
                        WHEN 'urgent' THEN 1
                        WHEN 'high' THEN 2
                        WHEN 'medium' THEN 3
                        WHEN 'low' THEN 4
                    END,
                    deadline ASC NULLS LAST,
                    created_at DESC
                LIMIT ${param_idx} OFFSET ${param_idx + 1}
            """

            rows = await conn.fetch(query, *params)
            return [dict(r) for r in rows]
    except Exception as e:
        print(f"Failed to get tasks: {e}")
        return []


async def get_task(task_id: str, user_id: str) -> Optional[Dict]:
    """Get a single task."""
    pool = await get_pool()
    if pool is None:
        return None

    try:
        async with pool.acquire() as conn:
            row = await conn.fetchrow(
                "SELECT * FROM inbox_tasks WHERE id = $1 AND user_id = $2",
                task_id, user_id
            )
            return dict(row) if row else None
    except Exception as e:
        print(f"Failed to get task: {e}")
        return None


async def update_task(
    task_id: str,
    user_id: str,
    title: Optional[str] = None,
    description: Optional[str] = None,
    priority: Optional[str] = None,
    status: Optional[str] = None,
    deadline: Optional[datetime] = None,
) -> bool:
    """Update a task."""
    pool = await get_pool()
    if pool is None:
        return False

    try:
        async with pool.acquire() as conn:
            updates = ["updated_at = NOW()"]
            params = [task_id, user_id]
            param_idx = 3

            if title is not None:
                updates.append(f"title = ${param_idx}")
                params.append(title)
                param_idx += 1

            if description is not None:
                updates.append(f"description = ${param_idx}")
                params.append(description)
                param_idx += 1

            if priority is not None:
                updates.append(f"priority = ${param_idx}")
                params.append(priority)
                param_idx += 1

            if status is not None:
                updates.append(f"status = ${param_idx}")
                params.append(status)
                param_idx += 1
                if status == "completed":
                    updates.append("completed_at = NOW()")

            if deadline is not None:
                updates.append(f"deadline = ${param_idx}")
                params.append(deadline)
                param_idx += 1

            set_clause = ", ".join(updates)
            await conn.execute(
                f"UPDATE inbox_tasks SET {set_clause} WHERE id = $1 AND user_id = $2",
                *params
            )
        return True
    except Exception as e:
        print(f"Failed to update task: {e}")
        return False


async def get_task_dashboard_stats(user_id: str) -> Dict:
    """Get dashboard statistics for tasks."""
    pool = await get_pool()
    if pool is None:
        return {}

    try:
        async with pool.acquire() as conn:
            now = datetime.now()
            today_end = now.replace(hour=23, minute=59, second=59)
            week_end = now + timedelta(days=7)

            stats = await conn.fetchrow(
                """
                SELECT
                    COUNT(*) as total_tasks,
                    COUNT(*) FILTER (WHERE status = 'pending') as pending_tasks,
                    COUNT(*) FILTER (WHERE status = 'in_progress') as in_progress_tasks,
                    COUNT(*) FILTER (WHERE status = 'completed') as completed_tasks,
                    COUNT(*) FILTER (WHERE status != 'completed' AND deadline < $2) as overdue_tasks,
                    COUNT(*) FILTER (WHERE status != 'completed' AND deadline <= $3) as due_today,
                    COUNT(*) FILTER (WHERE status != 'completed' AND deadline <= $4) as due_this_week
                FROM inbox_tasks
                WHERE user_id = $1
                """,
                user_id, now, today_end, week_end
            )

            by_priority = await conn.fetch(
                """
                SELECT priority, COUNT(*) as count
                FROM inbox_tasks
                WHERE user_id = $1 AND status != 'completed'
                GROUP BY priority
                """,
                user_id
            )

            by_sender = await conn.fetch(
                """
                SELECT source_sender_type, COUNT(*) as count
                FROM inbox_tasks
                WHERE user_id = $1 AND status != 'completed' AND source_sender_type IS NOT NULL
                GROUP BY source_sender_type
                """,
                user_id
            )

            return {
                "total_tasks": stats['total_tasks'] or 0,
                "pending_tasks": stats['pending_tasks'] or 0,
                "in_progress_tasks": stats['in_progress_tasks'] or 0,
                "completed_tasks": stats['completed_tasks'] or 0,
                "overdue_tasks": stats['overdue_tasks'] or 0,
                "due_today": stats['due_today'] or 0,
                "due_this_week": stats['due_this_week'] or 0,
                "by_priority": {r['priority']: r['count'] for r in by_priority},
                "by_sender_type": {r['source_sender_type']: r['count'] for r in by_sender},
            }
    except Exception as e:
        print(f"Failed to get task stats: {e}")
        return {}
