import urllib.parse

from django.conf import settings
from django.db.models import Q
from django.urls import reverse
from rest_framework import serializers

from funkwhale_api.common import middleware, preferences, utils
from funkwhale_api.federation import utils as federation_utils
from funkwhale_api.music import spa_views

from . import models


def channel_detail(query, redirect_to_ap):
    queryset = models.Channel.objects.filter(query).select_related(
        "artist__attachment_cover", "actor", "library"
    )
    try:
        obj = queryset.get()
    except models.Channel.DoesNotExist:
        return []

    if redirect_to_ap:
        raise middleware.ApiRedirect(obj.actor.fid)

    obj_url = utils.join_url(
        settings.FUNKWHALE_URL,
        utils.spa_reverse(
            "channel_detail", kwargs={"username": obj.actor.full_username}
        ),
    )
    metas = [
        {"tag": "meta", "property": "og:url", "content": obj_url},
        {"tag": "meta", "property": "og:title", "content": obj.artist.name},
        {"tag": "meta", "property": "og:type", "content": "profile"},
    ]

    if obj.artist.attachment_cover:
        metas.append(
            {
                "tag": "meta",
                "property": "og:image",
                "content": obj.artist.attachment_cover.download_url_medium_square_crop,
            }
        )

    if preferences.get("federation__enabled"):
        metas.append(
            {
                "tag": "link",
                "rel": "alternate",
                "type": "application/activity+json",
                "href": obj.actor.fid,
            }
        )

    metas.append(
        {
            "tag": "link",
            "rel": "alternate",
            "type": "application/rss+xml",
            "href": obj.get_rss_url(),
            "title": f"{obj.artist.name} - RSS Podcast Feed",
        },
    )

    if obj.library.uploads.all().playable_by(None).exists():
        metas.append(
            {
                "tag": "link",
                "rel": "alternate",
                "type": "application/json+oembed",
                "href": (
                    utils.join_url(settings.FUNKWHALE_URL, reverse("api:v1:oembed"))
                    + f"?format=json&url={urllib.parse.quote_plus(obj_url)}"
                ),
            }
        )
        # twitter player is also supported in various software
        metas += spa_views.get_twitter_card_metas(type="channel", id=obj.uuid)
    return metas


def channel_detail_uuid(request, uuid, redirect_to_ap):
    validator = serializers.UUIDField().to_internal_value
    try:
        uuid = validator(uuid)
    except serializers.ValidationError:
        return []
    return channel_detail(Q(uuid=uuid), redirect_to_ap)


def channel_detail_username(request, username, redirect_to_ap):
    validator = federation_utils.get_actor_data_from_username
    try:
        username_data = validator(username)
    except serializers.ValidationError:
        return []
    query = Q(
        actor__domain=username_data["domain"],
        actor__preferred_username__iexact=username_data["username"],
    )
    return channel_detail(query, redirect_to_ap)
