import requests

from pypos.core.utils.config_utils import normalize_base_url, read_endpoint_config
from pypos.core.utils.http_retry import post_with_retry
from pypos.core.utils.http_json_utils import parse_json_response

# edited by glg


class JwtAuthService:
    def __init__(self, http_client=None):
        self.http_client = http_client or requests

    def _build_url(self, endpoint_key):
        cfg = read_endpoint_config()
        base_url = normalize_base_url(str(cfg.get("api_base_url") or ""))
        endpoint = str(cfg.get(endpoint_key) or "").strip()
        if not base_url:
            raise ValueError("api_base_url belum diatur")
        if not endpoint:
            raise ValueError(f"Endpoint {endpoint_key} belum diatur")
        if endpoint.startswith(("http://", "https://")):
            return endpoint
        if not endpoint.startswith("/"):
            endpoint = "/" + endpoint
        return f"{base_url}{endpoint}"

    def issue_token(self, username, password, machine_id="", timeout=8):
        url = self._build_url("ep_jwt_issue")
        payload = {
            "username": str(username or ""),
            "password": str(password or ""),
            "machine_id": str(machine_id or ""),
        }
        response = post_with_retry(
            url,
            data=payload,
            timeout=int(timeout),
            session=self.http_client,
            retry_on=(requests.RequestException,),
        )
        data = parse_json_response(response, label="Response JWT issue")
        if not isinstance(data, dict):
            raise ValueError("Response JWT issue tidak valid")
        status = data.get("status")
        if str(status).strip().lower() not in {"1", "true", "ok", "success"} and status is not True and status != 1:
            reason = str(data.get("reason") or data.get("message") or "jwt_issue_failed")
            raise RuntimeError(reason)
        bundle = data.get("data") or {}
        if not isinstance(bundle, dict):
            raise RuntimeError("Bundle JWT tidak valid")
        return {
            "access_token": str(bundle.get("access_token") or ""),
            "refresh_token": str(bundle.get("refresh_token") or ""),
            "token_type": str(bundle.get("token_type") or "Bearer"),
            "expires_in": int(bundle.get("expires_in") or 0),
        }

    def refresh_token(self, refresh_token, timeout=8):
        url = self._build_url("ep_jwt_refresh")
        payload = {"refresh_token": str(refresh_token or "")}
        response = post_with_retry(
            url,
            data=payload,
            timeout=int(timeout),
            session=self.http_client,
            retry_on=(requests.RequestException,),
        )
        data = parse_json_response(response, label="Response JWT refresh")
        if not isinstance(data, dict):
            raise ValueError("Response JWT refresh tidak valid")
        status = data.get("status")
        if str(status).strip().lower() not in {"1", "true", "ok", "success"} and status is not True and status != 1:
            reason = str(data.get("reason") or data.get("message") or "jwt_refresh_failed")
            raise RuntimeError(reason)
        bundle = data.get("data") or {}
        if not isinstance(bundle, dict):
            raise RuntimeError("Bundle refresh JWT tidak valid")
        return {
            "access_token": str(bundle.get("access_token") or ""),
            "refresh_token": str(bundle.get("refresh_token") or ""),
            "token_type": str(bundle.get("token_type") or "Bearer"),
            "expires_in": int(bundle.get("expires_in") or 0),
        }
