package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "time"

    "chorus.services/bzzz/pkg/hmmm_adapter"
    "chorus.services/hmmm/pkg/hmmm"
)

// mockPubSub simulates the BZZZ pubsub system for demonstration
type mockPubSub struct {
    joinedTopics    map[string]bool
    publishedMsgs   map[string][]byte
}

func newMockPubSub() *mockPubSub {
    return &mockPubSub{
        joinedTopics:  make(map[string]bool),
        publishedMsgs: make(map[string][]byte),
    }
}

func (m *mockPubSub) JoinDynamicTopic(topic string) error {
    fmt.Printf("✅ Joined dynamic topic: %s\n", topic)
    m.joinedTopics[topic] = true
    return nil
}

func (m *mockPubSub) PublishRaw(topic string, payload []byte) error {
    fmt.Printf("📤 Published raw message to topic: %s (size: %d bytes)\n", topic, len(payload))
    m.publishedMsgs[topic] = payload
    return nil
}

func main() {
    fmt.Println("🧪 HMMM Adapter Demonstration")
    fmt.Println("=============================")

    // Create mock pubsub system
    mockPS := newMockPubSub()

    // Create HMMM adapter using the mock pubsub
    adapter := hmmm_adapter.NewAdapter(
        mockPS.JoinDynamicTopic,
        mockPS.PublishRaw,
    )

    fmt.Println("\n1. Testing basic adapter functionality...")
    
    // Test 1: Basic per-issue topic publishing
    issueID := int64(42)
    topic := fmt.Sprintf("bzzz/meta/issue/%d", issueID)
    
    testMessage := map[string]interface{}{
        "version":    1,
        "type":       "meta_msg",
        "issue_id":   issueID,
        "thread_id":  "issue-42",
        "msg_id":     "demo-msg-1",
        "node_id":    "demo-node-12D3KooW",
        "hop_count":  0,
        "timestamp":  time.Now().UTC(),
        "message":    "Demo: HMMM per-issue room initialized.",
    }

    payload, err := json.Marshal(testMessage)
    if err != nil {
        log.Fatalf("Failed to marshal test message: %v", err)
    }

    err = adapter.Publish(context.Background(), topic, payload)
    if err != nil {
        log.Fatalf("Failed to publish message: %v", err)
    }

    fmt.Println("\n2. Testing HMMM Router integration...")
    
    // Test 2: HMMM Router integration
    hmmmRouter := hmmm.NewRouter(adapter, hmmm.DefaultConfig())

    hmmmMessage := hmmm.Message{
        Version:   1,
        Type:      "meta_msg",
        IssueID:   43,
        ThreadID:  "issue-43",
        MsgID:     "hmmm-router-msg-1",
        NodeID:    "demo-node-12D3KooW",
        Author:    "demo-author",
        HopCount:  0,
        Timestamp: time.Now(),
        Message:   "Message published via HMMM Router",
    }

    err = hmmmRouter.Publish(context.Background(), hmmmMessage)
    if err != nil {
        log.Fatalf("Failed to publish via HMMM Router: %v", err)
    }

    fmt.Println("\n3. Testing multiple per-issue topics...")
    
    // Test 3: Multiple per-issue topics
    issueIDs := []int64{100, 101, 102}
    for _, id := range issueIDs {
        topicName := hmmm.TopicForIssue(id)
        msg := map[string]interface{}{
            "version":    1,
            "type":       "meta_msg",
            "issue_id":   id,
            "thread_id":  fmt.Sprintf("issue-%d", id),
            "msg_id":     fmt.Sprintf("multi-test-%d", id),
            "node_id":    "demo-node-12D3KooW",
            "hop_count":  0,
            "timestamp":  time.Now().UTC(),
            "message":    fmt.Sprintf("Message for issue %d", id),
        }
        
        msgPayload, err := json.Marshal(msg)
        if err != nil {
            log.Fatalf("Failed to marshal message for issue %d: %v", id, err)
        }
        
        err = adapter.Publish(context.Background(), topicName, msgPayload)
        if err != nil {
            log.Fatalf("Failed to publish to issue %d: %v", id, err)
        }
    }

    fmt.Println("\n4. Adapter Metrics:")
    fmt.Println("==================")
    
    // Display metrics
    metrics := adapter.GetMetrics()
    fmt.Printf("📊 Publish Count: %d\n", metrics.PublishCount)
    fmt.Printf("🔗 Join Count: %d\n", metrics.JoinCount)
    fmt.Printf("❌ Error Count: %d\n", metrics.ErrorCount)
    fmt.Printf("📂 Joined Topics: %d\n", metrics.JoinedTopics)

    fmt.Println("\n5. Joined Topics:")
    fmt.Println("=================")
    
    joinedTopics := adapter.GetJoinedTopics()
    for i, topic := range joinedTopics {
        fmt.Printf("%d. %s\n", i+1, topic)
    }

    fmt.Println("\n6. Published Messages:")
    fmt.Println("======================")
    
    for topic, payload := range mockPS.publishedMsgs {
        var msg map[string]interface{}
        if err := json.Unmarshal(payload, &msg); err == nil {
            fmt.Printf("Topic: %s\n", topic)
            fmt.Printf("  Message: %v\n", msg["message"])
            fmt.Printf("  Issue ID: %.0f\n", msg["issue_id"])
            fmt.Printf("  Type: %s\n", msg["type"])
            fmt.Println()
        }
    }

    fmt.Println("✅ HMMM Adapter demonstration completed successfully!")
    fmt.Println("\nKey Features Demonstrated:")
    fmt.Println("- ✅ Basic adapter functionality (join + publish)")
    fmt.Println("- ✅ HMMM Router integration")
    fmt.Println("- ✅ Per-issue topic publishing")
    fmt.Println("- ✅ Topic caching (avoid redundant joins)")
    fmt.Println("- ✅ Metrics tracking")
    fmt.Println("- ✅ Raw JSON publishing (no BZZZ envelope)")
    fmt.Println("- ✅ Multiple concurrent topics")
}