"""Payments router - PayPal subscription management."""

from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, Request, status
from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncSession

from apex.core.authentication.dependencies import get_current_active_user
from apex.infrastructure.database.session import get_db
from apex.infrastructure.paypal import PayPalService
from apex.infrastructure.paypal.schemas import (
    ActivateSubscriptionRequest,
    CancelSubscriptionRequest,
    CreateSubscriptionRequest,
    SubscriptionResponse,
    SuspendSubscriptionRequest,
)
from apex.infrastructure.paypal.webhooks import PayPalWebhookHandler

router = APIRouter(tags=["payments"])


def get_paypal_service() -> PayPalService:
    """Get PayPal service instance."""
    return PayPalService()


def get_webhook_handler() -> PayPalWebhookHandler:
    """Get PayPal webhook handler instance."""
    return PayPalWebhookHandler()


@router.post("/create-subscription", response_model=SubscriptionResponse)
async def create_subscription(
    request: CreateSubscriptionRequest,
    db: Annotated[AsyncSession, Depends(get_db)],
    current_user: dict = Depends(get_current_active_user),
    paypal: PayPalService = Depends(get_paypal_service),
):
    """
    Create a PayPal subscription.

    Args:
        request: Subscription creation request
        db: Database session
        current_user: Current authenticated user
        paypal: PayPal service

    Returns:
        Subscription data with approval links

    Example response:
        {
            "id": "I-BW452GLLEP1G",
            "status": "APPROVAL_PENDING",
            "plan_id": "P-5ML4271244454362WXNWU5NQ",
            "links": [
                {
                    "href": "https://www.paypal.com/webapps/billing/subscriptions?ba_token=...",
                    "rel": "approve",
                    "method": "GET"
                }
            ]
        }
    """
    try:
        subscriber = {
            "name": {
                "given_name": request.subscriber_first_name,
                "surname": request.subscriber_last_name,
            },
            "email_address": request.subscriber_email,
        }

        subscription = await paypal.create_subscription(
            plan_id=request.plan_id,
            subscriber=subscriber,
            return_url=request.return_url,
            cancel_url=request.cancel_url,
        )

        return SubscriptionResponse(**subscription)

    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Failed to create subscription: {str(e)}",
        ) from e


@router.get("/subscriptions/{subscription_id}", response_model=SubscriptionResponse)
async def get_subscription(
    subscription_id: str,
    db: Annotated[AsyncSession, Depends(get_db)],
    current_user: dict = Depends(get_current_active_user),
    paypal: PayPalService = Depends(get_paypal_service),
):
    """
    Get subscription details.

    Args:
        subscription_id: PayPal subscription ID
        db: Database session
        current_user: Current authenticated user
        paypal: PayPal service

    Returns:
        Subscription details
    """
    try:
        subscription = await paypal.get_subscription(subscription_id)
        return SubscriptionResponse(**subscription)

    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Subscription not found: {str(e)}",
        ) from e


@router.post("/cancel", status_code=status.HTTP_200_OK)
async def cancel_subscription(
    request: CancelSubscriptionRequest,
    db: Annotated[AsyncSession, Depends(get_db)],
    current_user: dict = Depends(get_current_active_user),
    paypal: PayPalService = Depends(get_paypal_service),
):
    """
    Cancel a subscription.

    Args:
        request: Cancellation request
        db: Database session
        current_user: Current authenticated user
        paypal: PayPal service

    Returns:
        Success message
    """
    try:
        await paypal.cancel_subscription(
            subscription_id=request.subscription_id,
            reason=request.reason or "User requested cancellation",
        )

        return {"message": "Subscription cancelled successfully"}

    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Failed to cancel subscription: {str(e)}",
        ) from e


@router.post("/suspend", status_code=status.HTTP_200_OK)
async def suspend_subscription(
    request: SuspendSubscriptionRequest,
    db: Annotated[AsyncSession, Depends(get_db)],
    current_user: dict = Depends(get_current_active_user),
    paypal: PayPalService = Depends(get_paypal_service),
):
    """
    Suspend a subscription.

    Args:
        request: Suspension request
        db: Database session
        current_user: Current authenticated user
        paypal: PayPal service

    Returns:
        Success message
    """
    try:
        await paypal.suspend_subscription(
            subscription_id=request.subscription_id,
            reason=request.reason or "Subscription suspended",
        )

        return {"message": "Subscription suspended successfully"}

    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Failed to suspend subscription: {str(e)}",
        ) from e


@router.post("/activate", status_code=status.HTTP_200_OK)
async def activate_subscription(
    request: ActivateSubscriptionRequest,
    db: Annotated[AsyncSession, Depends(get_db)],
    current_user: dict = Depends(get_current_active_user),
    paypal: PayPalService = Depends(get_paypal_service),
):
    """
    Activate a suspended subscription.

    Args:
        request: Activation request
        db: Database session
        current_user: Current authenticated user
        paypal: PayPal service

    Returns:
        Success message
    """
    try:
        await paypal.activate_subscription(
            subscription_id=request.subscription_id,
            reason=request.reason or "Subscription reactivated",
        )

        return {"message": "Subscription activated successfully"}

    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Failed to activate subscription: {str(e)}",
        ) from e


@router.get("/billing-history/{subscription_id}")
async def get_billing_history(
    subscription_id: str,
    start_date: str,
    end_date: str,
    db: Annotated[AsyncSession, Depends(get_db)],
    current_user: dict = Depends(get_current_active_user),
    paypal: PayPalService = Depends(get_paypal_service),
):
    """
    Get billing history for a subscription.

    Args:
        subscription_id: PayPal subscription ID
        start_date: Start date (ISO 8601 format, e.g., 2023-01-01T00:00:00Z)
        end_date: End date (ISO 8601 format)
        db: Database session
        current_user: Current authenticated user
        paypal: PayPal service

    Returns:
        Transaction history
    """
    try:
        transactions = await paypal.list_transactions(
            subscription_id=subscription_id,
            start_date=start_date,
            end_date=end_date,
        )

        return transactions

    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Failed to get billing history: {str(e)}",
        ) from e


@router.post("/webhook", status_code=status.HTTP_200_OK)
async def paypal_webhook(
    request: Request,
    db: Annotated[AsyncSession, Depends(get_db)],
    webhook_handler: PayPalWebhookHandler = Depends(get_webhook_handler),
):
    """
    Handle PayPal webhooks.

    This endpoint receives webhook events from PayPal.
    Configure this URL in your PayPal Developer Dashboard.

    Args:
        request: FastAPI request object
        db: Database session
        webhook_handler: Webhook handler instance

    Returns:
        Success message
    """
    try:
        # Get webhook headers
        transmission_id = request.headers.get("PAYPAL-TRANSMISSION-ID")
        transmission_time = request.headers.get("PAYPAL-TRANSMISSION-TIME")
        cert_url = request.headers.get("PAYPAL-CERT-URL")
        auth_algo = request.headers.get("PAYPAL-AUTH-ALGO")
        transmission_sig = request.headers.get("PAYPAL-TRANSMISSION-SIG")

        # Get webhook body
        webhook_event = await request.json()

        # Verify webhook signature (optional but recommended)
        # webhook_id = settings.PAYPAL_WEBHOOK_ID
        # if webhook_id:
        #     is_valid = await webhook_handler.verify_webhook_signature(
        #         webhook_id=webhook_id,
        #         transmission_id=transmission_id,
        #         transmission_time=transmission_time,
        #         cert_url=cert_url,
        #         auth_algo=auth_algo,
        #         transmission_sig=transmission_sig,
        #         webhook_event=webhook_event,
        #     )
        #     if not is_valid:
        #         raise HTTPException(
        #             status_code=status.HTTP_401_UNAUTHORIZED,
        #             detail="Invalid webhook signature",
        #         )

        # Process webhook event
        result = await webhook_handler.process_webhook_event(webhook_event)

        return {"status": "success", "result": result}

    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Failed to process webhook: {str(e)}",
        ) from e

