from datetime import date, datetime, timedelta, timezone
from typing import Iterable

from ..auth import Auth
from ..models.ems import ResourceType, UtilityContract, UtilitySpend, UtilityUsage
from .api import ApiEnvironment, ConfiguredApi
from .pagination import PagedRecords


class EmsService(ConfiguredApi):
    """EMS API client"""

    _envs = (
        ApiEnvironment(
            name="production",
            base_url="https://{tenant}.api.ndustrial.io/rest/ems/v1",
            client_id="e2IT0Zm9RgGlDBkLa2ruEcN9Iop6dJAS",
        ),
        ApiEnvironment(
            name="staging",
            base_url="https://{tenant}.api.staging.ndustrial.io/rest/ems/v1",
            client_id="vMV67yaRFgjBB1JFbT3vXBOlohFdG1I4",
        ),
    )

    def __init__(
        self, auth: Auth, org_id: str, org_slug: str, env: str = "production", **kwargs
    ) -> None:
        super().__init__(env=env, auth=auth, **kwargs)
        self.org_id = org_id
        self.base_url = self.base_url.format(tenant=org_slug)

    def get_monthly_utility_spend(
        self,
        facility_id: int,
        resource_type: ResourceType = ResourceType.ELECTRIC,
        start_date: date = date.today() - timedelta(days=3600),
        end_date: date = date.today(),
        pro_forma: bool = False,
        exclude_account_charges: bool = False,
    ) -> UtilitySpend:
        """Get monthly utility spend for facility `facility_id` and resource
        `resource_type` (for now, this must be "electric" but will be expanded).
        Note `start_date` defaults to 10 years ago (the API's maximum limit) and
        `end_date` defaults to today."""
        resp = self.get(
            f"{self.org_id}/facilities/{facility_id}/utility/spend/monthly",
            params={
                "type": resource_type.value,
                "date_start": start_date.strftime("%Y-%m"),
                "date_end": end_date.strftime("%Y-%m"),
                "pro_forma": pro_forma,
                "exclude_account_charges": exclude_account_charges,
            },
        )
        return UtilitySpend.from_api(resp)

    def get_monthly_utility_usage(
        self,
        facility_id: int,
        resource_type: ResourceType = ResourceType.ELECTRIC,
        start_date: date = date.today() - timedelta(days=3600),
        end_date: date = date.today(),
        pro_forma: bool = False,
    ) -> UtilityUsage:
        """Get monthly utility usage for facility `facility_id` and resource
        `resource_type` (for now, this must be "electric" but will be expanded).
        Note `start_date` defaults to 10 years ago (the API's maximum limit) and
        `end_date` defaults to today."""
        resp = self.get(
            f"{self.org_id}/facilities/{facility_id}/utility/usage/monthly",
            params={
                "type": resource_type.value,
                "date_start": start_date.strftime("%Y-%m"),
                "date_end": end_date.strftime("%Y-%m"),
                "pro_forma": pro_forma,
            },
        )
        return UtilityUsage.from_api(resp)

    def get_usage(
        self,
        facility_id: int,
        interval: str,
        resource_type: ResourceType = ResourceType.ELECTRIC,
        start: datetime = datetime.now(timezone.utc) - timedelta(days=365),
        end: datetime = datetime.now(timezone.utc),
    ) -> UtilityUsage:
        """Get utility usage for facility `facility_id` and resource `resource_type`"""
        resp = self.get(
            f"{self.org_id}/facilities/{facility_id}/usage/{interval}",
            params={
                "type": resource_type.value,
                "time_start": int(start.timestamp()),
                "time_end": int(end.timestamp()),
            },
        )
        return UtilityUsage.from_api(resp)

    def get_utility_contracts_for_facility(self, facility_id: int) -> Iterable[UtilityContract]:
        return PagedRecords(
            api=self,
            url=f"{self.org_id}/facilities/{facility_id}/contracts",
            record_parser=UtilityContract.from_api,
        )
