import logging

from agents.models import AgentSession
from agents.providers import (
    list_gemini_agent_models,
    list_openrouter_free_models,
)
from agents.utils import matching_turns
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import TextField
from django.db.models.functions import Cast
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views import View
from django.views.generic import TemplateView
from scrobbles.models import Scrobble
from scrobbles.scrobblers import manual_scrobble_agent_session
from scrobbles.views import ScrobbleableDetailView, ScrobbleableListView

logger = logging.getLogger(__name__)


class AgentSessionListView(ScrobbleableListView):
    model = AgentSession


class AgentSessionDetailView(ScrobbleableDetailView):
    model = AgentSession


class AgentSessionSearchView(LoginRequiredMixin, TemplateView):
    template_name = "agents/agent_session_search.html"

    def get(self, request, *args, **kwargs):
        if not request.GET.get("q"):
            return super().get(request, *args, **kwargs)
        return self.search(request)

    def search(self, request):
        query = request.GET.get("q", "").strip()
        user = request.user

        scrobbles = (
            Scrobble.objects.select_related("agent_session")
            .filter(user=user, media_type="AgentSession")
            .annotate(log_text=Cast("log", output_field=TextField()))
            .filter(log_text__icontains=query)
            .order_by("-timestamp")[:100]
        )

        results = []
        for scrobble in scrobbles:
            results.append(
                {
                    "scrobble": scrobble,
                    "turns": matching_turns(scrobble.logdata, query),
                }
            )

        context = self.get_context_data(query=query, results=results)
        return self.render_to_response(context)


class AgentModelSelectView(LoginRequiredMixin, TemplateView):
    template_name = "agents/agent_model_select.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["prompt"] = self.request.session.get("agent_prompt", "").strip()
        models = []
        try:
            models.extend(list_gemini_agent_models())
        except Exception as e:
            logger.exception("[agents] failed to load Gemini models")
            context["models_error"] = f"Could not load Gemini models: {e}"
        try:
            models.extend(list_openrouter_free_models())
        except Exception as e:
            logger.exception("[agents] failed to load OpenRouter models")
            context["models_error"] = f"Could not load models from OpenRouter: {e}"
        context["models"] = models
        if models:
            self.request.session["agent_models"] = models
        return context


class AgentScrobbleFromModelView(LoginRequiredMixin, View):
    http_method_names = ["post"]

    def post(self, request, *args, **kwargs):
        model = request.POST.get("model", "").strip()
        provider = request.POST.get("provider", "").strip() or "openrouter"
        prompt = (
            request.POST.get("prompt", "").strip()
            or request.session.get("agent_prompt", "").strip()
        )

        if not model:
            messages.error(request, "No model selected.")
            return HttpResponseRedirect(reverse("agents:agent_model_select"))
        if not prompt:
            messages.error(request, "Your prompt is empty.")
            return HttpResponseRedirect(reverse("agents:agent_model_select"))

        scrobble = manual_scrobble_agent_session(
            prompt, request.user.id, provider=provider, model=model
        )
        if scrobble:
            request.session.pop("agent_prompt", None)
            request.session.pop("agent_models", None)
            return HttpResponseRedirect(scrobble.get_absolute_url())
        messages.error(request, "Could not start agent session.")
        return HttpResponseRedirect(reverse("agents:agent_model_select"))
