# /opt/docker/dev/service_finder/backend/app/api/v1/endpoints/billing.py
from fastapi import APIRouter, Depends, HTTPException, status, Request, Header
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from typing import Optional, Dict, Any
import logging

from app.api.deps import get_db, get_current_user
from app.models.identity import User, Wallet, UserRole
from app.models import FinancialLedger, WalletType
from app.models.marketplace.payment import PaymentIntent, PaymentIntentStatus
from app.services.config_service import config
from app.services.payment_router import PaymentRouter
from app.services.stripe_adapter import stripe_adapter
from app.services.billing_engine import upgrade_subscription, get_user_balance

router = APIRouter()
logger = logging.getLogger(__name__)

@router.post("/upgrade")
async def upgrade_account(target_package: str, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user)):
    """
    Univerzális csomagváltó a Billing Engine segítségével.
    Kezeli az 5+ csomagot, a Rank-ugrást és a különleges 'Service Coin' bónuszokat.
    """
    try:
        result = await upgrade_subscription(db, current_user.id, target_package)
        return {
            "status": "success",
            "package": target_package,
            "price_paid": result.get("price_paid", 0.0),
            "new_plan": result.get("new_plan"),
            "expires_at": result.get("expires_at"),
            "transaction": result.get("transaction")
        }
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Upgrade error: {e}")
        raise HTTPException(status_code=500, detail=f"Belső hiba: {str(e)}")


@router.post("/payment-intent/create")
async def create_payment_intent(
    request: Dict[str, Any],
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    PaymentIntent létrehozása (Prior Intent - Kettős Lakat 1. lépés).
    
    Body:
    - net_amount: float (kötelező)
    - handling_fee: float (alapértelmezett: 0)
    - target_wallet_type: string (EARNED, PURCHASED, SERVICE_COINS, VOUCHER)
    - beneficiary_id: int (opcionális)
    - currency: string (alapértelmezett: "EUR")
    - metadata: dict (opcionális)
    """
    try:
        # Adatok kinyerése
        net_amount = request.get("net_amount")
        handling_fee = request.get("handling_fee", 0.0)
        target_wallet_type_str = request.get("target_wallet_type")
        beneficiary_id = request.get("beneficiary_id")
        currency = request.get("currency", "EUR")
        metadata = request.get("metadata", {})
        
        # Validáció
        if net_amount is None or net_amount <= 0:
            raise HTTPException(status_code=400, detail="net_amount pozitív szám kell legyen")
        
        if handling_fee < 0:
            raise HTTPException(status_code=400, detail="handling_fee nem lehet negatív")
        
        try:
            target_wallet_type = WalletType(target_wallet_type_str)
        except ValueError:
            raise HTTPException(
                status_code=400, 
                detail=f"Érvénytelen target_wallet_type: {target_wallet_type_str}. Használd: {[wt.value for wt in WalletType]}"
            )
        
        # PaymentIntent létrehozása
        payment_intent = await PaymentRouter.create_payment_intent(
            db=db,
            payer_id=current_user.id,
            net_amount=net_amount,
            handling_fee=handling_fee,
            target_wallet_type=target_wallet_type,
            beneficiary_id=beneficiary_id,
            currency=currency,
            metadata=metadata
        )
        
        return {
            "success": True,
            "payment_intent_id": payment_intent.id,
            "intent_token": str(payment_intent.intent_token),
            "net_amount": float(payment_intent.net_amount),
            "handling_fee": float(payment_intent.handling_fee),
            "gross_amount": float(payment_intent.gross_amount),
            "currency": payment_intent.currency,
            "status": payment_intent.status.value,
            "expires_at": payment_intent.expires_at.isoformat() if payment_intent.expires_at else None,
        }
        
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"PaymentIntent létrehozási hiba: {e}")
        raise HTTPException(status_code=500, detail=f"Belső hiba: {str(e)}")


@router.post("/payment-intent/{payment_intent_id}/stripe-checkout")
async def initiate_stripe_checkout(
    payment_intent_id: int,
    request: Dict[str, Any],
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Stripe Checkout Session indítása PaymentIntent alapján.
    
    Body:
    - success_url: string (kötelező)
    - cancel_url: string (kötelező)
    """
    try:
        success_url = request.get("success_url")
        cancel_url = request.get("cancel_url")
        
        if not success_url or not cancel_url:
            raise HTTPException(status_code=400, detail="success_url és cancel_url kötelező")
        
        # Ellenőrizzük, hogy a PaymentIntent a felhasználóhoz tartozik-e
        stmt = select(PaymentIntent).where(
            PaymentIntent.id == payment_intent_id,
            PaymentIntent.payer_id == current_user.id
        )
        result = await db.execute(stmt)
        payment_intent = result.scalar_one_or_none()
        
        if not payment_intent:
            raise HTTPException(status_code=404, detail="PaymentIntent nem található vagy nincs hozzáférésed")
        
        # Stripe Checkout indítása
        session_data = await PaymentRouter.initiate_stripe_payment(
            db=db,
            payment_intent_id=payment_intent_id,
            success_url=success_url,
            cancel_url=cancel_url
        )
        
        return {
            "success": True,
            "checkout_url": session_data["checkout_url"],
            "stripe_session_id": session_data["stripe_session_id"],
            "expires_at": session_data["expires_at"],
        }
        
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Stripe Checkout indítási hiba: {e}")
        raise HTTPException(status_code=500, detail=f"Belső hiba: {str(e)}")


@router.post("/payment-intent/{payment_intent_id}/process-internal")
async def process_internal_payment(
    payment_intent_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Belső ajándékozás feldolgozása (SmartDeduction használatával).
    Csak akkor engedélyezett, ha a PaymentIntent PENDING státuszú és a felhasználó a payer.
    """
    try:
        # Ellenőrizzük, hogy a PaymentIntent a felhasználóhoz tartozik-e
        stmt = select(PaymentIntent).where(
            PaymentIntent.id == payment_intent_id,
            PaymentIntent.payer_id == current_user.id,
            PaymentIntent.status == PaymentIntentStatus.PENDING
        )
        result = await db.execute(stmt)
        payment_intent = result.scalar_one_or_none()
        
        if not payment_intent:
            raise HTTPException(
                status_code=404, 
                detail="PaymentIntent nem található, nincs hozzáférésed, vagy nem PENDING státuszú"
            )
        
        # Belső fizetés feldolgozása
        result = await PaymentRouter.process_internal_payment(db, payment_intent_id)
        
        if not result["success"]:
            raise HTTPException(status_code=400, detail=result.get("error", "Ismeretlen hiba"))
        
        return {
            "success": True,
            "transaction_id": result.get("transaction_id"),
            "used_amounts": result.get("used_amounts"),
            "beneficiary_credited": result.get("beneficiary_credited", False),
        }
        
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Belső fizetés feldolgozási hiba: {e}")
        raise HTTPException(status_code=500, detail=f"Belső hiba: {str(e)}")


@router.post("/stripe-webhook")
async def stripe_webhook(
    request: Request,
    stripe_signature: Optional[str] = Header(None),
    db: AsyncSession = Depends(get_db)
):
    """
    Stripe webhook végpont a Kettős Lakat validációval.
    
    Stripe a következő header-t küldi: Stripe-Signature
    """
    if not stripe_signature:
        raise HTTPException(status_code=400, detail="Missing Stripe-Signature header")
    
    try:
        # Request body kiolvasása
        payload = await request.body()
        
        # Webhook feldolgozása
        result = await PaymentRouter.process_stripe_webhook(
            db=db,
            payload=payload,
            signature=stripe_signature
        )
        
        if not result.get("success", False):
            error_msg = result.get("error", "Unknown error")
            logger.error(f"Stripe webhook feldolgozás sikertelen: {error_msg}")
            raise HTTPException(status_code=400, detail=error_msg)
        
        return result
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Stripe webhook végpont hiba: {e}")
        raise HTTPException(status_code=500, detail=f"Belső hiba: {str(e)}")


@router.get("/payment-intent/{payment_intent_id}/status")
async def get_payment_intent_status(
    payment_intent_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    PaymentIntent státusz lekérdezése.
    """
    try:
        # Ellenőrizzük, hogy a PaymentIntent a felhasználóhoz tartozik-e
        stmt = select(PaymentIntent).where(
            PaymentIntent.id == payment_intent_id,
            PaymentIntent.payer_id == current_user.id
        )
        result = await db.execute(stmt)
        payment_intent = result.scalar_one_or_none()
        
        if not payment_intent:
            raise HTTPException(status_code=404, detail="PaymentIntent nem található vagy nincs hozzáférésed")
        
        return {
            "id": payment_intent.id,
            "intent_token": str(payment_intent.intent_token),
            "net_amount": float(payment_intent.net_amount),
            "handling_fee": float(payment_intent.handling_fee),
            "gross_amount": float(payment_intent.gross_amount),
            "currency": payment_intent.currency,
            "status": payment_intent.status.value,
            "target_wallet_type": payment_intent.target_wallet_type.value,
            "beneficiary_id": payment_intent.beneficiary_id,
            "stripe_session_id": payment_intent.stripe_session_id,
            "transaction_id": str(payment_intent.transaction_id) if payment_intent.transaction_id else None,
            "created_at": payment_intent.created_at.isoformat(),
            "updated_at": payment_intent.updated_at.isoformat(),
            "completed_at": payment_intent.completed_at.isoformat() if payment_intent.completed_at else None,
            "expires_at": payment_intent.expires_at.isoformat() if payment_intent.expires_at else None,
        }
        
    except Exception as e:
        logger.error(f"PaymentIntent státusz lekérdezési hiba: {e}")
        raise HTTPException(status_code=500, detail=f"Belső hiba: {str(e)}")


@router.get("/wallet/balance")
async def get_wallet_balance(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Felhasználó pénztárca egyenlegének lekérdezése a Billing Engine segítségével.
    """
    try:
        balances = await get_user_balance(db, current_user.id)
        return balances
    except ValueError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except Exception as e:
        logger.error(f"Pénztárca egyenleg lekérdezési hiba: {e}")
        raise HTTPException(status_code=500, detail=f"Belső hiba: {str(e)}")
        raise HTTPException(status_code=500, detail=f"Belső hiba: {str(e)}")