package main

import (
	"log"

	"github.com/gin-gonic/gin"

	tasktracker "github.com/ankush/implementation-practice/level1_task_tracker"
	loganalyzer "github.com/ankush/implementation-practice/level2_log_analyzer"
	urlshortener "github.com/ankush/implementation-practice/level3_url_shortener"
	notification "github.com/ankush/implementation-practice/level4_notification_system"
)

// AppContainer holds all the dependencies across modules.
type AppContainer struct {
	TaskManager *tasktracker.TaskManager
	URLStore    urlshortener.URLStore
	Hub         *notification.Hub
}

func SetupGatewayRouter(app *AppContainer) *gin.Engine {
	r := gin.Default()

	// 1. Task Tracker Endpoint (Integrates Level 1 + Level 4 Broadcast)
	r.POST("/tasks", func(c *gin.Context) {
		var req struct{ Description string `json:"description" binding:"required"` }
		if err := c.ShouldBindJSON(&req); err != nil {
			c.JSON(400, gin.H{"error": err.Error()})
			return
		}

		// TODO: 
		// 1. Call app.TaskManager.AddTask(req.Description)
		// 2. Broadcast event to app.Hub.Broadcast: "task_created: [description]"
		// 3. Return status 201 with the created task.
	})

	r.GET("/tasks", func(c *gin.Context) {
		// TODO: Call app.TaskManager.ListTasks()
	})

	// 2. Concurrent Log Analyzer (Integrates Level 2)
	r.POST("/logs/analyze", func(c *gin.Context) {
		// Hint: To handle log uploads:
		// form, err := c.MultipartForm()
		// files := form.File["logs"]
		// Save them locally in temporary paths.
		// Call loganalyzer.AnalyzeLogs(c.Request.Context(), tempFilePaths)
		// Return the LogResult JSON.
	})

	// 3. URL Shortener (Integrates Level 3 + Level 4 Broadcast)
	r.POST("/shorten", func(c *gin.Context) {
		var req struct{ URL string `json:"url" binding:"required"` }
		if err := c.ShouldBindJSON(&req); err != nil {
			c.JSON(400, gin.H{"error": err.Error()})
			return
		}

		// TODO:
		// 1. Generate code and save using app.URLStore.Save.
		// 2. Broadcast event to app.Hub.Broadcast: "url_shortened: [code]"
		// 3. Return JSON with the short code and URL.
	})

	r.GET("/:short_code", func(c *gin.Context) {
		// TODO:
		// 1. Resolve using app.URLStore.Get.
		// 2. Increment hits via app.URLStore.IncrementHits.
		// 3. Broadcast event: "url_hit: [code]"
		// 4. Redirect 307.
	})

	// 4. Real-time Event Feed WebSocket (Integrates Level 4 WebSockets)
	r.GET("/ws", func(c *gin.Context) {
		// TODO:
		// 1. Upgrade request to websocket using standard upgrader:
		//    var upgrader = websocket.Upgrader{}
		//    conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
		// 2. Create a client struct wrapping conn.
		// 3. Register client: app.Hub.Register <- client
		// 4. Run client.WritePump() in the background or foreground.
	})

	return r
}

func main() {
	// 1. Instantiate level modules
	tm := tasktracker.NewTaskManager("tasks.json")
	store := urlshortener.NewMemoryStore()
	hub := notification.NewHub()

	// 2. Start the WebSocket hub event-loop
	go hub.Run()

	app := &AppContainer{
		TaskManager: tm,
		URLStore:    store,
		Hub:         hub,
	}

	r := SetupGatewayRouter(app)
	log.Println("Starting Integrated Gateway Service on :8080...")
	r.Run(":8080")
}
