"""Billing and subscription management endpoints."""

from __future__ import annotations

from fastapi import APIRouter, Depends, Request, HTTPException
from pydantic import BaseModel

from hieromem_api.auth import require_api_key
from hieromem_api.billing import get_billing_service, get_stripe_module, stripe_available
from hieromem_api.settings import get_settings
from hieromem_api.tenants import Tenant, get_tenant_registry


router = APIRouter(prefix="/billing", tags=["Billing"])


class CheckoutRequest(BaseModel):
    """Request to create checkout session."""
    tier: str  # 'pro' or 'team'
    success_url: str = "https://hieromemsystemsorg.com/dashboard?success=true"
    cancel_url: str = "https://hieromemsystemsorg.com/pricing?canceled=true"


class CheckoutResponse(BaseModel):
    """Response with checkout URL."""
    url: str


class PortalResponse(BaseModel):
    """Response with portal URL."""
    url: str


@router.post("/create-checkout-session", response_model=CheckoutResponse)
async def create_checkout_session(
    req: CheckoutRequest,
    tenant: Tenant = Depends(require_api_key)
):
    """
    Create a Stripe checkout session for upgrading to Pro or Team tier.

    Returns a URL to redirect the user to Stripe checkout.
    """
    if not stripe_available():
        raise HTTPException(status_code=503, detail="Stripe dependency not installed")

    billing = get_billing_service()

    # Validate tier
    if req.tier not in ["pro", "team"]:
        raise HTTPException(status_code=400, detail="Invalid tier. Must be 'pro' or 'team'")

    # Create Stripe customer if not exists
    if not tenant.stripe_customer_id:
        # You'll need to get email from somewhere (user registration, etc.)
        # For now, use tenant_id as placeholder
        customer_id = billing.create_customer(
            email=f"{tenant.tenant_id}@hieromem.local",
            tenant_id=tenant.tenant_id
        )

        # Update tenant with customer ID
        tenant.stripe_customer_id = customer_id
        registry = get_tenant_registry()
        registry.upsert(tenant)

    # Create checkout session
    checkout_url = billing.create_checkout_session(
        customer_id=tenant.stripe_customer_id,
        tier=req.tier,
        success_url=req.success_url,
        cancel_url=req.cancel_url
    )

    return CheckoutResponse(url=checkout_url)


@router.get("/portal", response_model=PortalResponse)
async def get_portal_session(
    return_url: str = "https://hieromemsystemsorg.com/dashboard",
    tenant: Tenant = Depends(require_api_key)
):
    """
    Create a Stripe customer portal session.

    Allows users to manage their subscription, update payment methods, etc.
    """
    if not tenant.stripe_customer_id:
        raise HTTPException(
            status_code=400,
            detail="No Stripe customer found. Please subscribe first."
        )

    if not stripe_available():
        raise HTTPException(status_code=503, detail="Stripe dependency not installed")

    billing = get_billing_service()
    portal_url = billing.create_portal_session(
        customer_id=tenant.stripe_customer_id,
        return_url=return_url
    )

    return PortalResponse(url=portal_url)


@router.post("/webhook")
async def stripe_webhook(request: Request):
    """
    Handle Stripe webhook events.

    This endpoint receives events from Stripe when subscriptions are created,
    updated, or canceled.
    """
    settings = get_settings()
    payload = await request.body()
    sig_header = request.headers.get("stripe-signature")

    if not stripe_available():
        raise HTTPException(status_code=503, detail="Stripe dependency not installed")

    stripe_module = get_stripe_module()

    try:
        event = stripe_module.Webhook.construct_event(
            payload, sig_header, settings.stripe_webhook_secret
        )
    except ValueError:
        # Invalid payload
        raise HTTPException(status_code=400, detail="Invalid payload")
    except stripe_module.error.SignatureVerificationError:
        # Invalid signature
        raise HTTPException(status_code=400, detail="Invalid signature")

    billing = get_billing_service()

    # Handle different event types
    if event["type"] == "checkout.session.completed":
        session = event["data"]["object"]
        billing.handle_checkout_completed(session)

    elif event["type"] == "customer.subscription.updated":
        subscription = event["data"]["object"]
        billing.handle_subscription_updated(subscription)

    elif event["type"] == "customer.subscription.deleted":
        subscription = event["data"]["object"]
        billing.handle_subscription_deleted(subscription)

    elif event["type"] == "invoice.payment_failed":
        # Handle failed payment (could send email, downgrade tier, etc.)
        pass

    return {"status": "success"}


__all__ = ["router"]
