"""
Watcher Manager — admin API for series3-watcher and thor-watcher agents.

Endpoints:
  GET  /api/admin/watchers                      — list all watcher agents
  GET  /api/admin/watchers/{agent_id}           — get single agent detail
  POST /api/admin/watchers/{agent_id}/trigger-update  — flag agent for update
  POST /api/admin/watchers/{agent_id}/clear-update    — clear update flag
  GET  /api/admin/watchers/{agent_id}/update-check    — polled by watcher on heartbeat

Page:
  GET  /admin/watchers                          — HTML admin page
"""

from datetime import datetime, timezone
from fastapi import APIRouter, Depends, HTTPException, Request
from fastapi.responses import HTMLResponse
from pydantic import BaseModel
from sqlalchemy.orm import Session
from typing import Optional

from backend.database import get_db
from backend.models import WatcherAgent
from backend.templates_config import templates

router = APIRouter(tags=["admin"])


# ── helpers ──────────────────────────────────────────────────────────────────

def _agent_to_dict(agent: WatcherAgent) -> dict:
    last_seen = agent.last_seen
    if last_seen:
        now_utc = datetime.utcnow()
        age_minutes = int((now_utc - last_seen).total_seconds() // 60)
        if age_minutes > 60:
            status = "missing"
        else:
            status = "ok"
    else:
        age_minutes = None
        status = "missing"

    return {
        "id": agent.id,
        "source_type": agent.source_type,
        "version": agent.version,
        "last_seen": last_seen.isoformat() if last_seen else None,
        "age_minutes": age_minutes,
        "status": status,
        "ip_address": agent.ip_address,
        "log_tail": agent.log_tail,
        "update_pending": bool(agent.update_pending),
        "update_version": agent.update_version,
    }


# ── API routes ────────────────────────────────────────────────────────────────

@router.get("/api/admin/watchers")
def list_watchers(db: Session = Depends(get_db)):
    agents = db.query(WatcherAgent).order_by(WatcherAgent.last_seen.desc()).all()
    return [_agent_to_dict(a) for a in agents]


@router.get("/api/admin/watchers/{agent_id}")
def get_watcher(agent_id: str, db: Session = Depends(get_db)):
    agent = db.query(WatcherAgent).filter(WatcherAgent.id == agent_id).first()
    if not agent:
        raise HTTPException(status_code=404, detail="Watcher agent not found")
    return _agent_to_dict(agent)


class TriggerUpdateRequest(BaseModel):
    version: Optional[str] = None  # target version label (informational)


@router.post("/api/admin/watchers/{agent_id}/trigger-update")
def trigger_update(agent_id: str, body: TriggerUpdateRequest, db: Session = Depends(get_db)):
    agent = db.query(WatcherAgent).filter(WatcherAgent.id == agent_id).first()
    if not agent:
        raise HTTPException(status_code=404, detail="Watcher agent not found")
    agent.update_pending = True
    agent.update_version = body.version
    db.commit()
    return {"ok": True, "agent_id": agent_id, "update_pending": True}


@router.post("/api/admin/watchers/{agent_id}/clear-update")
def clear_update(agent_id: str, db: Session = Depends(get_db)):
    agent = db.query(WatcherAgent).filter(WatcherAgent.id == agent_id).first()
    if not agent:
        raise HTTPException(status_code=404, detail="Watcher agent not found")
    agent.update_pending = False
    agent.update_version = None
    db.commit()
    return {"ok": True, "agent_id": agent_id, "update_pending": False}


@router.get("/api/admin/watchers/{agent_id}/update-check")
def update_check(agent_id: str, db: Session = Depends(get_db)):
    """
    Polled by watcher agents on each heartbeat cycle.
    Returns update_available=True when an update has been triggered via the UI.
    Automatically clears the flag after the watcher acknowledges it.
    """
    agent = db.query(WatcherAgent).filter(WatcherAgent.id == agent_id).first()
    if not agent:
        return {"update_available": False}

    pending = bool(agent.update_pending)

    if pending:
        # Clear the flag — the watcher will now self-update
        agent.update_pending = False
        db.commit()

    return {
        "update_available": pending,
        "version": agent.update_version,
    }


# ── HTML page ─────────────────────────────────────────────────────────────────

@router.get("/admin/watchers", response_class=HTMLResponse)
def admin_watchers_page(request: Request, db: Session = Depends(get_db)):
    agents = db.query(WatcherAgent).order_by(WatcherAgent.last_seen.desc()).all()
    agents_data = [_agent_to_dict(a) for a in agents]
    return templates.TemplateResponse("admin_watchers.html", {
        "request": request,
        "agents": agents_data,
    })
