"""Health monitor — periodic checks with AI-powered auto-remediation."""

from __future__ import annotations

import asyncio
import logging
from datetime import datetime, timezone
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from easyclaw_tui.agent.config import AgentConfig
    from easyclaw_tui.agent.core import ForemanAgent

log = logging.getLogger("foreman.monitor")


class HealthMonitor:
    """Periodic health checks with AI-powered auto-fix."""

    def __init__(self, agent: ForemanAgent, config: AgentConfig) -> None:
        self.agent = agent
        self.config = config
        self._running = False
        self._consecutive_failures = 0

        # Set auto-approve for daemon mode (no interactive user)
        from easyclaw_tui.agent.tools.confirm import set_confirm_callback
        set_confirm_callback(self._auto_approve)

    async def _auto_approve(self, question: str) -> str:
        """Auto-approve in daemon mode, but log the action."""
        log.info("Auto-approved (daemon mode): %s", question[:200])
        return "approved (daemon mode — auto-approved)"

    async def run_forever(self) -> None:
        """Main monitor loop. Runs until stopped."""
        self._running = True
        log.info(
            "Health monitor started (interval: %ds)", self.config.check_interval
        )

        while self._running:
            try:
                await self._check_health()
            except Exception as e:
                log.error("Health check error: %s", e)
            await asyncio.sleep(self.config.check_interval)

    def stop(self) -> None:
        self._running = False

    async def _check_health(self) -> None:
        """Run health checks and trigger auto-fix on failure."""
        now = datetime.now(timezone.utc).isoformat()
        self.config.last_health_check = now

        checks = [
            ("systemctl is-active --quiet openclaw-gateway", "Gateway service"),
            (
                "curl -sf --max-time 5 http://localhost:3400/health",
                "Gateway HTTP health",
            ),
        ]

        all_ok = True
        failed_checks: list[tuple[str, str]] = []

        for cmd, label in checks:
            try:
                proc = await asyncio.create_subprocess_shell(
                    cmd,
                    stdout=asyncio.subprocess.PIPE,
                    stderr=asyncio.subprocess.PIPE,
                )
                stdout, stderr = await asyncio.wait_for(
                    proc.communicate(), timeout=15
                )

                if proc.returncode != 0:
                    all_ok = False
                    err = stderr.decode(errors="replace").strip()
                    out = stdout.decode(errors="replace").strip()
                    error_text = err or out or f"exit code {proc.returncode}"
                    log.warning("Health check FAILED: %s — %s", label, error_text)
                    failed_checks.append((label, error_text))

            except asyncio.TimeoutError:
                all_ok = False
                log.warning("Health check TIMEOUT: %s", label)
                failed_checks.append((label, "timed out after 15s"))
            except Exception as e:
                all_ok = False
                log.warning("Health check ERROR: %s — %s", label, e)
                failed_checks.append((label, str(e)))

        if all_ok:
            self._consecutive_failures = 0
            log.debug("Health check passed")
        elif self._consecutive_failures < self.config.max_auto_fix_attempts:
            self._consecutive_failures += 1
            for label, error in failed_checks:
                await self._auto_fix(label, error)
        else:
            log.error(
                "Max auto-fix attempts (%d) reached. Manual intervention needed.",
                self.config.max_auto_fix_attempts,
            )

        self.config.save()

    async def _auto_fix(self, check_name: str, error: str) -> None:
        """Use the agent to diagnose and fix the issue."""
        log.info("Auto-fixing: %s (attempt %d)", check_name, self._consecutive_failures)

        prompt = (
            f"AUTOMATED HEALTH CHECK FAILURE — fix this now.\n\n"
            f"Check: {check_name}\n"
            f"Error: {error}\n\n"
            f"Diagnose this issue and fix it. Check logs, restart services if needed, "
            f"edit config if required, and verify the fix worked. "
            f"This is an automated health check — be decisive and take action."
        )

        try:
            response = await self.agent.chat(prompt)
            log.info("Auto-fix result: %s", response[:500])
            self.config.recent_actions.append(
                {
                    "time": datetime.now(timezone.utc).isoformat(),
                    "check": check_name,
                    "error": error[:200],
                    "action": response[:500],
                }
            )
            # Keep only last 20 actions
            self.config.recent_actions = self.config.recent_actions[-20:]
            # Reset context after auto-fix to keep memory clean
            self.agent.reset()
        except Exception as e:
            log.error("Auto-fix failed: %s", e)
