# -*- coding: utf-8 -*-
from __future__ import annotations

import uuid

from django.contrib import messages
import django.db
from django.http import HttpRequest, HttpResponse, JsonResponse
from django.shortcuts import redirect, render
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django.views.generic import FormView
from django_htmx.http import trigger_client_event

from hotpocket_backend.apps.accounts.decorators import account_required
from hotpocket_backend.apps.accounts.mixins import AccountRequiredMixin
from hotpocket_backend.apps.htmx import messages as htmx_messages
from hotpocket_backend.apps.ui.constants import UIAccessTokenOriginApp
from hotpocket_backend.apps.ui.dto.accounts import AppsBrowseParams
from hotpocket_backend.apps.ui.forms.accounts.apps import DeleteForm
from hotpocket_backend.apps.ui.services import UIAccessTokensService
from hotpocket_soa.dto.accounts import AccessTokenOut, AccessTokensQuery
from hotpocket_soa.services import AccessTokensService


class AccessTokenMixin:
    def get_access_token(self) -> AccessTokenOut:
        if hasattr(self, '_access_token') is False:
            setattr(
                self,
                '_access_token',
                UIAccessTokensService().get_or_404(
                    account_uuid=self.request.user.pk,  # type: ignore[attr-defined]
                    pk=self.kwargs['pk'],  # type: ignore[attr-defined]
                ),
            )

        return self._access_token  # type: ignore[attr-defined]


class DetailView(AccessTokenMixin, AccountRequiredMixin, FormView):
    def get_context_data(self, **kwargs) -> dict:
        result = super().get_context_data(**kwargs)

        result.update({
            'access_token': self.get_access_token(),
        })

        return result


class ConfirmationView(DetailView):
    def get_initial(self) -> dict:
        result = super().get_initial()

        access_token: AccessTokenOut = self.get_access_token()

        origin_app = access_token.get_origin_app()
        if origin_app is not None:
            origin_app = UIAccessTokenOriginApp[origin_app.value].value

        result.update({
            'canhazconfirm': 'hai',
            'origin_app': origin_app or access_token.get_origin_app_id(),
            'platform': access_token.meta.get('platform', '-'),
            'version': access_token.meta.get('version', '-'),
        })

        return result

    def get_success_url(self) -> str:
        return reverse('ui.accounts.apps.browse')


@account_required
def index(request: HttpRequest) -> HttpResponse:
    return redirect(reverse('ui.accounts.apps.browse'))


@account_required
def browse(request: HttpRequest) -> HttpResponse:
    params = AppsBrowseParams.from_request(request=request)

    access_tokens = AccessTokensService().search(
        query=AccessTokensQuery.model_validate(dict(
            account_uuid=request.user.pk,
            before=params.before,
        )),
        limit=params.limit,
    )

    before: uuid.UUID | None = None
    if len(access_tokens) == params.limit:
        before = access_tokens[-1].pk

    next_url: str | None = None
    if before is not None:
        next_url = reverse('ui.accounts.apps.browse', query=[
            ('before', before),
            ('limit', params.limit),
        ])

    context = {
        'access_tokens': access_tokens,
        'params': params,
        'before': before,
        'next_url': next_url,
    }

    if request.htmx:
        response = render(
            request,
            'ui/accounts/partials/apps/apps.html',
            context,
        )

        return trigger_client_event(
            response,
            'HotPocket:BrowseAccountAppsView:updateLoadMoreButton',
            {'next_url': next_url},
            after='swap',
        )

    return render(
        request,
        'ui/accounts/apps/browse.html',
        context,
    )


class DeleteView(ConfirmationView):
    template_name = 'ui/accounts/apps/delete.html'
    form_class = DeleteForm

    def form_valid(self, form: DeleteForm) -> HttpResponse:
        with django.db.transaction.atomic():
            result = AccessTokensService().delete(
                access_token=self.get_access_token(),
            )

        if self.request.htmx:
            response = JsonResponse({
                'status': 'ok',
                'result': result,
            })

            htmx_messages.add_htmx_message(
                request=self.request,
                response=response,
                level=htmx_messages.SUCCESS,
                message=_('The app auhtorization has been deleted.'),
            )

            return trigger_client_event(
                response,
                'HotPocket:BrowseAccountAppsView:delete',
                {'pk': self.kwargs['pk']},
                after='swap',
            )

        messages.add_message(
            self.request,
            messages.SUCCESS,
            _('The app auhtorization has been deleted.'),
        )

        return super().form_valid(form)
