from django.http import HttpRequest, HttpResponse, JsonResponse

from activities.services import TimelineService
from api import schemas
from api.decorators import identity_required
from api.pagination import MastodonPaginator
from api.views.base import api_router
from core.models import Config


@api_router.get("/v1/timelines/home", response=list[schemas.Status])
@identity_required
def home(
    request: HttpRequest,
    response: HttpResponse,
    max_id: str | None = None,
    since_id: str | None = None,
    min_id: str | None = None,
    limit: int = 20,
):
    # Grab a paginated result set of instances
    paginator = MastodonPaginator()
    queryset = TimelineService(request.identity).home()
    queryset = queryset.select_related(
        "subject_post_interaction__post",
        "subject_post_interaction__post__author",
        "subject_post_interaction__post__author__domain",
    )
    queryset = queryset.prefetch_related(
        "subject_post__mentions__domain",
        "subject_post_interaction__post__attachments",
        "subject_post_interaction__post__mentions",
        "subject_post_interaction__post__emojis",
        "subject_post_interaction__post__mentions__domain",
        "subject_post_interaction__post__author__posts",
    )
    pager = paginator.paginate_home(
        queryset,
        min_id=min_id,
        max_id=max_id,
        since_id=since_id,
        limit=limit,
    )
    # Convert those to the JSON form
    pager.jsonify_status_events(identity=request.identity)
    # Add the link header if needed
    if pager.results:
        response.headers["Link"] = pager.link_header(request, ["limit"])
    return pager.json_results


@api_router.get("/v1/timelines/public", response=list[schemas.Status])
def public(
    request: HttpRequest,
    response: HttpResponse,
    local: bool = False,
    remote: bool = False,
    only_media: bool = False,
    max_id: str | None = None,
    since_id: str | None = None,
    min_id: str | None = None,
    limit: int = 20,
):
    if not request.identity and not Config.system.public_timeline:
        return JsonResponse({"error": "public timeline is disabled"}, status=422)

    if local:
        queryset = TimelineService(request.identity).local()
    else:
        queryset = TimelineService(request.identity).federated()
    if remote:
        queryset = queryset.filter(local=False)
    if only_media:
        queryset = queryset.filter(attachments__id__isnull=True)
    # Grab a paginated result set of instances
    paginator = MastodonPaginator()
    pager = paginator.paginate(
        queryset,
        min_id=min_id,
        max_id=max_id,
        since_id=since_id,
        limit=limit,
    )
    # Convert those to the JSON form
    pager.jsonify_posts(identity=request.identity)
    # Add the link header if needed
    if pager.results:
        response.headers["Link"] = pager.link_header(
            request,
            ["limit", "local", "remote", "only_media"],
        )
    return pager.json_results


@api_router.get("/v1/timelines/tag/{hashtag}", response=list[schemas.Status])
@identity_required
def hashtag(
    request: HttpRequest,
    response: HttpResponse,
    hashtag: str,
    local: bool = False,
    only_media: bool = False,
    max_id: str | None = None,
    since_id: str | None = None,
    min_id: str | None = None,
    limit: int = 20,
):
    if limit > 40:
        limit = 40
    queryset = TimelineService(request.identity).hashtag(hashtag)
    if local:
        queryset = queryset.filter(local=True)
    if only_media:
        queryset = queryset.filter(attachments__id__isnull=True)
    # Grab a paginated result set of instances
    paginator = MastodonPaginator()
    pager = paginator.paginate(
        queryset,
        min_id=min_id,
        max_id=max_id,
        since_id=since_id,
        limit=limit,
    )
    # Convert those to the JSON form
    pager.jsonify_posts(identity=request.identity)
    # Add a link header if we need to
    if pager.results:
        response.headers["Link"] = pager.link_header(
            request,
            ["limit", "local", "remote", "only_media"],
        )
    return pager.json_results


@api_router.get("/v1/conversations", response=list[schemas.Status])
@identity_required
def conversations(
    request: HttpRequest,
    response: HttpResponse,
    max_id: str | None = None,
    since_id: str | None = None,
    min_id: str | None = None,
    limit: int = 20,
):
    # We don't implement this yet
    return []
