import os
import httpx
from typing import Dict, Any, Optional
from dataclasses import dataclass
from core.config import settings

# =========================
# Configuration (.env)
# =========================
BASE_URL_PAYMENT = settings.PAYMENT_GATEWAY_URL

AUTH_GATEWAY = "service/auth"
URL_INIT_PAYMENT = "v3/sessions"
CHECK_PAYMENT_STATUS = "check_payment_status"


# =========================
# DTO Response
# =========================
@dataclass
class PaymentResponse:
    payment_url: Optional[str] = None
    payment_token: Optional[str] = None
    description: Optional[str] = None
    expired_url: Optional[str] = None
    raw: Optional[Dict[str, Any]] = None

    @property
    def success(self) -> bool:
        return self.payment_url is not None

@dataclass
class PaymentResponseCheck:
    status: Optional[str] = None
    message: Optional[str] = None
    raw: Optional[Dict[str, Any]] = None


# =========================
# Service
# =========================
class InitPaymentWeb:
    def __init__(self, params: Dict[str, Any]):
        self.params = params
        self._auth_token: Optional[str] = None

    # -------------------------
    # Auth Token
    # -------------------------
    async def get_auth_token(self) -> str:
        if self._auth_token:
            return self._auth_token

        auth_body = {
            "auth": {
                "name": settings.SERVICE_GATEWAY,
                "authentication_token": settings.AUTH_TOKEN_GATEWAY,
                "order": "sg8DhR37-mzSO-wcqO-NtTv-NW0nOsjYCtcd"
            }
        }

        async with httpx.AsyncClient(timeout=30) as client:
            response = await client.post(
                f"{BASE_URL_PAYMENT}/{AUTH_GATEWAY}",
                json=auth_body,
                headers={"Accept": "application/json"}
            )

        if response.status_code != 200:
            raise Exception(f"Auth failed: {response.text}")

        data = response.json()
        self._auth_token = data.get("auth_token")

        if not self._auth_token:
            raise Exception("Auth token missing in response")

        return self._auth_token

    # -------------------------
    # Init Payment
    # -------------------------
    async def init_payment(self) -> PaymentResponse:
        token = await self.get_auth_token()

        async with httpx.AsyncClient(timeout=30) as client:
            response = await client.post(
                f"{BASE_URL_PAYMENT}/{URL_INIT_PAYMENT}",
                json=self.params,
                headers={
                    "Authorization": token,
                    "Content-Type": "application/json"
                }
            )

        data = response.json()

        if response.status_code != 200:
            return PaymentResponse(
                description=data.get("description", "Payment init failed"),
                raw=data
            )

        return PaymentResponse(
            payment_url=data.get("payment_url"),
            payment_token=data.get("payment_token"),
            description=data.get("description"),
            expired_url=data.get("expired_url"),
            raw=data
        )


    # -------------------------
    # Check Status
    # -------------------------
  
    async def check_status(self, order: str) -> PaymentResponse:
        token = await self.get_auth_token()

        async with httpx.AsyncClient(timeout=30) as client:
            response = await client.post(
                f"https://securetest.crossroad-africa.net/{CHECK_PAYMENT_STATUS}/{order}",
                headers={
                    "Authorization": token,
                    "Accept": "application/json"
                }
            )

        data = response.json()
        return PaymentResponseCheck(
            status=data.get("code"),      # "1" ou "0"
            message=data.get("message"),
            raw=data.get("data")           # données métier
        )

        
