from functools import cached_property

import requests

from bubobot_mcp.src.config.config import Config
from bubobot_mcp.src.utils.singleton import BaseSingleton


class BuboBotAPIManager(BaseSingleton):
    def __init__(self, config: Config):
        self.config = config

    @cached_property
    def _base_url(self):
        return self.config.base_bubobot_url

    @cached_property
    def _headers(self):
        return {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        }

    async def make_request(self, bearer_token: str, endpoint: str, body: dict, method: str):
        self._headers.update({'Authorization': f'Bearer {bearer_token}'})
        try:
            if method.upper() == 'GET':
                response = requests.get(
                    url=f"{self._base_url}{endpoint}",
                    headers=self._headers,
                    params=body,
                    timeout=30
                )
            elif method.upper() == 'POST':
                response = requests.post(
                    url=f"{self._base_url}{endpoint}",
                    headers=self._headers,    
                    json=body,
                    timeout=30
                )
            elif method.upper() == 'PUT':
                response = requests.put(
                    url=f"{self._base_url}{endpoint}",
                    headers=self._headers,
                    json=body,
                    timeout=30
                )
            elif method.upper() == 'DELETE':
                response = requests.delete(
                    url=f"{self._base_url}{endpoint}",
                    headers=self._headers,
                    json=body,
                    timeout=30
                )
            else:
                raise ValueError(f"Unsupported HTTP method: {method}")
            
            response.raise_for_status()
            return response.json()
            
        except requests.exceptions.RequestException as e:
            raise Exception(f"Request failed: {str(e)}")
        except ValueError as e:
            raise Exception(f"Invalid method: {str(e)}")
