# webapp/api/auth/views.py
from django.conf import settings
from rest_framework import generics, status, permissions
from rest_framework.response import Response
from drf_spectacular.utils import extend_schema, OpenApiResponse, OpenApiExample

from .serializers import LoginSerializer, CustomTokenRefreshSerializer, LogoutSerializer


# ==== LOGIN ====
@extend_schema(
    tags=["User Auth"],
    summary="Login user",
    description="Autentikasi dengan username & password. Token akan disimpan di HttpOnly cookie.",
    request=LoginSerializer,
    responses={
        200: OpenApiResponse(
            description="Login sukses",
            examples=[
                OpenApiExample(
                    "Contoh sukses",
                    value={
                        "user": {"id": 1, "username": "johndoe", "role": "Admin"},
                        "detail": "Login berhasil, token disimpan di cookie."
                    }
                )
            ],
        ),
        401: OpenApiResponse(
            description="Login gagal",
            examples=[
                OpenApiExample(
                    "Contoh gagal",
                    value={"detail": "Invalid username or password"}
                )
            ],
        ),
    },
)
class LoginView(generics.GenericAPIView):
    permission_classes = [permissions.AllowAny] 
    serializer_class = LoginSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data

        response = Response({
            "user": data["user"],
            "detail": "Login berhasil, token disimpan di cookie."
        }, status=status.HTTP_200_OK)

        # simpan token ke cookie
        response.set_cookie(
            key="access_token",
            value=data["access"],
            httponly=True,
            secure=not settings.DEBUG,
            samesite="Lax"
        )
        response.set_cookie(
            key="refresh_token",
            value=data["refresh"],
            httponly=True,
            secure=not settings.DEBUG,
            samesite="Lax"
        )
        return response


# ==== REFRESH ====
@extend_schema(
    tags=["User Auth"],
    summary="Refresh token",
    description="Gunakan refresh token (dari body, header, atau cookie) untuk mendapatkan access token baru.",
    request=CustomTokenRefreshSerializer,
    responses={
        200: OpenApiResponse(
            description="Refresh sukses",
            examples=[
                OpenApiExample(
                    "Contoh sukses",
                    value={"detail": "Access token diperbarui."}
                )
            ],
        ),
        401: OpenApiResponse(
            description="Refresh gagal",
            examples=[
                OpenApiExample(
                    "Contoh gagal",
                    value={"detail": "Token tidak valid atau kadaluarsa"}
                )
            ],
        ),
    },
)
class RefreshView(generics.GenericAPIView):
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = CustomTokenRefreshSerializer

    def post(self, request, *args, **kwargs):

        # PRIORITAS:
        # 1. Body (Android)
        # 2. Header custom
        # 3. Cookie (Browser)
        refresh = (
            request.data.get("refresh") or
            request.headers.get("X-Refresh-Token") or
            request.COOKIES.get("refresh_token")
        )

        if not refresh:
            return Response(
                {"detail": "Refresh token tidak ditemukan"},
                status=status.HTTP_401_UNAUTHORIZED
            )

        # inject refresh ke serializer
        request.data["refresh"] = refresh

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data

        response = Response({"detail": "Access token diperbarui."}, status=status.HTTP_200_OK)

        # set access token baru
        response.set_cookie(
            key="access_token",
            value=data["access"],
            httponly=True,
            secure=not settings.DEBUG,
            samesite="Lax"
        )
        return response


# ==== LOGOUT ====
@extend_schema(
    tags=["User Auth"],
    summary="Logout user",
    description="Blacklist refresh token dan hapus cookie JWT.",
    request=LogoutSerializer,
    responses={
        205: OpenApiResponse(
            description="Logout sukses",
            examples=[
                OpenApiExample(
                    "Contoh sukses",
                    value={"detail": "Logout berhasil."}
                )
            ],
        ),
        400: OpenApiResponse(
            description="Logout gagal",
            examples=[
                OpenApiExample(
                    "Contoh gagal",
                    value={"detail": "Refresh token tidak valid"}
                )
            ],
        ),
    },
)
class LogoutView(generics.GenericAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = LogoutSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data={})
        serializer.is_valid(raise_exception=True)
        response = Response({"detail": "Logout berhasil."}, status=status.HTTP_205_RESET_CONTENT)
        serializer.save(response=response)
        return response
