package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"time"
)

// WebHookNotification must match the server's definition
type WebHookNotification struct {
	Key       string `json:"key"`
	Value     string `json:"value"`
	EventType int    `json:"event_type"` // 0=Set, 1=Del
	Timestamp int64  `json:"timestamp"`
}

func main() {
	listenPort := ":9601"
	targetNodeAPI := "http://127.0.0.1:8501" // Node 2 API
	myURL := fmt.Sprintf("http://127.0.0.1%s/callback", listenPort)
	
	// Start Listener
	go func() {
		http.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {
			if r.Method != http.MethodPost {
				http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
				return
			}

			body, err := io.ReadAll(r.Body)
			if err != nil {
				log.Printf("Error reading body: %v", err)
				http.Error(w, "Bad request", http.StatusBadRequest)
				return
			}
			defer r.Body.Close()

			var event WebHookNotification
			if err := json.Unmarshal(body, &event); err != nil {
				log.Printf("Error unmarshalling JSON: %v", err)
				http.Error(w, "Invalid JSON", http.StatusBadRequest)
				return
			}

			eventTypeStr := "SET"
			if event.EventType == 1 {
				eventTypeStr = "DEL"
			}

			// Print received event
			fmt.Printf("\n[Client 2 Received] %s\n", time.Now().Format("15:04:05"))
			fmt.Printf("  Key:   %s\n", event.Key)
			fmt.Printf("  Type:  %s\n", eventTypeStr)
			if event.EventType == 0 {
				fmt.Printf("  Value: %s\n", event.Value)
			}
			fmt.Println("----------------------------------------")

			w.WriteHeader(http.StatusOK)
		})

		log.Printf("Client 2 Listener started on %s", listenPort)
		if err := http.ListenAndServe(listenPort, nil); err != nil {
			log.Fatalf("Server failed: %v", err)
		}
	}()

	// Give listener time to start
	time.Sleep(1 * time.Second)

	// Subscribe to Node 2
	log.Printf("Subscribing to Node 2 (%s)...", targetNodeAPI)
	subscribe(targetNodeAPI, "key-2", myURL)

	// Keep running
	select {}
}

func subscribe(apiBase, key, callbackURL string) {
	data := map[string]string{
		"key": key,
		"url": callbackURL,
	}
	jsonData, _ := json.Marshal(data)

	resp, err := http.Post(apiBase+"/watch", "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		log.Printf("Failed to subscribe: %v", err)
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusOK {
		log.Printf("Successfully subscribed to key '%s'", key)
	} else {
		log.Printf("Failed to subscribe, status: %d", resp.StatusCode)
	}
}

