"""
surepy.pet
====================================
The `Pet` class of surepy

|license-info|
"""

from __future__ import annotations

from datetime import datetime
from typing import Any
from urllib.parse import urlparse

from surepy.entities import PetActivity, PetLocation, StateDrinking, StateFeeding, SurepyEntity
from surepy.entities.states import PetState
from surepy.enums import EntityType, FoodType, Location


class Pet(SurepyEntity):
    """
    Represents pet. Contains attributes of the pet.

    Attributes obtained through Sure PetCare API and include
     - pet ID (int) provided by Sure PetCare
     - pet type default always "pet"
     - pet data: raw output from Sure PetCare API
     - pet name (string) name of pet
     - pet state (integer in API, string in script), one of "outside" or "home"

    """

    def __init__(self, data: dict[str, Any]):

        super().__init__(data=data)

        self.pet_id: int = int(data["id"])

        self._type: EntityType = EntityType.PET
        self._data: dict[str, Any] = data

        self._name = str(name) if (name := self._data.get("name")) else "Unnamed"

        self.state = PetState(data["status"]) if "status" in data else "Unknown"

    @property
    def id(self) -> int:
        """ID of the household the pet belongs to."""
        return self.pet_id

    @property
    def tag_id(self) -> int | None:
        """ID of the household the pet belongs to."""
        return int(tag_id) if (tag_id := self._data.get("tag_id")) else None

    @property
    def food_type(self) -> str | None:
        """Type of food."""
        # pylint: disable=used-before-assignment
        return str(FoodType(type_id)) if (type_id := self._data.get("food_type_id")) else None

    @property
    def updated_at(self) -> datetime | None:
        """Type of food."""
        return (
            datetime.fromisoformat(updated_at)
            if (updated_at := self._data.get("updated_at"))
            else None
        )

    @property
    def photo_url(self) -> str | None:
        """Picture of the Pet."""
        picture_url = (
            photo_url
            if (photo_url := self._data.get("photo", {}).get("location"))
            else "https://surehub.io/assets/images/no-pet-pic-dark.svg"
        )

        return urlparse(picture_url).geturl()

    @property
    def at_home(self) -> bool:
        """Location of the Pet."""
        return bool(self.location.where == Location.INSIDE)

    @property
    def location(self) -> PetLocation:
        """Location of the Pet."""
        position = self._data.get("position", {})
        # pylint: disable=no-member
        return PetLocation(
            where=Location(position.get("where", Location.UNKNOWN.value)),
            since=position.get("since", None),
        )

    @property
    def activity(self) -> PetActivity:
        """Last Activity of the Pet."""
        activity = self._data.get("status", {}).get("activity", {})
        # pylint: disable=no-member
        return PetActivity(
            where=Location(activity.get("where", Location.UNKNOWN.value)),
            since=activity.get("since", None),
        )

    @property
    def feeding(self) -> StateFeeding | None:
        """Last Activity of the Pet."""
        if activity := self._data.get("status", {}).get("feeding", {}):
            return StateFeeding(
                change=activity.get("change", [0.0, 0.0]),
                at=datetime.fromisoformat(activity.get("at", None)),
            )

        return None

    @property
    def drinking(self) -> StateDrinking | None:
        """Last Activity of the Pet."""
        if activity := self._data.get("status", {}).get("drinking", {}):
            return StateDrinking(
                change=activity.get("change", [0.0]),
                at=datetime.fromisoformat(activity.get("at", None)),
            )

        return None

    @property
    def last_lunch(self) -> datetime | None:
        return self.feeding.at if self.feeding else None

    @property
    def last_drink(self) -> datetime | None:
        return self.drinking.at if self.drinking else None
