"""
Stripe payment gateway integration utilities.
"""

import logging
from decimal import Decimal
from typing import Any, Dict, Optional

import stripe
from flask import current_app

logger = logging.getLogger(__name__)


class StripeIntegration:
    """
    Stripe payment gateway integration.
    """

    def __init__(self, api_key: str):
        """
        Initialize Stripe integration.

        Args:
            api_key: Stripe API key (secret key)
        """
        self.api_key = api_key
        stripe.api_key = api_key

    def create_payment_intent(
        self,
        amount: Decimal,
        currency: str,
        invoice_id: int,
        description: Optional[str] = None,
        metadata: Optional[Dict[str, Any]] = None,
    ) -> Dict[str, Any]:
        """
        Create a Stripe PaymentIntent.

        Returns:
            dict with 'success', 'client_secret', and 'payment_intent' keys
        """
        try:
            # Convert amount to cents
            amount_cents = int(amount * 100)

            payment_intent_data = {
                "amount": amount_cents,
                "currency": currency.lower(),
                "metadata": {"invoice_id": str(invoice_id), **(metadata or {})},
            }

            if description:
                payment_intent_data["description"] = description

            payment_intent = stripe.PaymentIntent.create(**payment_intent_data)

            return {"success": True, "client_secret": payment_intent.client_secret, "payment_intent": payment_intent}
        except stripe.error.StripeError as e:
            logger.error(f"Stripe error creating payment intent: {e}")
            return {"success": False, "message": str(e), "error_code": e.code if hasattr(e, "code") else None}
        except Exception as e:
            logger.error(f"Error creating payment intent: {e}")
            return {"success": False, "message": f"Error creating payment intent: {str(e)}"}

    def verify_webhook(self, payload: bytes, signature: str, webhook_secret: str) -> Optional[stripe.Event]:
        """
        Verify and parse a Stripe webhook.

        Returns:
            Stripe Event object if valid, None otherwise
        """
        try:
            event = stripe.Webhook.construct_event(payload, signature, webhook_secret)
            return event
        except ValueError as e:
            logger.error(f"Invalid payload: {e}")
            return None
        except stripe.error.SignatureVerificationError as e:
            logger.error(f"Invalid signature: {e}")
            return None

    def get_payment_intent(self, payment_intent_id: str) -> Optional[stripe.PaymentIntent]:
        """Retrieve a PaymentIntent from Stripe"""
        try:
            return stripe.PaymentIntent.retrieve(payment_intent_id)
        except stripe.error.StripeError as e:
            logger.error(f"Error retrieving payment intent: {e}")
            return None

    def create_checkout_session(
        self,
        invoice_id: int,
        amount: Decimal,
        currency: str,
        success_url: str,
        cancel_url: str,
        description: Optional[str] = None,
    ) -> Dict[str, Any]:
        """
        Create a Stripe Checkout Session.

        Returns:
            dict with 'success', 'session_id', and 'url' keys
        """
        try:
            amount_cents = int(amount * 100)

            session_data = {
                "payment_method_types": ["card"],
                "line_items": [
                    {
                        "price_data": {
                            "currency": currency.lower(),
                            "product_data": {
                                "name": description or f"Invoice #{invoice_id}",
                            },
                            "unit_amount": amount_cents,
                        },
                        "quantity": 1,
                    }
                ],
                "mode": "payment",
                "success_url": success_url,
                "cancel_url": cancel_url,
                "metadata": {"invoice_id": str(invoice_id)},
            }

            session = stripe.checkout.Session.create(**session_data)

            return {"success": True, "session_id": session.id, "url": session.url}
        except stripe.error.StripeError as e:
            logger.error(f"Stripe error creating checkout session: {e}")
            return {"success": False, "message": str(e), "error_code": e.code if hasattr(e, "code") else None}
        except Exception as e:
            logger.error(f"Error creating checkout session: {e}")
            return {"success": False, "message": f"Error creating checkout session: {str(e)}"}
