import os
import platform
from datetime import timedelta

from django import get_version as django_version
from django.contrib import messages
from django.db.models import Avg, Count, Sum
from django.db.models.functions import Coalesce
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone

from .forms import MomentumEntryForm
from .models import Category, MomentumEntry


APP_NAME = "Momentum Atlas"
APP_TAGLINE = "A polished personal dashboard for tracking focus, energy, and small wins."


def _build_weekly_trend(entries):
    today = timezone.localdate()
    start_date = today - timedelta(days=6)
    trend_source = (
        entries.filter(entry_date__gte=start_date, entry_date__lte=today)
        .values("entry_date")
        .annotate(
            avg_focus=Coalesce(Avg("focus_score"), 0.0),
            avg_energy=Coalesce(Avg("energy_score"), 0.0),
            total_minutes=Coalesce(Sum("deep_work_minutes"), 0),
        )
    )
    by_date = {row["entry_date"]: row for row in trend_source}

    trend = []
    for offset in range(7):
        day = start_date + timedelta(days=offset)
        row = by_date.get(day, {})
        focus = float(row.get("avg_focus") or 0)
        energy = float(row.get("avg_energy") or 0)
        minutes = int(row.get("total_minutes") or 0)
        focus_level = int(round((focus / 10) * 10) * 10) if focus else 0
        energy_level = int(round((energy / 10) * 10) * 10) if energy else 0
        trend.append(
            {
                "date": day,
                "label": day.strftime("%a"),
                "focus": round(focus, 1),
                "energy": round(energy, 1),
                "minutes": minutes,
                "focus_level": max(0, min(100, focus_level)),
                "energy_level": max(0, min(100, energy_level)),
            }
        )
    return trend


def _dashboard_context():
    entries = MomentumEntry.objects.select_related("category")
    recent_entries = entries[:6]
    last_30_days = timezone.localdate() - timedelta(days=29)
    stats_window = entries.filter(entry_date__gte=last_30_days)
    totals = stats_window.aggregate(
        total_entries=Count("id"),
        avg_focus=Coalesce(Avg("focus_score"), 0.0),
        avg_energy=Coalesce(Avg("energy_score"), 0.0),
        total_minutes=Coalesce(Sum("deep_work_minutes"), 0),
    )
    active_days = stats_window.values("entry_date").distinct().count()
    top_category = (
        stats_window.values("category__name")
        .annotate(total=Count("id"))
        .order_by("-total", "category__name")
        .first()
    )
    weekly_trend = _build_weekly_trend(entries)

    focus_average = round(float(totals["avg_focus"] or 0), 1)
    energy_average = round(float(totals["avg_energy"] or 0), 1)
    if focus_average >= 8:
        spotlight = "Your recent focus trend is excellent—keep protecting that deep-work time."
    elif focus_average >= 6:
        spotlight = "Momentum is building. A little more consistency could turn this into a real streak."
    else:
        spotlight = "A reset week might help—shrink the task list and aim for one clear win each day."

    return {
        "recent_entries": recent_entries,
        "categories": Category.objects.all(),
        "weekly_trend": weekly_trend,
        "stats": {
            "total_entries": totals["total_entries"],
            "avg_focus": focus_average,
            "avg_energy": energy_average,
            "total_minutes": totals["total_minutes"],
            "active_days": active_days,
            "top_category": top_category["category__name"] if top_category else "No category yet",
            "spotlight": spotlight,
        },
    }


def home(request):
    host_name = request.get_host().lower()
    agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic"
    now = timezone.now()

    if request.method == "POST":
        form = MomentumEntryForm(request.POST)
        if form.is_valid():
            entry = form.save()
            messages.success(request, "Momentum captured. Your new check-in is ready.")
            return redirect(f"{entry.get_absolute_url()}?created=1")
        messages.error(request, "Please fix the form errors and try again.")
    else:
        form = MomentumEntryForm()

    context = {
        "project_name": APP_NAME,
        "agent_brand": agent_brand,
        "django_version": django_version(),
        "python_version": platform.python_version(),
        "current_time": now,
        "host_name": host_name,
        "project_description": os.getenv("PROJECT_DESCRIPTION", APP_TAGLINE),
        "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""),
        "page_title": f"{APP_NAME} | Daily focus dashboard",
        "meta_description": "Track daily focus, energy, and deep-work minutes in a polished Python dashboard.",
        "form": form,
        **_dashboard_context(),
    }
    return render(request, "core/index.html", context)


def entry_list(request):
    selected_slug = request.GET.get("category", "")
    entries = MomentumEntry.objects.select_related("category")
    if selected_slug:
        entries = entries.filter(category__slug=selected_slug)

    context = {
        "page_title": f"All check-ins | {APP_NAME}",
        "meta_description": "Browse recent check-ins and filter your momentum history by category.",
        "entries": entries,
        "categories": Category.objects.annotate(entry_total=Count("entries")),
        "selected_slug": selected_slug,
    }
    return render(request, "core/entry_list.html", context)


def entry_detail(request, pk):
    entry = get_object_or_404(MomentumEntry.objects.select_related("category"), pk=pk)
    related_entries = (
        MomentumEntry.objects.select_related("category")
        .filter(category=entry.category)
        .exclude(pk=entry.pk)[:3]
    )
    context = {
        "page_title": f"{entry.title} | {APP_NAME}",
        "meta_description": entry.takeaway,
        "entry": entry,
        "related_entries": related_entries,
        "created": request.GET.get("created") == "1",
    }
    return render(request, "core/entry_detail.html", context)
