from django.contrib.auth import get_user_model
from django.utils import timezone
from drf_spectacular.utils import OpenApiExample, extend_schema
from rest_framework import generics, permissions, status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from rest_framework.views import APIView

from django_cfg.mixins import ClientAPIMixin
from django_cfg.modules.django_telegram import DjangoTelegram
from django_cfg.utils import get_logger
from ..serializers.profile import (
    AccountDeleteResponseSerializer,
    AvatarUploadSerializer,
    UserProfileUpdateSerializer,
    UserSerializer,
)

logger = get_logger(__name__)

User = get_user_model()


@extend_schema(
    tags=['User Profile'],
    summary="Get current user profile",
    description="Retrieve the current authenticated user's profile information.",
    responses={
        200: UserSerializer,
        401: {"description": "Authentication credentials were not provided."}
    }
)
class UserProfileView(ClientAPIMixin, generics.RetrieveAPIView):
    """
    Get current user profile details.

    Requires authenticated user (JWT or Session).
    """
    serializer_class = UserSerializer

    def get_object(self):
        return self.request.user


@extend_schema(
    tags=['User Profile'],
    summary="Update user profile",
    description="Update the current authenticated user's profile information.",
    request=UserProfileUpdateSerializer,
    responses={
        200: UserSerializer,
        400: {"description": "Invalid data provided."},
        401: {"description": "Authentication credentials were not provided."}
    },
    examples=[
        OpenApiExample(
            "Valid Profile Update",
            value={
                "first_name": "John",
                "last_name": "Doe",
                "company": "Tech Corp",
                "phone": "+1 (555) 123-4567",
                "position": "Software Engineer"
            },
            request_only=True,
            status_codes=["200"]
        )
    ]
)
class UserProfileUpdateView(ClientAPIMixin, generics.UpdateAPIView):
    """
    Update current user profile.

    Requires authenticated user (JWT or Session).
    """
    serializer_class = UserProfileUpdateSerializer

    def get_object(self):
        return self.request.user

    def update(self, request, *args, **kwargs):
        """Update user profile and return updated data."""
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        # Return full user data
        user_serializer = UserSerializer(instance, context={'request': request})
        return Response(user_serializer.data, status=status.HTTP_200_OK)


@extend_schema(
    tags=['User Profile'],
    summary="Partial update user profile",
    description="Partially update the current authenticated user's profile information. Supports avatar upload.",
    request=UserProfileUpdateSerializer,
    responses={
        200: UserSerializer,
        400: {"description": "Invalid data provided."},
        401: {"description": "Authentication credentials were not provided."}
    },
    examples=[
        OpenApiExample(
            "Profile Update with Avatar",
            value={
                "first_name": "John",
                "last_name": "Doe",
                "company": "Tech Corp",
                "phone": "+1 (555) 123-4567",
                "position": "Software Engineer"
            },
            request_only=True,
            status_codes=["200"]
        )
    ]
)
class UserProfilePartialUpdateView(ClientAPIMixin, generics.UpdateAPIView):
    """
    Partially update current user profile.

    Requires authenticated user (JWT or Session).
    """
    serializer_class = UserProfileUpdateSerializer

    def get_object(self):
        return self.request.user

    def update(self, request, *args, **kwargs):  # noqa: ARG002
        """Update user profile and return updated data."""
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        # Return full user data (same as UserProfileUpdateView)
        user_serializer = UserSerializer(instance, context={'request': request})
        return Response(user_serializer.data, status=status.HTTP_200_OK)


@extend_schema(
    tags=['User Profile'],
    summary="Upload user avatar",
    description="Upload avatar image for the current authenticated user. Accepts multipart/form-data with 'avatar' field.",
    request={
        'multipart/form-data': {
            'type': 'object',
            'properties': {
                'avatar': {
                    'type': 'string',
                    'format': 'binary',
                    'description': 'Avatar image file (JPEG, PNG, GIF, WebP, max 5MB)'
                }
            },
            'required': ['avatar']
        }
    },
    responses={
        200: UserSerializer,
        400: {"description": "Invalid file or validation error."},
        401: {"description": "Authentication credentials were not provided."}
    }
)
@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def upload_avatar(request):
    """Upload avatar for current user."""
    if 'avatar' not in request.FILES:
        return Response(
            {'error': 'No avatar file provided'},
            status=status.HTTP_400_BAD_REQUEST
        )

    avatar_file = request.FILES['avatar']
    user = request.user

    # Validate file
    serializer = AvatarUploadSerializer(user, data={'avatar': avatar_file}, partial=True)
    if not serializer.is_valid():
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    # Save avatar
    serializer.save()

    # Return updated user data
    user_serializer = UserSerializer(user, context={'request': request})
    return Response(user_serializer.data, status=status.HTTP_200_OK)


@extend_schema(
    tags=['User Profile'],
    summary="Delete user account",
    description="""
    Permanently delete the current user's account.

    This operation:
    - Deactivates the account (user cannot log in)
    - Anonymizes personal data (GDPR compliance)
    - Frees up the email address for re-registration
    - Preserves audit trail

    The account can be restored by an administrator if needed.
    """,
    request=None,
    responses={
        200: AccountDeleteResponseSerializer,
        401: {"description": "Authentication credentials were not provided."},
        400: {"description": "Account is already deleted."}
    }
)
class AccountDeleteView(ClientAPIMixin, APIView):
    """
    Delete (soft delete) the current user's account.

    This deactivates the account and anonymizes personal data.
    The account can be restored by an administrator.
    """

    def post(self, request):
        """Delete the current user's account."""
        user = request.user

        # Check if already deleted
        if user.is_deleted:
            return Response(
                {'error': 'Account is already deleted.'},
                status=status.HTTP_400_BAD_REQUEST
            )

        # Store info before deletion for notification
        original_email = user.email
        user_id = user.id
        full_name = user.full_name or "N/A"

        # Perform soft delete
        user.soft_delete()

        # Send Telegram notification
        try:
            DjangoTelegram.send_warning("Account Deleted", {
                "User ID": user_id,
                "Email": original_email,
                "Full Name": full_name,
                "Deleted At": timezone.now().strftime("%Y-%m-%d %H:%M:%S UTC"),
                "Action": "Self-deletion via API",
            })
        except Exception as e:
            logger.error(f"Failed to send Telegram notification for account deletion: {e}")

        return Response(
            {
                'success': True,
                'message': 'Your account has been successfully deleted.'
            },
            status=status.HTTP_200_OK
        )
