"""Time Tracking selectors — read-only queries."""

from __future__ import annotations

from datetime import date
from typing import TYPE_CHECKING

from django.db.models import QuerySet, Sum
from django.db.models.functions import TruncDate

if TYPE_CHECKING:
    from simorgh.apps.time_tracking.models import TimeEntry


def entries_for_tenant(tenant_id: int) -> "QuerySet[TimeEntry]":
    from simorgh.apps.time_tracking.models import TimeEntry
    return TimeEntry.objects.filter(tenant_id=tenant_id)


def entries_for_user(tenant_id: int, user_id: int) -> "QuerySet[TimeEntry]":
    return entries_for_tenant(tenant_id).filter(user_id=user_id)


def entries_for_project(tenant_id: int, project_id: int) -> "QuerySet[TimeEntry]":
    return entries_for_tenant(tenant_id).filter(project_id=project_id)


def entry_by_public_id(tenant_id: int, public_id: str) -> "TimeEntry":
    from simorgh.apps.time_tracking.models import TimeEntry
    return TimeEntry.objects.get(tenant_id=tenant_id, public_id=public_id)


def filter_entries(
    tenant_id: int,
    *,
    user_id: int | None = None,
    project_id: int | None = None,
    task_id: int | None = None,
    date_from: date | None = None,
    date_to: date | None = None,
    is_billable: bool | None = None,
    is_approved: bool | None = None,
) -> "QuerySet[TimeEntry]":
    qs = entries_for_tenant(tenant_id).select_related("user", "project", "task")
    if user_id is not None:
        qs = qs.filter(user_id=user_id)
    if project_id is not None:
        qs = qs.filter(project_id=project_id)
    if task_id is not None:
        qs = qs.filter(task_id=task_id)
    if date_from is not None:
        qs = qs.filter(date__gte=date_from)
    if date_to is not None:
        qs = qs.filter(date__lte=date_to)
    if is_billable is not None:
        qs = qs.filter(is_billable=is_billable)
    if is_approved is not None:
        qs = qs.filter(is_approved=is_approved)
    return qs


def my_weekly_entries(tenant_id: int, user_id: int, week_start: date, week_end: date) -> "QuerySet[TimeEntry]":
    """Return all entries for a user in a given week."""
    return entries_for_tenant(tenant_id).filter(
        user_id=user_id,
        date__gte=week_start,
        date__lte=week_end,
    ).select_related("project", "task").order_by("date", "project__name")


def project_time_report(tenant_id: int, project_id: int, date_from: date | None, date_to: date | None):
    """Aggregate hours per user per task for a project in a date range.

    Returns a list of dicts: {user_id, task_id, total_hours}
    """
    qs = entries_for_project(tenant_id, project_id)
    if date_from:
        qs = qs.filter(date__gte=date_from)
    if date_to:
        qs = qs.filter(date__lte=date_to)
    return (
        qs.values("user_id", "user__email", "task_id", "task__title")
          .annotate(total_hours=Sum("hours"))
          .order_by("user_id", "task_id")
    )
