# app/modules/billing/routes/api/store_checkout.py
"""
Store checkout and subscription management endpoints.

Provides:
- Stripe checkout session creation
- Stripe portal session creation
- Subscription cancellation and reactivation
- Upcoming invoice preview
- Tier changes (upgrade/downgrade)

All routes require module access control for the 'billing' module.
Resolves store_id to (merchant_id, platform_id) for all billing service calls.
"""

import logging

from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session

from app.api.deps import get_current_store_api, require_module_access
from app.core.config import settings
from app.core.database import get_db
from app.modules.billing.schemas.billing import (
    CancelRequest,
    CancelResponse,
    ChangeTierRequest,
    ChangeTierResponse,
    CheckoutRequest,
    CheckoutResponse,
    PortalResponse,
    UpcomingInvoiceResponse,
)
from app.modules.billing.services import billing_service
from app.modules.billing.services.subscription_service import subscription_service
from app.modules.enums import FrontendType
from app.modules.tenancy.schemas.auth import UserContext

store_checkout_router = APIRouter(
    dependencies=[Depends(require_module_access("billing", FrontendType.STORE))],
)
logger = logging.getLogger(__name__)


# ============================================================================
# Endpoints
# ============================================================================


@store_checkout_router.post("/checkout", response_model=CheckoutResponse)
def create_checkout_session(
    request: CheckoutRequest,
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
):
    """Create a Stripe checkout session for subscription."""
    store_id = current_user.token_store_id
    merchant_id, platform_id = subscription_service.resolve_store_to_merchant(db, store_id, current_user.token_platform_id)

    store_code = subscription_service.get_store_code(db, store_id)

    base_url = settings.app_base_url.rstrip("/")
    success_url = f"{base_url}/store/{store_code}/billing?success=true"
    cancel_url = f"{base_url}/store/{store_code}/billing?cancelled=true"

    result = billing_service.create_checkout_session(
        db=db,
        merchant_id=merchant_id,
        platform_id=platform_id,
        tier_code=request.tier_code,
        is_annual=request.is_annual,
        success_url=success_url,
        cancel_url=cancel_url,
    )
    db.commit()

    return CheckoutResponse(checkout_url=result["checkout_url"], session_id=result["session_id"])


@store_checkout_router.post("/portal", response_model=PortalResponse)
def create_portal_session(
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
):
    """Create a Stripe customer portal session."""
    store_id = current_user.token_store_id
    merchant_id, platform_id = subscription_service.resolve_store_to_merchant(db, store_id, current_user.token_platform_id)

    store_code = subscription_service.get_store_code(db, store_id)
    return_url = f"{settings.app_base_url.rstrip('/')}/store/{store_code}/billing"

    result = billing_service.create_portal_session(db, merchant_id, platform_id, return_url)

    return PortalResponse(portal_url=result["portal_url"])


@store_checkout_router.post("/cancel", response_model=CancelResponse)
def cancel_subscription(
    request: CancelRequest,
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
):
    """Cancel subscription."""
    store_id = current_user.token_store_id
    merchant_id, platform_id = subscription_service.resolve_store_to_merchant(db, store_id, current_user.token_platform_id)

    result = billing_service.cancel_subscription(
        db=db,
        merchant_id=merchant_id,
        platform_id=platform_id,
        reason=request.reason,
        immediately=request.immediately,
    )
    db.commit()

    return CancelResponse(
        message=result["message"],
        effective_date=result["effective_date"],
    )


@store_checkout_router.post("/reactivate")
def reactivate_subscription(
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
):
    """Reactivate a cancelled subscription."""
    store_id = current_user.token_store_id
    merchant_id, platform_id = subscription_service.resolve_store_to_merchant(db, store_id, current_user.token_platform_id)

    result = billing_service.reactivate_subscription(db, merchant_id, platform_id)
    db.commit()

    return result


@store_checkout_router.get("/upcoming-invoice", response_model=UpcomingInvoiceResponse)
def get_upcoming_invoice(
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
):
    """Preview the upcoming invoice."""
    store_id = current_user.token_store_id
    merchant_id, platform_id = subscription_service.resolve_store_to_merchant(db, store_id, current_user.token_platform_id)

    result = billing_service.get_upcoming_invoice(db, merchant_id, platform_id)

    return UpcomingInvoiceResponse(
        amount_due_cents=result.get("amount_due_cents", 0),
        currency=result.get("currency", "EUR"),
        next_payment_date=result.get("next_payment_date"),
        line_items=result.get("line_items", []),
    )


@store_checkout_router.post("/change-tier", response_model=ChangeTierResponse)
def change_tier(
    request: ChangeTierRequest,
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
):
    """Change subscription tier (upgrade/downgrade)."""
    store_id = current_user.token_store_id
    merchant_id, platform_id = subscription_service.resolve_store_to_merchant(db, store_id, current_user.token_platform_id)

    result = billing_service.change_tier(
        db=db,
        merchant_id=merchant_id,
        platform_id=platform_id,
        new_tier_code=request.tier_code,
        is_annual=request.is_annual,
    )
    db.commit()

    return ChangeTierResponse(
        message=result["message"],
        new_tier=result["new_tier"],
        effective_immediately=result["effective_immediately"],
    )
