package api

import (
	"encoding/json"
	"log"
	"net/http"
	"time"

	"github.com/cynfo/rmm-backend/ws"
)

// POST /api/v1/agents/{id}/wireguard/peers — Neuen WG-Peer anlegen
func (h *Handler) wgAddPeer(hub *ws.Hub) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		agentID := r.PathValue("id")

		var req struct {
			Name       string `json:"name"`
			AllowedIPs string `json:"allowed_ips"`
			DNS        string `json:"dns"`
			ServerName string `json:"server_name"`
		}
		if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.Name == "" {
			writeError(w, http.StatusBadRequest, "Parameter 'name' erforderlich")
			return
		}

		params := map[string]interface{}{
			"name": req.Name,
		}
		if req.AllowedIPs != "" {
			params["allowed_ips"] = req.AllowedIPs
		}
		if req.DNS != "" {
			params["dns"] = req.DNS
		}
		if req.ServerName != "" {
			params["server_name"] = req.ServerName
		}

		h.auditLog(r, "wireguard.add", "agent", agentID, "", req.Name)
		h.sendCommandAndWait(hub, agentID, "wg_add_peer", params, 30, w)
	}
}

// DELETE /api/v1/agents/{id}/wireguard/peers/{uuid} — Peer loeschen
func (h *Handler) wgDeletePeer(hub *ws.Hub) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		agentID := r.PathValue("id")
		peerUUID := r.PathValue("uuid")

		params := map[string]interface{}{
			"peer_uuid": peerUUID,
		}

		h.auditLog(r, "wireguard.delete", "agent", agentID, "", peerUUID)
		h.sendCommandAndWait(hub, agentID, "wg_delete_peer", params, 30, w)
	}
}

// GET /api/v1/agents/{id}/wireguard/peers — Alle Peers auflisten
func (h *Handler) wgListPeers(hub *ws.Hub) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		agentID := r.PathValue("id")

		if !hub.IsAgentConnected(agentID) {
			writeError(w, http.StatusServiceUnavailable, "Agent nicht verbunden")
			return
		}

		serverName := r.URL.Query().Get("server_name")
		params := map[string]interface{}{}
		if serverName != "" {
			params["server_name"] = serverName
		}

		cmdID := generateID()
		cmd := map[string]interface{}{
			"type":    "command",
			"id":      cmdID,
			"command": "wg_list_peers",
			"params":  params,
		}

		responseCh := hub.RegisterResponseWaiter(cmdID)
		defer hub.UnregisterResponseWaiter(cmdID)

		cmdJSON, _ := json.Marshal(cmd)
		if err := hub.SendToAgent(agentID, cmdJSON); err != nil {
			log.Printf("WG list peers senden fehlgeschlagen: %v", err)
			writeError(w, http.StatusInternalServerError, "Command senden fehlgeschlagen")
			return
		}

		select {
		case resp := <-responseCh:
			writeJSON(w, http.StatusOK, resp)
		case <-time.After(30 * time.Second):
			writeError(w, http.StatusGatewayTimeout, "Timeout")
		}
	}
}
