from __future__ import annotations

from django.conf import settings
from rest_framework import serializers


class ContactSerializer(serializers.Serializer):
	email = serializers.EmailField()
	first_name = serializers.CharField(required=False, allow_blank=True)
	last_name = serializers.CharField(required=False, allow_blank=True)
	phone_number = serializers.CharField(required=False, allow_blank=True)
	city = serializers.CharField(required=False, allow_blank=True)
	street = serializers.CharField(required=False, allow_blank=True)
	postal_code = serializers.CharField(required=False, allow_blank=True)
	country_code = serializers.CharField(required=False, allow_blank=True)


class PayerSerializer(serializers.Serializer):
	contact = ContactSerializer()

	# Optional controls – keep everything optional, no card numbers allowed (SDK handles UI)
	allowed_payment_instruments = serializers.ListField(
		child=serializers.CharField(), required=False
	)
	default_payment_instrument = serializers.CharField(required=False)
	allowed_swifts = serializers.ListField(child=serializers.CharField(), required=False)
	default_swift = serializers.CharField(required=False)


class CallbackSerializer(serializers.Serializer):
	return_url = serializers.URLField()
	notification_url = serializers.URLField(required=False)

	def validate(self, attrs):
		# Default notification_url from settings if not provided
		if not attrs.get("notification_url"):
			attrs["notification_url"] = getattr(
				settings, "GOPAY_NOTIFICATION_URL", "http://localhost:8000/api/payments/gopay/webhook"
			)
		return attrs


class ItemSerializer(serializers.Serializer):
	name = serializers.CharField()
	amount = serializers.IntegerField(min_value=1, help_text="Minor units")
	type = serializers.CharField(required=False, default="ITEM")
	count = serializers.IntegerField(required=False, min_value=1, default=1)


class AdditionalParamSerializer(serializers.Serializer):
	name = serializers.CharField()
	value = serializers.CharField()


class PaymentBodySerializer(serializers.Serializer):
	# Minimal required
	amount = serializers.IntegerField(min_value=1, help_text="Minor units (e.g. 100 CZK = 10000)")
	currency = serializers.CharField()
	order_number = serializers.CharField()

	# Optional
	order_description = serializers.CharField(required=False, allow_blank=True)
	payer = PayerSerializer()
	callback = CallbackSerializer()
	items = ItemSerializer(many=True, required=False)
	additional_params = AdditionalParamSerializer(many=True, required=False)
	lang = serializers.CharField(required=False)
	preauthorize = serializers.BooleanField(required=False)

	def validate(self, attrs):
		# Explicitly reject any card details if someone tries to sneak them in
		forbidden_keys = {"card", "card_data", "pan", "cvv", "expiry", "card_number"}
		for key in list(attrs.keys()):
			if key in forbidden_keys:
				raise serializers.ValidationError({key: "Card details must not be sent to the server."})
		return attrs


class PaymentCreateSerializer(serializers.Serializer):
	# Frontend posts { payment: { ... } }
	payment = PaymentBodySerializer()

	# Optional: local metadata only (not sent to GoPay)
	user_id = serializers.IntegerField(required=False)


class RefundSerializer(serializers.Serializer):
	amount = serializers.IntegerField(min_value=1, help_text="Minor units")
