from django.shortcuts import get_object_or_404
from rest_framework import permissions, status
from rest_framework.response import Response
from rest_framework.views import APIView

from match_result_governance.models import MatchReplayOrder

from .models import ReplayFixtureExecution
from .serializers import (
    ReplayExecutionCreateSerializer,
    ReplayFixtureExecutionSerializer,
    ReplayResultConsolidationSerializer,
)
from .services import (
    ReplayExecutionIntegrityService,
    ReplayFixtureExecutionService,
    ReplayResultConsolidationService,
)


class ReplayExecutionCreateView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        serializer = ReplayExecutionCreateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        order = get_object_or_404(MatchReplayOrder, pk=serializer.validated_data["replay_order_id"])
        execution = ReplayFixtureExecutionService.create(
            replay_order=order,
            scheduled_at=serializer.validated_data["scheduled_at"],
            actor=request.user,
        )
        return Response(ReplayFixtureExecutionSerializer(execution).data, status=status.HTTP_201_CREATED)


class ReplayExecutionDetailView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, pk):
        execution = get_object_or_404(
            ReplayFixtureExecution.objects.select_related(
                "replay_order", "root_match", "original_match", "replacement_match", "calendar_edition"
            ), pk=pk
        )
        data = ReplayFixtureExecutionSerializer(execution).data
        try:
            data["consolidation"] = ReplayResultConsolidationSerializer(execution.consolidation).data
        except Exception:
            data["consolidation"] = None
        return Response(data)


class ReplayConsolidateView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request, pk):
        execution = get_object_or_404(ReplayFixtureExecution, pk=pk)
        row = ReplayResultConsolidationService.consolidate_for_replacement(
            replacement_match_id=execution.replacement_match_id,
            actor=request.user,
        )
        if row is None:
            return Response({"detail": "Replacement match has no final consolidatable certification."}, status=409)
        return Response(ReplayResultConsolidationSerializer(row).data)


class ReplayIntegrityView(APIView):
    permission_classes = [permissions.IsAdminUser]

    def get(self, request):
        return Response(ReplayExecutionIntegrityService.verify_all())
