package api

import (
	"net/http"

	"gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/auth"
	"gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/models"
	"gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/services"
	"github.com/gin-gonic/gin"
	"go.mongodb.org/mongo-driver/v2/bson"
)

func registerChannelRoutes(g *gin.RouterGroup) {
	g.GET("/channels", listChannels)
	g.POST("/channels", createChannel)
	g.PUT("/channels/:id", updateChannel)
	g.DELETE("/channels/:id", deleteChannel)
	g.POST("/channels/:id/test", testChannel)
}

func listChannels(c *gin.Context) {
	channels, err := services.ListChannels(auth.InstanceID(c))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, channels)
}

func createChannel(c *gin.Context) {
	var ch models.NotificationChannel
	if err := c.ShouldBindJSON(&ch); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	if ch.Name == "" || ch.Type == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "name and type are required"})
		return
	}
	created, err := services.CreateChannel(auth.InstanceID(c), &ch)
	if err != nil {
		if limitStatus(c, err) {
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusCreated, created)
}

func updateChannel(c *gin.Context) {
	var body struct {
		Name    *string            `json:"name"`
		Type    *string            `json:"type"`
		Config  *map[string]string `json:"config"`
		Enabled *bool              `json:"enabled"`
	}
	if err := c.ShouldBindJSON(&body); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	upd := bson.M{}
	if body.Name != nil {
		upd["name"] = *body.Name
	}
	if body.Type != nil {
		upd["type"] = *body.Type
	}
	if body.Config != nil {
		upd["config"] = *body.Config
	}
	if body.Enabled != nil {
		upd["enabled"] = *body.Enabled
	}
	if len(upd) == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "no fields to update"})
		return
	}
	if err := services.UpdateChannel(auth.InstanceID(c), c.Param("id"), upd); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.Status(http.StatusNoContent)
}

func deleteChannel(c *gin.Context) {
	if err := services.DeleteChannel(auth.InstanceID(c), c.Param("id")); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.Status(http.StatusNoContent)
}

func testChannel(c *gin.Context) {
	if err := services.TestChannel(auth.InstanceID(c), c.Param("id")); err != nil {
		c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"status": "sent"})
}
