"""Heating pilot - the aggregate root for heating decisions."""

from __future__ import annotations

import logging

from ..interfaces import IDecisionStrategy, ISchedulerCommander
from ..value_objects import (
    EnvironmentState,
    HeatingDecision,
)

_LOGGER = logging.getLogger(__name__)


class HeatingPilot:
    """Coordinates heating decisions for a single VTherm.

    This is the aggregate root that orchestrates all domain logic
    for intelligent heating control. It delegates decision-making to
    a configurable strategy, allowing users to choose between:

    - Simple rule-based decisions (no ML required)
    - ML-powered decisions (requires IHP-ML-Models add-on)

    This design follows the Strategy pattern, making the pilot
    independent of the decision algorithm complexity.

    Attributes:
        _decision_strategy: Strategy for making heating decisions
        _scheduler_commander: Interface to control scheduler actions
    """

    def __init__(
        self,
        decision_strategy: IDecisionStrategy,
        scheduler_commander: ISchedulerCommander,
    ) -> None:
        """Initialize the heating pilot.

        Args:
            decision_strategy: Strategy for making heating decisions
                              (simple rules or ML-based)
            scheduler_commander: Implementation of scheduler control interface
        """
        _LOGGER.debug("Initializing HeatingPilot")
        self._decision_strategy = decision_strategy
        self._scheduler_commander = scheduler_commander
        _LOGGER.info(f"HeatingPilot initialized with strategy: {type(decision_strategy).__name__}")

    async def decide_heating_action(
        self,
        environment: EnvironmentState,
    ) -> HeatingDecision:
        """Decide what heating action to take based on current conditions.

        This method delegates the decision to the configured strategy,
        which can be either simple rule-based or ML-powered.

        Args:
            environment: Current environmental conditions

        Returns:
            A heating decision with the action to take
        """
        _LOGGER.debug("HeatingPilot.decide_heating_action called")
        _LOGGER.debug(f"Delegating decision to {type(self._decision_strategy).__name__}")

        decision = await self._decision_strategy.decide_heating_action(environment)

        _LOGGER.info(f"HeatingPilot decision: {decision.action.value}")
        return decision

    async def check_overshoot_risk(
        self,
        environment: EnvironmentState,
        current_slope: float,
    ) -> HeatingDecision:
        """Check if heating should stop to prevent overshooting target.

        This method delegates the overshoot check to the configured strategy.

        Args:
            environment: Current environmental conditions
            current_slope: Current heating rate in °C/hour

        Returns:
            Decision to stop heating if overshoot is detected
        """
        _LOGGER.debug("HeatingPilot.check_overshoot_risk called")
        _LOGGER.debug(f"Delegating overshoot check to {type(self._decision_strategy).__name__}")

        decision = await self._decision_strategy.check_overshoot_risk(environment, current_slope)

        _LOGGER.info(f"HeatingPilot overshoot check: {decision.action.value}")
        return decision
