from datetime import datetime, timedelta, timezone

from sqlalchemy import func, select
from sqlalchemy.orm import Session

from app.db.models import AnalysisTask, Child, Report, TrainingPlan, TrainingRecord, Video


def _tenant_child_ids_subquery(tenant_id: int):
    return select(Child.id).where(Child.tenant_id == tenant_id).scalar_subquery()


def get_dashboard_metrics(db: Session, tenant_id: int | None = None) -> dict:
    since = datetime.now(timezone.utc) - timedelta(days=30)

    child_q = select(func.count()).select_from(Child).where(Child.status == "active")
    video_q = select(func.count()).select_from(Video)
    report_q = select(func.count()).select_from(Report).where(Report.status == "published")
    plan_q = select(func.count()).select_from(TrainingPlan).where(TrainingPlan.status == "active")
    new_child_q = select(func.count()).select_from(Child).where(Child.created_at >= since)
    succeeded_q = select(func.count()).select_from(AnalysisTask).where(
        AnalysisTask.status == "SUCCEEDED"
    )
    reassessment_q = select(func.count()).select_from(AnalysisTask).where(
        AnalysisTask.task_type == "reassessment", AnalysisTask.status == "SUCCEEDED"
    )
    pending_review_q = select(func.count()).select_from(Report).where(Report.reviewed_by.is_(None))
    pending_training_q = select(func.count()).select_from(TrainingRecord).where(
        TrainingRecord.score.is_not(None)
    )

    if tenant_id:
        tenant_children = _tenant_child_ids_subquery(tenant_id)
        child_q = child_q.where(Child.tenant_id == tenant_id)
        new_child_q = new_child_q.where(Child.tenant_id == tenant_id)
        video_q = video_q.where(Video.child_id.in_(tenant_children))
        report_q = report_q.where(Report.child_id.in_(tenant_children))
        plan_q = plan_q.where(TrainingPlan.child_id.in_(tenant_children))
        succeeded_q = succeeded_q.where(AnalysisTask.child_id.in_(tenant_children))
        reassessment_q = reassessment_q.where(AnalysisTask.child_id.in_(tenant_children))
        pending_review_q = pending_review_q.where(Report.child_id.in_(tenant_children))
        pending_training_q = pending_training_q.where(TrainingRecord.child_id.in_(tenant_children))

    new_children = db.scalar(new_child_q) or 0
    uploaded_videos = db.scalar(video_q) or 0
    completed_reports = db.scalar(report_q) or 0
    active_plans = db.scalar(plan_q) or 0
    succeeded_tasks = db.scalar(succeeded_q) or 0
    reassessment_done = db.scalar(reassessment_q) or 0

    conversion_rate = round(completed_reports / max(succeeded_tasks, 1), 2)
    reassessment_rate = round(reassessment_done / max(active_plans, 1), 2)

    pending_review = db.scalar(pending_review_q) or 0
    pending_training = db.scalar(pending_training_q) or 0

    return {
        "newChildren": new_children,
        "uploadedVideos": uploaded_videos,
        "completedReports": completed_reports,
        "activePlans": active_plans,
        "conversionRate": min(conversion_rate, 1.0),
        "reassessmentCompletionRate": min(reassessment_rate, 1.0),
        "pendingReviewReports": pending_review,
        "pendingTrainingReview": pending_training,
    }
