import logging
import threading
from datetime import datetime

logger = logging.getLogger(__name__)


class HaPoller:
    """Background daemon thread that periodically polls Home Assistant
    for battery percentages and updates installed batteries in the DB.

    Lifecycle:
        poller = HaPoller(ha_client, session_factory, interval_seconds)
        poller.start()   # called once from create_app
        poller.stop()    # not normally needed; daemon thread exits with the process
    """

    def __init__(self, ha_client, session_factory, interval: int):
        self._client = ha_client
        self._Session = session_factory
        self._interval = interval
        self._stop = threading.Event()
        self._thread = threading.Thread(
            target=self._run, name="ha-poller", daemon=True
        )

    def start(self):
        self._thread.start()
        logger.info("HA poller started (interval=%ds)", self._interval)

    def stop(self):
        self._stop.set()

    def _run(self):
        # Wait first so startup DB activity settles before the first poll
        while not self._stop.wait(self._interval):
            self._poll_once()

    def _poll_once(self):
        from models import Battery, BatteryPctLog, Device  # local import avoids circular-import risk

        session = self._Session()
        try:
            devices = (
                session.query(Device)
                .filter(Device.ha_entity_id.isnot(None))
                .all()
            )
            for device in devices:
                pct = self._client.get_state(device.ha_entity_id)
                if pct is not None:
                    pct = max(0, min(100, pct))
                    for battery in device.installed_batteries():
                        if battery.battery_percentage != pct:
                            battery.battery_percentage = pct
                            session.add(BatteryPctLog(
                                battery_id=battery.id,
                                percentage=pct,
                                recorded_at=datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"),
                                source="poll",
                            ))
            session.commit()
            logger.debug("HA poll complete (%d devices checked)", len(devices))
        except Exception as exc:
            session.rollback()
            logger.warning("HA poll failed: %s", exc)
        finally:
            session.close()
