"""Data models for Pentair Thermal WiFi API."""

from __future__ import annotations

from dataclasses import dataclass
from enum import IntEnum
from typing import Any


class RegulationMode(IntEnum):
    """Thermostat regulation modes."""

    SCHEDULE = 1  # Use the configured schedule
    BOOST = 2  # Boost / comfort temp mode
    MANUAL = 3  # Constant temp mode
    OFF = 5  # Off


def temp_to_celsius(raw_temp: int) -> float:
    """Convert raw temperature (1/100 degrees C) to Celsius.

    Args:
        raw_temp: Temperature in 1/100 degrees Celsius (e.g., 2100 = 21.0°C)

    Returns:
        Temperature in Celsius
    """
    return raw_temp / 100.0


def celsius_to_temp(celsius: float) -> int:
    """Convert Celsius to raw temperature (1/100 degrees C).

    Args:
        celsius: Temperature in Celsius

    Returns:
        Temperature in 1/100 degrees Celsius (e.g., 21.0 = 2100)
    """
    return int(celsius * 100)


@dataclass
class AuthResponse:
    """Response from authentication endpoint."""

    session_id: str
    new_account: bool
    error_code: int
    role_type: int
    email: str
    language: str

    @property
    def is_success(self) -> bool:
        """Check if authentication was successful."""
        return self.error_code == 0 and bool(self.session_id)

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> AuthResponse:
        """Create AuthResponse from API response."""
        return cls(
            session_id=data["SessionId"],
            new_account=data["NewAccount"],
            error_code=data["ErrorCode"],
            role_type=data["RoleType"],
            email=data["Email"],
            language=data["Language"],
        )


@dataclass
class Event:
    """Schedule event."""

    schedule_type: int
    clock: str
    temp_floor: int
    active: bool

    @property
    def temp_floor_celsius(self) -> float:
        """Get floor temperature in Celsius."""
        return temp_to_celsius(self.temp_floor)

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> Event:
        """Create Event from API response."""
        return cls(
            schedule_type=data["ScheduleType"],
            clock=data["Clock"],
            temp_floor=data["TempFloor"],
            active=data["Active"],
        )

    def to_dict(self) -> dict[str, Any]:
        """Convert to API format."""
        return {
            "ScheduleType": self.schedule_type,
            "Clock": self.clock,
            "TempFloor": self.temp_floor,
            "Active": self.active,
        }


@dataclass
class Day:
    """Schedule day."""

    week_day_grp_no: int
    is_defined: bool
    events: list[Event]

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> Day:
        """Create Day from API response."""
        return cls(
            week_day_grp_no=data["WeekDayGrpNo"],
            is_defined=data["IsDefined"],
            events=[Event.from_dict(e) for e in data["Events"]],
        )

    def to_dict(self) -> dict[str, Any]:
        """Convert to API format."""
        return {
            "WeekDayGrpNo": self.week_day_grp_no,
            "IsDefined": self.is_defined,
            "Events": [e.to_dict() for e in self.events],
        }


@dataclass
class Schedule:
    """Thermostat schedule/program."""

    number: int
    name: str
    days: list[Day]

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> Schedule:
        """Create Schedule from API response."""
        return cls(
            number=data["Number"],
            name=data["Name"],
            days=[Day.from_dict(d) for d in data["Days"]],
        )

    def to_dict(self) -> dict[str, Any]:
        """Convert to API format."""
        return {
            "Number": self.number,
            "Name": self.name,
            "Days": [d.to_dict() for d in self.days],
        }


@dataclass
class Thermostat:
    """Thermostat data."""

    serial_number: str
    room: str
    icon_id: int
    group_name: str
    group_id: int
    temperature: int
    regulation_mode: int
    vacation_enabled: bool
    vacation_begin_day: str
    vacation_end_day: str
    vacation_temperature: int
    comfort_temperature: int
    comfort_end_time: str
    comfort_override: int
    manual_temperature: int
    last_primary_mode_is_auto: bool
    frost_temperature: int
    frost_protection_is_enabled: bool
    first_warming_daysleft: int
    boost_duration: int
    boost_floor_temp: int
    boost_room_temp: int
    sensor_application: int
    no_sensor_pwm_index: int
    online: bool
    heating: bool
    early_start_of_heating: bool
    max_temp: int
    min_temp: int
    error_code: int
    confirmed: bool
    email: str
    utc_offset_sec: int
    assigned: bool
    sw_version: str
    has_been_assigned: bool
    selected_schedule: int
    schedules: list[Schedule]

    @property
    def temperature_celsius(self) -> float:
        """Get current temperature in Celsius."""
        return temp_to_celsius(self.temperature)

    @property
    def comfort_temperature_celsius(self) -> float:
        """Get comfort temperature in Celsius."""
        return temp_to_celsius(self.comfort_temperature)

    @property
    def manual_temperature_celsius(self) -> float:
        """Get manual temperature in Celsius."""
        return temp_to_celsius(self.manual_temperature)

    @property
    def vacation_temperature_celsius(self) -> float:
        """Get vacation temperature in Celsius."""
        return temp_to_celsius(self.vacation_temperature)

    @property
    def frost_temperature_celsius(self) -> float:
        """Get frost temperature in Celsius."""
        return temp_to_celsius(self.frost_temperature)

    @property
    def boost_floor_temp_celsius(self) -> float:
        """Get boost floor temperature in Celsius."""
        return temp_to_celsius(self.boost_floor_temp)

    @property
    def boost_room_temp_celsius(self) -> float:
        """Get boost room temperature in Celsius."""
        return temp_to_celsius(self.boost_room_temp)

    @property
    def max_temp_celsius(self) -> float:
        """Get maximum temperature in Celsius."""
        return temp_to_celsius(self.max_temp)

    @property
    def min_temp_celsius(self) -> float:
        """Get minimum temperature in Celsius."""
        return temp_to_celsius(self.min_temp)

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> Thermostat:
        """Create Thermostat from API response."""
        return cls(
            serial_number=data["SerialNumber"],
            room=data["Room"],
            icon_id=data["IconId"],
            group_name=data["GroupName"],
            group_id=data["GroupId"],
            temperature=data["Temperature"],
            regulation_mode=data["RegulationMode"],
            vacation_enabled=data["VacationEnabled"],
            vacation_begin_day=data["VacationBeginDay"],
            vacation_end_day=data["VacationEndDay"],
            vacation_temperature=data["VacationTemperature"],
            comfort_temperature=data["ComfortTemperature"],
            comfort_end_time=data["ComfortEndTime"],
            comfort_override=data["ComfortOverride"],
            manual_temperature=data["ManualTemperature"],
            last_primary_mode_is_auto=data["LastPrimaryModeIsAuto"],
            frost_temperature=data["FrostTemperature"],
            frost_protection_is_enabled=data["FrostProtectionIsEnabled"],
            first_warming_daysleft=data["FirstWarmingDaysleft"],
            boost_duration=data["BoostDuration"],
            boost_floor_temp=data["BoostFloorTemp"],
            boost_room_temp=data["BoostRoomTemp"],
            sensor_application=data["SensorApplication"],
            no_sensor_pwm_index=data["NoSensorPwmIndex"],
            online=data["Online"],
            heating=data["Heating"],
            early_start_of_heating=data["EarlyStartOfHeating"],
            max_temp=data["MaxTemp"],
            min_temp=data["MinTemp"],
            error_code=data["ErrorCode"],
            confirmed=data["Confirmed"],
            email=data["Email"],
            utc_offset_sec=data["UTCOffsetSec"],
            assigned=data["Assigned"],
            sw_version=data["SWVersion"],
            has_been_assigned=data["HasBeenAssigned"],
            selected_schedule=data["SelectedSchedule"],
            schedules=[Schedule.from_dict(s) for s in data["Schedules"]],
        )

    def to_dict(self) -> dict[str, Any]:
        """Convert to API format for updates."""
        return {
            "Room": self.room,
            "SelectedSchedule": self.selected_schedule,
            "BoostDuration": self.boost_duration,
            "BoostFloorTemp": self.boost_floor_temp,
            "BoostRoomTemp": self.boost_room_temp,
            "VacationTemperature": self.vacation_temperature,
            "SensorApplication": self.sensor_application,
            "VacationBeginDay": self.vacation_begin_day,
            "ComfortOverride": self.comfort_override,
            "Schedules": [s.to_dict() for s in self.schedules],
            "FrostTemperature": self.frost_temperature,
            "NoSensorPwmIndex": self.no_sensor_pwm_index,
            "ManualTemperature": self.manual_temperature,
            "ComfortTemperature": self.comfort_temperature,
            "ComfortEndTime": self.comfort_end_time,
            "VacationEnabled": 1 if self.vacation_enabled else 0,
            "VacationEndDay": self.vacation_end_day,
            "RegulationMode": self.regulation_mode,
        }


@dataclass
class Group:
    """Thermostat group."""

    group_name: str
    group_id: int
    group_color: str
    thermostats: list[Thermostat]

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> Group:
        """Create Group from API response."""
        return cls(
            group_name=data["GroupName"],
            group_id=data["GroupId"],
            group_color=data["GroupColor"],
            thermostats=[Thermostat.from_dict(t) for t in data["Thermostats"]],
        )


@dataclass
class ThermostatsResponse:
    """Response from GET /api/thermostat."""

    groups: list[Group]

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> ThermostatsResponse:
        """Create ThermostatsResponse from API response."""
        return cls(groups=[Group.from_dict(g) for g in data["Groups"]])

    def get_all_thermostats(self) -> list[Thermostat]:
        """Get all thermostats from all groups."""
        thermostats = []
        for group in self.groups:
            thermostats.extend(group.thermostats)
        return thermostats

    def get_thermostat(self, serial_number: str) -> Thermostat | None:
        """Get thermostat by serial number."""
        for thermostat in self.get_all_thermostats():
            if thermostat.serial_number == serial_number:
                return thermostat
        return None


@dataclass
class UpdateThermostatResponse:
    """Response from POST /api/thermostat."""

    success: bool

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> UpdateThermostatResponse:
        """Create UpdateThermostatResponse from API response."""
        return cls(success=data["Success"])


@dataclass
class Notification:
    """Notification from the API about a thermostat change."""

    sequence_nr: int
    action: int
    thermostat: Thermostat

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> Notification:
        """Create Notification from API response."""
        return cls(
            sequence_nr=data["SequenceNr"],
            action=data["Action"],
            thermostat=Thermostat.from_dict(data["Thermostat"]),
        )
