# utils/rewards.py

import logging
from setting.views import get_setting_value
from wallet.models import ShoppingPoint
from vendor_listing.tasks import send_purchase_reward_email

logger = logging.getLogger(__name__)

def apply_purchase_reward(order):
    if not order or not order.grand_total:
        logger.info(f"Missing or invalid order or grand_total for Order ID: {getattr(order, 'id', 'Unknown')}")
        return

    buyer = order.buyer

    try:
        purchase_points = int(get_setting_value('purchase_point_percentage'))
    except ValueError:
        logger.error("Invalid 'purchase_point_percentage' in settings. Defaulting to 0.")
        purchase_points = 0

    try:
        shopping_point_credit = round((order.grand_total * purchase_points) / 100, 2)

        logger.info(f"Order #{order.id} total: {order.grand_total}, reward points: {shopping_point_credit}")

        if shopping_point_credit <= 0:
            logger.info(f"No points to credit for Order #{order.id}")
            return

        order_point_exists = ShoppingPoint.objects.filter(
            user=buyer,
            order=order,
            transaction_type='credit'
        ).exists()

        if order_point_exists:
            logger.info(f"Points already credited for Order #{order.id}")
            return

        # Credit shopping points
        ShoppingPoint.objects.create(
            user=buyer,
            transaction_type='credit',
            points=shopping_point_credit,
            description=f"Shopping Points Credit on Order #{order.id}",
            order=order
        )

        logger.info(f"[SHOPPING] ShoppingPoint for buyer {buyer.id} with points : {buyer.total_points}")

        buyer.total_points = (buyer.total_points or 0) + shopping_point_credit
        buyer.save()

        logger.info(
            f"[SHOPPING] Credited {shopping_point_credit} points to user {buyer.id} for Order #{order.id}. "
            f"[SHOPPING] New total_points: {buyer.total_points}"
        )

        try:
            send_purchase_reward_email.delay(buyer.id, shopping_point_credit, order.id)
            logger.info(f"Reward email queued for Order #{order.id}")
        except Exception as e:
            logger.exception(f"Failed to send reward email for Order #{order.id}: {str(e)}")

    except Exception as e:
        logger.exception(f"Error applying purchase reward for Order #{order.id}: {str(e)}")
