"""
API paiement : tarifs, vérification accès, création paiement, IPN PayTech.
"""
import json
import time
import logging
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST, require_GET
from rest_framework import status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from .models import DocumentPrice, DocumentPurchase
from .services import request_payment, verify_ipn


logger = logging.getLogger(__name__)


def _get_prices():
    """Retourne la seule instance DocumentPrice ou des valeurs par défaut."""
    obj = DocumentPrice.objects.first()
    if obj:
        return {"price_bp": obj.price_bp, "price_bmc": obj.price_bmc, "price_pitch": obj.price_pitch}
    return {"price_bp": 5000, "price_bmc": 3000, "price_pitch": 3000}


@api_view(["GET", "PUT"])
@permission_classes([IsAuthenticated])
def prices_view(request):
    """
    GET /api/payment/prices/ – Tarifs des documents (FCFA).
    PUT /api/payment/prices/ – Mise à jour des tarifs (réservé à l'admin).
    """
    if request.method == "GET":
        prices = _get_prices()
        logger.info("PAYMENT prices_view GET user=%s prices=%s", getattr(request.user, "id", None), prices)
        return Response(prices)

    # PUT – admin only
    if not (getattr(request.user, "is_staff", False) or getattr(request.user, "is_superuser", False)):
        return Response({"detail": "Permission refusée."}, status=status.HTTP_403_FORBIDDEN)

    data = request.data or {}
    logger.info("PAYMENT prices_view PUT user=%s payload=%s", request.user.id, data)

    obj, _ = DocumentPrice.objects.get_or_create(id=1)
    for field in ("price_bp", "price_bmc", "price_pitch"):
        if field in data:
            try:
                setattr(obj, field, int(data[field]))
            except (TypeError, ValueError):
                return Response({field: "Valeur invalide."}, status=status.HTTP_400_BAD_REQUEST)
    obj.save()

    prices = {"price_bp": obj.price_bp, "price_bmc": obj.price_bmc, "price_pitch": obj.price_pitch}
    logger.info("PAYMENT prices_view updated prices=%s", prices)
    return Response(prices)


@api_view(["GET"])
@permission_classes([IsAuthenticated])
def check_access_view(request):
    """
    GET /api/payment/check-access/?document_type=bp&document_id=123
    Retourne can_preview (toujours true pour doc existant), can_download, has_paid.
    """
    document_type = (request.query_params.get("document_type") or "").strip().lower()
    if document_type not in ("bp", "bmc", "pitch"):
        return Response(
            {"error": "document_type doit être bp, bmc ou pitch."},
            status=status.HTTP_400_BAD_REQUEST,
        )
    # document_id optionnel ; on débloque par type pour l'user
    has_paid = DocumentPurchase.objects.filter(
        user=request.user,
        document_type=document_type,
        status="completed",
    ).exists()
    return Response({
        "can_preview": True,
        "can_download": has_paid,
        "has_paid": has_paid,
    })


@api_view(["POST"])
@permission_classes([IsAuthenticated])
def create_payment_view(request):
    """
    POST /api/payment/create/
    Body: { "document_type": "bp"|"bmc"|"pitch" }
    Crée une DocumentPurchase pending, appelle PayTech, retourne redirect_url.
    """
    document_type = (request.data.get("document_type") or "").strip().lower()
    if document_type not in ("bp", "bmc", "pitch"):
        return Response(
            {"error": "document_type doit être bp, bmc ou pitch."},
            status=status.HTTP_400_BAD_REQUEST,
        )

    prices = _get_prices()
    amount = prices.get(f"price_{document_type}", 5000)
    labels = {"bp": "Business Plan", "bmc": "BMC", "pitch": "Pitch Deck"}
    item_name = labels.get(document_type, document_type)

    ref_command = f"DOC_{document_type}_{request.user.id}_{int(time.time())}"

    custom_field = {
        "user_id": request.user.id,
        "document_type": document_type,
    }

    logger.info(
        "PAYMENT create_payment_view user=%s type=%s amount=%s ref=%s custom_field=%s",
        request.user.id,
        document_type,
        amount,
        ref_command,
        custom_field,
    )

    result = request_payment(
        item_name=item_name,
        item_price=amount,
        ref_command=ref_command,
        custom_field=custom_field,
        user=request.user,
        document_type=document_type,
    )

    logger.info(
        "PAYMENT create_payment_view PayTech result success=%s message=%s",
        result.get("success"),
        result.get("message"),
    )

    if result.get("success") != 1:
        logger.error(
            "PAYMENT create_payment_view FAILED user=%s type=%s error=%s",
            request.user.id,
            document_type,
            result.get("message"),
        )
        return Response(
            {"error": result.get("message", "Impossible de créer le paiement.")},
            status=status.HTTP_502_BAD_GATEWAY,
        )

    purchase = DocumentPurchase.objects.create(
        user=request.user,
        document_type=document_type,
        amount=amount,
        ref_command=ref_command,
        paytech_token=result.get("token", ""),
        status="pending",
    )
    redirect_url = result["redirect_url"]
    logger.info(
        "PAYMENT create_payment_view CREATED purchase id=%s user=%s type=%s amount=%s redirect_url=%r",
        purchase.id,
        request.user.id,
        document_type,
        amount,
        redirect_url,
    )
    print("[PAYMENT] CREATED purchase_id=%s redirect_url=%s" % (purchase.id, redirect_url))
    return Response(
        {
            "redirect_url": redirect_url,
            "purchase_id": purchase.id,
            "ref_command": ref_command,
        },
        status=status.HTTP_201_CREATED,
    )


@csrf_exempt
@require_POST
def ipn_view(request):
    """
    POST /api/payment/ipn/ – Webhook PayTech (notification instantanée).
    Vérifie la signature puis met à jour DocumentPurchase en completed.
    """
    from django.http import HttpResponse

    if not verify_ipn(request):
        return HttpResponse("IPN KO", status=403)

    type_event = request.POST.get("type_event", "")
    ref_command = request.POST.get("ref_command", "")

    if type_event == "sale_complete":
        from django.utils import timezone
        DocumentPurchase.objects.filter(ref_command=ref_command).update(
            status="completed",
            paid_at=timezone.now(),
        )
    elif type_event == "sale_canceled":
        DocumentPurchase.objects.filter(ref_command=ref_command).update(status="canceled")

    return HttpResponse("IPN OK", status=200)


@api_view(["GET"])
@permission_classes([IsAuthenticated])
def purchases_list_view(request):
    """
    GET /api/payment/purchases/ – Liste des paiements (réservée à l'admin).
    """
    if not (getattr(request.user, "is_staff", False) or getattr(request.user, "is_superuser", False)):
        return Response({"detail": "Permission refusée."}, status=status.HTTP_403_FORBIDDEN)

    qs = (
        DocumentPurchase.objects.select_related("user")
        .order_by("-created_at")
    )

    items = []
    for p in qs:
        user = getattr(p, "user", None)
        item = {
            "id": p.id,
            "user_id": p.user_id,
            "user_email": getattr(user, "email", "") if user else "",
            "document_type": p.document_type,
            "amount": p.amount,
            "status": p.status,
            "ref_command": p.ref_command,
            "paid_at": p.paid_at,
            "created_at": p.created_at,
        }
        items.append(item)

    logger.info("PAYMENT purchases_list_view count=%s", len(items))
    return Response(items)