from datetime import datetime
from typing import Self

from bb_integrations_lib.gravitate.base_api import BaseAPI
from bb_integrations_lib.secrets.credential_models import AnovaCredential


class AnovaApiClient(BaseAPI):
    def __init__(self, base_url: str, pat_token: str, tenant_id: str):
        super().__init__(timeout=30.0)
        self.base_url = base_url.strip().rstrip("/")
        self.pat_token = pat_token
        self.tenant_id = tenant_id
        self.headers.update({"Authorization": f"Bearer {pat_token}"})

    @classmethod
    def from_credential(cls, credential: AnovaCredential) -> Self:
        return cls(**credential.model_dump(exclude={"type_tag"}))

    async def get_assets(
        self,
        page_index: int = 1,
        page_size: int = 200,
        include_descendants: bool = True,
    ) -> dict:
        params = {
            "pageIndex": page_index,
            "pageSize": page_size,
            "includeDescendants": str(include_descendants).lower(),
        }
        response = await self.get(
            f"{self.base_url}/assets/v1/asset-location/{self.tenant_id}/assets",
            params=params,
        )
        response.raise_for_status()
        return response.json()

    async def get_all_assets(self, page_size: int = 200) -> list[dict]:
        items = []
        page_index = 1
        while True:
            page = await self.get_assets(page_index=page_index, page_size=page_size)
            items.extend(page["items"])
            if page_index * page_size >= page["totalCount"]:
                break
            page_index += 1
        return items

    async def get_readings(
        self, asset_id: int, from_dt: datetime, to_dt: datetime
    ) -> list[dict]:
        params = {
            "from": from_dt.strftime("%Y-%m-%d %H:%M:%S.00"),
            "to": to_dt.strftime("%Y-%m-%d %H:%M:%S.00"),
        }
        response = await self.get(
            f"{self.base_url}/assets/v1/assets/{asset_id}/readings/volume",
            params=params,
        )
        response.raise_for_status()
        return response.json()