from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.permissions import AllowAny, IsAdminUser, IsAuthenticated
from rest_framework.response import Response

from apps.promotions.models import Promotion, PromotionPlan
from apps.promotions.payment import create_payment_link
from apps.promotions.serializers import (
    PromotionCreateSerializer,
    PromotionPlanSerializer,
    PromotionSerializer,
)


class PromotionPlanViewSet(viewsets.ModelViewSet):
    """CRUD for promotion plans.

    - list / retrieve : public
    - create / update / delete : admin only
    """

    serializer_class = PromotionPlanSerializer

    def get_permissions(self):
        if self.action in ("list", "retrieve"):
            return [AllowAny()]
        return [IsAdminUser()]

    def get_queryset(self):
        qs = PromotionPlan.objects.all()
        # Public users only see active plans
        if not (self.request.user.is_authenticated and self.request.user.is_staff):
            qs = qs.filter(is_active=True)
        return qs


class PromotionViewSet(viewsets.ModelViewSet):
    """Promotions for store owners.

    - list / retrieve / create : authenticated store owners
    - update / delete : admin only
    """

    def get_permissions(self):
        if self.action in ("list", "retrieve", "create", "my_promotions"):
            return [IsAuthenticated()]
        return [IsAdminUser()]

    def get_serializer_class(self):
        if self.action == "create":
            return PromotionCreateSerializer
        return PromotionSerializer

    def get_queryset(self):
        user = self.request.user
        if user.is_staff:
            return Promotion.objects.select_related("store", "product", "plan").all()
        return Promotion.objects.select_related("store", "product", "plan").filter(owner=user)

    def create(self, request, *args, **kwargs):
        """Create promotion and generate payment link via MyFatoorah."""
        serializer = PromotionCreateSerializer(data=request.data, context={"request": request})
        serializer.is_valid(raise_exception=True)

        plan = serializer.validated_data["plan"]
        store = serializer.validated_data["store"]
        product = serializer.validated_data.get("product")

        # Save promotion with pending status
        promotion = serializer.save(
            owner=request.user,
            status="pending",
            amount_paid=plan.price,
        )

        # Build description
        target_name = product.name_en if product else store.name_en
        description = f"{plan.name_en} - {target_name}"
        reference = f"PROMO-{promotion.id}"

        # Create payment link via MyFatoorah
        user = request.user
        payment_result = create_payment_link(
            customer_name=user.full_name or user.username,
            customer_email=user.email or "",
            customer_mobile=str(user.phone_number) if user.phone_number else "",
            amount=float(plan.price),
            description=description,
            reference=reference,
            language=getattr(user, "language", "en"),
        )

        # Store payment reference
        promotion.payment_reference = str(payment_result.get("invoice_id", ""))
        promotion.save(update_fields=["payment_reference"])

        return Response(
            {
                "promotion": PromotionSerializer(promotion).data,
                "payment_url": payment_result["invoice_url"],
                "invoice_id": payment_result["invoice_id"],
            },
            status=status.HTTP_201_CREATED,
        )

    @action(detail=True, methods=["post"], url_path="confirm-payment")
    def confirm_payment(self, request, pk=None):
        """POST /promotions/{id}/confirm-payment/ — mobile app confirms payment completed."""
        try:
            promotion = Promotion.objects.get(pk=pk, owner=request.user)
        except Promotion.DoesNotExist:
            return Response(
                {"detail": "Promotion not found."},
                status=status.HTTP_404_NOT_FOUND,
            )

        if promotion.status != "pending":
            return Response(
                {"detail": f"Promotion is already {promotion.status}."},
                status=status.HTTP_400_BAD_REQUEST,
            )

        # Activate the promotion
        from django.utils import timezone
        from dateutil.relativedelta import relativedelta

        now = timezone.now()
        promotion.status = "active"
        promotion.start_date = now
        promotion.end_date = now + relativedelta(months=promotion.plan.duration_months)
        promotion.save(update_fields=["status", "start_date", "end_date"])

        # If this is a store-level promotion, mark the store as top
        if promotion.is_store_promotion:
            promotion.store.is_top = True
            promotion.store.save(update_fields=["is_top"])

        return Response(PromotionSerializer(promotion).data)

    @action(detail=False, methods=["get"], url_path="mine")
    def my_promotions(self, request):
        """GET /promotions/mine/ — current user's promotions."""
        promotions = self.get_queryset().filter(owner=request.user)
        serializer = PromotionSerializer(promotions, many=True)
        return Response(serializer.data)
