from django.utils import timezone
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.reverse import reverse

from bridger import buttons as bt
from bridger import display as dp
from bridger import viewsets

from .models import Notification
from .serializers import NotificationModelSerializer


class NotificationModelViewSet(viewsets.ModelViewSet):
    ENDPOINT = "bridger:notification-list"

    INSTANCE_WIDGET_TITLE = "Notification: {{title}}"
    LIST_WIDGET_TITLE = "Notifications"

    LIST_BUTTONS = ["refresh"]
    INSTANCE_BUTTONS = ["refresh", "delete"]
    CREATE_BUTTONS = []

    def get_custom_buttons(self, request):
        return [
            bt.ActionButton(
                method="post",
                action_label="All notifications read.",
                endpoint=reverse(
                    "bridger:notification-mark-all-as-read", request=request
                ),
                description_fields="Do you want to mark notifications as read?",
                label="Mark all as read",
                icon="wb-icon-eye-open",
                confirm_config=bt.AdditionalButtonConfig(label="Read all"),
                cancel_config=bt.AdditionalButtonConfig(label="Cancel"),
                identifiers=["relatedmodeltest-list"],
            ).to_dict(),
            bt.ActionButton(
                method="post",
                action_label="Delete all read notifications.",
                endpoint=reverse(
                    "bridger:notification-delete-all-read", request=request
                ),
                description_fields="Do you want delete all read notifications?",
                label="Delete all read notifications",
                icon="wb-icon-trash",
                confirm_config=bt.AdditionalButtonConfig(
                    label="Delete all", level=bt.ButtonLevel.WARNING
                ),
                cancel_config=bt.AdditionalButtonConfig(
                    label="Cancel", level=bt.ButtonLevel.ERROR
                ),
                identifiers=[reverse("bridger:notification-list", request=request)],
            ).to_dict(),
        ]

    LIST_DISPLAY = dp.ListDisplay(
        fields=[
            dp.Field(key="title", label="Title"),
            dp.Field(key="timestamp_created", label="Created"),
            dp.Field(key="message", label="Message"),
        ],
        formatting=[
            dp.RowFormatting(
                column="timestamp_read",
                conditions=[
                    dp.RowIconCondition(icon="wb-icon-eye-open", condition=("∃", True)),
                ],
            ),
        ],
    )

    INSTANCE_DISPLAY = dp.InstanceDisplay(
        sections=[
            dp.Section(
                fields=dp.FieldSet(
                    fields=[
                        dp.FieldSet(fields=["timestamp_created", "timestamp_received"]),
                        dp.FieldSet(fields=["timestamp_received", "timestamp_mailed"]),
                        "title",
                        "message",
                    ]
                )
            )
        ]
    )

    queryset = Notification.objects.all()
    serializer_class = NotificationModelSerializer

    ordering_fields = ("timestamp_created",)

    def retrieve(self, request, *args, **kwargs):
        obj = self.get_object()
        if not obj.timestamp_read:
            obj.timestamp_read = timezone.now()
            obj.save()
        return super().retrieve(request, *args, **kwargs)

    def list(self, request, *args, **kwargs):
        self.get_queryset().filter(timestamp_received__isnull=True).update(
            timestamp_received=timezone.now()
        )
        return super().list(request, *args, **kwargs)

    def get_queryset(self):
        return super().get_queryset().filter(recipient=self.request.user)

    @action(methods=["POST"], detail=False)
    def mark_all_as_read(self, request, pk=None):
        Notification.objects.filter(timestamp_read__isnull=True).update(
            timestamp_read=timezone.now()
        )
        return Response({})

    @action(methods=["POST"], detail=False)
    def delete_all_read(self, request, pk=None):
        Notification.objects.filter(timestamp_read__isnull=False).delete()
        return Response({})
