"""کلاینت OTP — فراخوانی Core Service برای ارسال/تأیید کد."""
from __future__ import annotations

import httpx

from app.core.config import settings
from shared.exceptions import AppError, UnauthorizedError


class OtpProxyError(AppError):
    status_code = 502
    error_code = "otp_proxy_failed"


class CoreOtpClient:
    async def request_otp(self, mobile: str, *, force_sms: bool = False) -> dict:
        payload = {"mobile": mobile, "force_sms": force_sms, "context": "public"}
        try:
            async with httpx.AsyncClient(timeout=15.0) as client:
                resp = await client.post(
                    f"{settings.core_service_url}/api/v1/auth/otp/request",
                    json=payload,
                )
        except httpx.RequestError as exc:
            raise OtpProxyError(
                "اتصال به سرویس ارسال کد برقرار نشد؛ لطفاً بعداً دوباره تلاش کنید"
            ) from exc
        if resp.status_code >= 400:
            body = resp.json() if resp.content else {}
            msg = body.get("error", {}).get("message") or "ارسال کد ناموفق بود"
            raise OtpProxyError(msg)
        return resp.json()

    async def verify_otp(
        self,
        mobile: str,
        code: str,
        *,
        keycloak_sub: str | None = None,
        email: str | None = None,
    ) -> dict:
        payload: dict = {
            "mobile": mobile,
            "code": code,
            "context": "public",
        }
        if keycloak_sub:
            payload["keycloak_sub"] = keycloak_sub
        if email:
            payload["email"] = email
        try:
            async with httpx.AsyncClient(timeout=15.0) as client:
                resp = await client.post(
                    f"{settings.core_service_url}/api/v1/auth/otp/verify",
                    json=payload,
                )
        except httpx.RequestError as exc:
            raise OtpProxyError(
                "اتصال به سرویس تأیید کد برقرار نشد؛ لطفاً بعداً دوباره تلاش کنید"
            ) from exc
        if resp.status_code == 401:
            raise UnauthorizedError("کد تأیید نامعتبر یا منقضی شده است")
        if resp.status_code >= 400:
            body = resp.json() if resp.content else {}
            msg = body.get("error", {}).get("message") or "تأیید کد ناموفق بود"
            raise OtpProxyError(msg)
        return resp.json()
