from __future__ import annotations

from typing import Any
from uuid import UUID

from src.connectors.sdk.base_sdk import SDKConnector
from src.connectors.base import ConnectorResult
from src.core.logging import get_logger

logger = get_logger("rest_connector")


class RESTConnector(SDKConnector):
    connector_type: str = "custom_rest"

    _STOCK_PATH: str = "/stock"
    _RESERVE_PATH: str = "/reservations"
    _PHARMACY_PATH: str = "/pharmacy"
    _SYNC_PATH: str = "/sync"
    _HEALTH_PATH: str = "/health"

    def configure(self, config: dict[str, Any]) -> None:
        self._base_url = config.get("base_url", "")
        self._timeout = config.get("timeout", 30.0)
        self._STOCK_PATH = config.get("stock_path", self._STOCK_PATH)
        self._RESERVE_PATH = config.get("reserve_path", self._RESERVE_PATH)
        self._PHARMACY_PATH = config.get("pharmacy_path", self._PHARMACY_PATH)
        self._SYNC_PATH = config.get("sync_path", self._SYNC_PATH)
        self._HEALTH_PATH = config.get("health_path", self._HEALTH_PATH)
        super().configure(config)

    async def get_stock(self, pharmacy_id: UUID, medication_id: UUID | None = None, nregistro: str | None = None) -> ConnectorResult:
        try:
            params: dict[str, Any] = {"pharmacy_id": str(pharmacy_id)}
            if nregistro:
                params["nregistro"] = nregistro
            if medication_id:
                params["medication_id"] = str(medication_id)
            response = await self._request("GET", self._STOCK_PATH, params=params)
            self._record_metric("get_stock", "success")
            return ConnectorResult(success=True, data=response.json())
        except Exception as exc:
            self._record_metric("get_stock", "error")
            return ConnectorResult(success=False, error=str(exc))

    async def reserve(self, pharmacy_id: UUID, medication_id: UUID, quantity: int, idempotency_key: str | None = None) -> ConnectorResult:
        try:
            payload: dict[str, Any] = {
                "pharmacy_id": str(pharmacy_id),
                "medication_id": str(medication_id),
                "quantity": quantity,
            }
            if idempotency_key:
                payload["idempotency_key"] = idempotency_key
            response = await self._request("POST", self._RESERVE_PATH, json=payload)
            self._record_metric("reserve", "success")
            return ConnectorResult(success=True, data=response.json())
        except Exception as exc:
            self._record_metric("reserve", "error")
            return ConnectorResult(success=False, error=str(exc))

    async def cancel_reservation(self, pharmacy_id: UUID, reservation_id: str) -> ConnectorResult:
        try:
            response = await self._request("DELETE", f"{self._RESERVE_PATH}/{reservation_id}", json={"pharmacy_id": str(pharmacy_id)})
            self._record_metric("cancel_reservation", "success")
            return ConnectorResult(success=True, data=response.json())
        except Exception as exc:
            self._record_metric("cancel_reservation", "error")
            return ConnectorResult(success=False, error=str(exc))

    async def pharmacy_information(self, pharmacy_id: UUID) -> ConnectorResult:
        try:
            response = await self._request("GET", f"{self._PHARMACY_PATH}/{pharmacy_id}")
            self._record_metric("pharmacy_information", "success")
            return ConnectorResult(success=True, data=response.json())
        except Exception as exc:
            self._record_metric("pharmacy_information", "error")
            return ConnectorResult(success=False, error=str(exc))

    async def synchronize(self, pharmacy_id: UUID, strategy: str = "incremental", since: str | None = None) -> ConnectorResult:
        try:
            payload: dict[str, Any] = {"pharmacy_id": str(pharmacy_id), "strategy": strategy}
            if since:
                payload["since"] = since
            response = await self._request("POST", self._SYNC_PATH, json=payload)
            self._record_metric("synchronize", "success")
            return ConnectorResult(success=True, data=response.json())
        except Exception as exc:
            self._record_metric("synchronize", "error")
            return ConnectorResult(success=False, error=str(exc))

    async def heartbeat(self, pharmacy_id: UUID) -> ConnectorResult:
        try:
            response = await self._request("GET", self._HEALTH_PATH)
            data = response.json()
            data["connector_type"] = self.connector_type
            data["pharmacy_id"] = str(pharmacy_id)
            data["circuit_breaker"] = self._circuit_breaker.state.value
            self._record_metric("heartbeat", "success")
            return ConnectorResult(success=True, data=data)
        except Exception as exc:
            self._record_metric("heartbeat", "error")
            return ConnectorResult(success=False, error=str(exc))
