from __future__ import annotations

from typing import Any, Dict, Optional
from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session

from src.core.database import get_session
from src.apps.payment_methods.schemas.payment_methods import (
    PaymentMethodTokenCreateSchema,
    PaymentMethodResponseSchema,
    PaymentMethodSaveSchema,
    PaymentMethodSaveResponseSchema,
    PaymentMethodListFilterSchema,
)
from src.apps.payment_methods.services import (
    get_payment_method_details_from_token,
    save_payment_method,
    get_payment_methods_list,
)
from src.apps.auth.utils.auth import get_current_user, get_current_merchant
from src.apps.merchants.schemas.merchant_common import MerchantSchema
from src.core.utils import constants

router = APIRouter()


@router.post("/token", response_model=PaymentMethodResponseSchema)
async def create_payment_method_from_token_endpoint(
    payload: PaymentMethodTokenCreateSchema,
    db: Session = Depends(get_session),
    merchant: MerchantSchema = Depends(get_current_merchant),
):
    result = await get_payment_method_details_from_token(
        db,
        payment_method_token=payload.payment_method_token,
        merchant_id=merchant.id,
        customer_id=None,
        billing_info=payload.billing_info,
        card_details=payload.card_details,
        ach_details=payload.ach_details,
    )
    return PaymentMethodResponseSchema(**result)


@router.post("/save", response_model=PaymentMethodSaveResponseSchema)
async def save_payment_method_endpoint(
    payload: PaymentMethodSaveSchema,
    db: Session = Depends(get_session),
    current_user = Depends(get_current_user),
    merchant: MerchantSchema = Depends(get_current_merchant),
):
    result = await save_payment_method(
        db,
        payment_method_token=payload.payment_method_token,
        merchant_id=merchant.id,
        payment_method_id=payload.payment_method_id,
        customer_id=payload.customer_id,
        payer_id=payload.payer_id,
        payment_request_id=payload.payment_request_id,
        card_details=payload.card_details,
        ach_details=payload.ach_details,
    )
    return result


@router.get("/", response_model=Dict[str, Any])
async def get_payment_methods_list_endpoint(
    db: Session = Depends(get_session),
    merchant: MerchantSchema = Depends(get_current_merchant),
    filters: PaymentMethodListFilterSchema = Depends(),
    sort_by: str = Query(
        default="-created_at",
        description="Sort column name with direction. Prepend '-' to sort descending. E.g: ?sort_by=-created_at",
    ),
    page: int = Query(
        default=1,
        ge=1,
        description="Page number to fetch",
    ),
    per_page: int = Query(
        default=constants.DEFAULT_PER_PAGE,
        ge=1,
        le=constants.MAX_PER_PAGE,
        description="Number of records per page",
    ),
) -> Any:
    """
    Retrieve payment methods with filtering and pagination.
    Merchant ID is automatically applied from authenticated merchant.
    """
    # Calculate offset from page
    skip = (page - 1) * per_page
    
    # Get payment methods using service
    result = await get_payment_methods_list(
        db=db,
        merchant_id=merchant.id,
        filters=filters,
        sort_by=sort_by,
        skip=skip,
        limit=per_page,
        paginate=True,
    )
    
    return result
