"""Telegram API functions for heartbeat monitoring."""

from __future__ import annotations

import logging
import os
import socket
import time

from heartbeat.config import TTL_SECONDS
from heartbeat.state import load_pending, save_pending

logger = logging.getLogger("health-heartbeat")


def _log_telegram_telemetry(
    message: str,
    *,
    silent: bool = False,
    source: str = "heartbeat",
) -> None:
    """Append Telegram message to local JSONL telemetry log for post-mortem analysis."""
    try:
        import json
        import re
        from datetime import datetime, timezone
        from pathlib import Path

        log_dir = Path.home() / ".cache" / "opendeviationbar" / "telemetry"
        log_dir.mkdir(parents=True, exist_ok=True)
        log_file = log_dir / "telegram.jsonl"

        plain = re.sub(r"<[^>]+>", "", message)
        entry = {
            "ts": datetime.now(timezone.utc).isoformat(),
            "source": source,
            "host": socket.gethostname(),
            "silent": silent,
            "message": plain[:2000],
        }
        with log_file.open("a") as f:
            f.write(json.dumps(entry, ensure_ascii=False) + "\n")
    except Exception:
        pass  # telemetry logging must never break the send path


def delete_telegram_message(token: str, chat_id: str, message_id: int) -> bool:
    """Delete a Telegram message via Bot API (self-contained, no package import)."""
    import requests

    try:
        r = requests.post(
            f"https://api.telegram.org/bot{token}/deleteMessage",
            json={"chat_id": chat_id, "message_id": message_id},
            timeout=10,
        )
        return r.ok
    except requests.exceptions.RequestException:
        return False


def delete_expired() -> int:
    """Delete Telegram messages older than TTL. Returns count deleted."""
    records = load_pending()
    if not records:
        return 0

    token = os.environ.get("OPENDEVIATIONBAR_TELEGRAM_TOKEN", "")
    chat_id = os.environ.get("OPENDEVIATIONBAR_TELEGRAM_CHAT_ID", "90417581")
    if not token:
        return 0

    now = time.time()
    still_pending = []
    deleted = 0

    for rec in records:
        age = now - rec["sent_at"]
        if age >= TTL_SECONDS:
            if delete_telegram_message(token, chat_id, rec["message_id"]):
                deleted += 1
                logger.info(
                    "Deleted heartbeat message %d (age %.0fs)",
                    rec["message_id"],
                    age,
                )
            else:
                # Failed to delete — drop it anyway to avoid infinite retries
                logger.warning(
                    "Failed to delete message %d, dropping from state",
                    rec["message_id"],
                )
        else:
            still_pending.append(rec)

    save_pending(still_pending)
    return deleted


def send_telegram(token: str, chat_id: str, message: str, *, silent: bool) -> int:
    """Send a Telegram message, return message_id (0 on failure)."""
    _log_telegram_telemetry(message, silent=silent, source="heartbeat")

    import requests

    try:
        r = requests.post(
            f"https://api.telegram.org/bot{token}/sendMessage",
            json={
                "chat_id": chat_id,
                "text": message,
                "parse_mode": "HTML",
                "disable_notification": silent,
            },
            timeout=10,
        )
        r.raise_for_status()
        return r.json().get("result", {}).get("message_id", 0)
    except requests.exceptions.RequestException as e:
        logger.warning("Telegram send failed: %s", e)
        return 0


_NTFY_TOPIC = os.environ.get(
    "OPENDEVIATIONBAR_NTFY_TOPIC", "opendeviationbar-heartbeat-deadman"
)
_NTFY_SERVER = os.environ.get("OPENDEVIATIONBAR_NTFY_SERVER", "https://ntfy.sh")


def push_deadman_switch() -> None:
    """Push ntfy dead-man's-switch forward by 15 minutes.

    Every heartbeat (5 min) pushes a scheduled alert 15 min into the future.
    If 3 consecutive heartbeats fail, the message fires from the ntfy.sh server
    — an external dead-man's-switch that works even if bigblack is down.
    """
    import urllib.request

    host = socket.gethostname()
    url = f"{_NTFY_SERVER}/{_NTFY_TOPIC}"
    data = (
        f"DEAD-MAN ALERT: {host} heartbeat stopped. "
        f"No heartbeat received for 15+ minutes. Check systemd timers and host status."
    ).encode()
    req = urllib.request.Request(url, data=data, method="POST")
    req.add_header("Title", f"Heartbeat stopped: {host}")
    req.add_header("Priority", "urgent")
    req.add_header("Tags", "rotating_light,skull")
    req.add_header("At", "+15m")
    try:
        with urllib.request.urlopen(req, timeout=5):
            pass
    except Exception:
        logger.warning("ntfy dead-man's-switch push failed", exc_info=True)
