"""Views."""

from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.db.models import F
from django.http import HttpRequest
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.translation import gettext_lazy as _
from esi.decorators import token_required

from allianceauth.framework.datatables import DataTablesView
from allianceauth.services.hooks import get_extension_logger

from dens import tasks
from dens.models import ESI_SCOPES, DenOwner, MercenaryDen

logger = get_extension_logger(__name__)


@login_required
@permission_required("dens.basic_access")
def index(request):
    """Render index view."""
    return redirect("dens:dens")


@login_required
@permission_required("dens.basic_access")
@token_required(scopes=ESI_SCOPES)
def add_owner(request, token):
    """View to add an owner"""
    character_ownership = get_object_or_404(
        request.user.character_ownerships.select_related("character"),
        character__character_id=token.character_id,
    )

    owner, created = DenOwner.objects.get_or_create(
        character_ownership=character_ownership
    )

    if not created:
        owner.enable()
        messages.success(
            request,
            _(
                "Successfully enabled owner %(owner_name)s. Starting to fetch mercenary dens."
            )
            % {"owner_name": owner.character_name},
        )
    else:
        messages.success(
            request,
            _(
                "Successfully created owner %(owner_name)s. Starting to fetch mercenary dens."
            )
            % {"owner_name": owner.character_name},
        )

    tasks.update_owner_dens.delay(owner.id)

    return redirect("dens:index")


def _get_dens_filtered(request: HttpRequest):
    """Filters mercenary dens based on request/user and applies select_related"""

    user = request.user
    if user.has_perm("dens.manager"):
        qs = MercenaryDen.objects.all()
    elif user.has_perm("dens.alliance_view"):
        alliance = request.user.profile.main_character.alliance
        qs = MercenaryDen.objects.filter_alliance_dens(alliance)
    elif user.has_perm("dens.corporation_view"):
        corporation = request.user.profile.main_character.corporation
        qs = MercenaryDen.objects.filter_corporation_dens(corporation)
    else:
        qs = MercenaryDen.objects.filter_user_dens(user)

    qs = qs.select_related(
        "owner",
        "location",
        "location__solar_system",
        "location__solar_system__constellation",
        "location__solar_system__constellation__region",
    )

    return qs


@permission_required("dens.basic_access")
def dens(request):
    """Renders dens table"""
    qs = _get_dens_filtered(request)

    den_owners = (
        qs.values(
            "owner__character_ownership__character__character_name",
            "owner__character_ownership__character__character_id",
        )
        .annotate(
            character_name=F("owner__character_ownership__character__character_name"),
            character_id=F("owner__character_ownership__character__character_id"),
        )
        .order_by("character_name")
        .distinct()
    )

    den_owner_mains = (
        qs.values(
            "owner__character_ownership__user__profile__main_character__character_name",
            "owner__character_ownership__user__id",
        )
        .annotate(
            name=F(
                "owner__character_ownership__user__profile__main_character__character_name"
            ),
            id=F("owner__character_ownership__user__id"),
        )
        .order_by("name")
        .distinct()
    )

    solar_systems = (
        qs.values(
            "location__solar_system__name",
            "location__solar_system__id",
        )
        .annotate(
            name=F("location__solar_system__name"),
            id=F("location__solar_system__id"),
        )
        .order_by("name")
        .distinct()
    )

    constellations = (
        qs.values(
            "location__solar_system__constellation__name",
            "location__solar_system__constellation__id",
        )
        .annotate(
            name=F("location__solar_system__constellation__name"),
            id=F("location__solar_system__constellation__id"),
        )
        .order_by("name")
        .distinct()
    )

    regions = (
        qs.values(
            "location__solar_system__constellation__region__name",
            "location__solar_system__constellation__region__id",
        )
        .annotate(
            name=F("location__solar_system__constellation__region__name"),
            id=F("location__solar_system__constellation__region__id"),
        )
        .order_by("name")
        .distinct()
    )

    context = {
        "den_owners": den_owners,
        "den_owner_mains": den_owner_mains,
        "solar_systems": solar_systems,
        "constellations": constellations,
        "regions": regions,
    }

    return render(request, "dens/dens.html", context)


class MercenaryDenTableData(
    DataTablesView, LoginRequiredMixin, PermissionRequiredMixin
):
    """Data to populate the mercenary dens datatable"""

    model = MercenaryDen
    permission_required = "dens.basic_access"
    columns = [
        ("owner", "{{ row.owner.character_ownership.character.character_name }}"),
        (
            "owner__character_ownership__user",
            "{{ row.owner.character_ownership.user.profile.main_character.character_name }}",
        ),
        ("location", "{{ row.location.name }}"),
        ("location__solar_system", "dens/stubs/system_name.html"),
        ("", "dens/stubs/region_constellation.html"),
        ("", "dens/stubs/reinforced.html"),  # TODO check for full data
        (
            "location__solar_system__constellation",
            "{{ row.location.solar_system.constellation.name }}",
        ),
        (
            "location__solar_system__constellation__region",
            "{{ row.location.solar_system.constellation.region.name }}",
        ),
    ]

    def get_model_qs(self, request: HttpRequest, *args, **kwargs):
        qs = _get_dens_filtered(request)

        get_params = request.GET.dict()

        if filter_den_owner := get_params.get("filter_den_owner"):
            qs = qs.filter(den_owner_id=filter_den_owner)
        if filter_den_owner_main := get_params.get("filter_den_owner_main"):
            qs = qs.filter(
                den_owner__character_ownership__user_id=filter_den_owner_main
            )
        if filter_solar_system := get_params.get("filter_solar_system"):
            qs = qs.filter(location__solar_system_id=filter_solar_system)
        if filter_constellation := get_params.get("filter_constellation"):
            qs = qs.filter(
                location__solar_system__constellation_id=filter_constellation
            )
        if filter_region := get_params.get("filter_region"):
            qs = qs.filter(location__solar_system__constellation__region=filter_region)
        if filter_reinforced := get_params.get("filter_reinforced"):
            if filter_reinforced == "YES":
                qs = qs.filter_is_reinforced(True)
            elif filter_reinforced == "NO":
                qs = qs.filter_is_reinforced(False)
            logger.warning(
                "Unexpected reinforcement filter received: '%s'", filter_reinforced
            )

        return qs
