package handlers

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"

	"switchboard-core/store"
	"switchboard-core/triggers"
)

// TriggerHandler provides admin CRUD for extension-declared triggers.
type TriggerHandler struct {
	stores store.Stores
	engine *triggers.Engine
}

// NewTriggerHandler creates a TriggerHandler.
func NewTriggerHandler(stores store.Stores, engine *triggers.Engine) *TriggerHandler {
	return &TriggerHandler{stores: stores, engine: engine}
}

// ListTriggers returns all triggers with optional filters.
// GET /admin/triggers?package_id=&type=&enabled=
func (h *TriggerHandler) ListTriggers(c *gin.Context) {
	opts := store.TriggerListOptions{
		ListOptions: store.ListOptions{
			Limit:  parseIntParam(c, "limit", 50),
			Offset: parseIntParam(c, "offset", 0),
		},
		PackageID: c.Query("package_id"),
		Type:      c.Query("type"),
	}
	if e := c.Query("enabled"); e != "" {
		b := e == "true"
		opts.Enabled = &b
	}

	triggers, total, err := h.stores.Triggers.List(c.Request.Context(), opts)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"triggers": triggers, "total": total})
}

// GetTrigger returns a single trigger by ID.
// GET /admin/triggers/:id
func (h *TriggerHandler) GetTrigger(c *gin.Context) {
	t, err := h.stores.Triggers.GetByID(c.Request.Context(), c.Param("id"))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if t == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "trigger not found"})
		return
	}
	c.JSON(http.StatusOK, t)
}

// EnableTrigger enables a trigger.
// PUT /admin/triggers/:id/enable
func (h *TriggerHandler) EnableTrigger(c *gin.Context) {
	id := c.Param("id")
	if err := h.stores.Triggers.SetEnabled(c.Request.Context(), id, true); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// Re-register with engine
	t, _ := h.stores.Triggers.GetByID(c.Request.Context(), id)
	if t != nil {
		h.engine.RegisterTrigger(t)
	}

	c.JSON(http.StatusOK, gin.H{"ok": true})
}

// DisableTrigger disables a trigger.
// PUT /admin/triggers/:id/disable
func (h *TriggerHandler) DisableTrigger(c *gin.Context) {
	id := c.Param("id")
	if err := h.stores.Triggers.SetEnabled(c.Request.Context(), id, false); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	h.engine.UnregisterTrigger(id)
	c.JSON(http.StatusOK, gin.H{"ok": true})
}

// DeleteTrigger deletes a trigger.
// DELETE /admin/triggers/:id
func (h *TriggerHandler) DeleteTrigger(c *gin.Context) {
	id := c.Param("id")
	h.engine.UnregisterTrigger(id)
	if err := h.stores.Triggers.Delete(c.Request.Context(), id); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"ok": true})
}

// ListTriggerLogs returns execution logs for a trigger.
// GET /admin/triggers/:id/logs?limit=
func (h *TriggerHandler) ListTriggerLogs(c *gin.Context) {
	limit := parseIntParam(c, "limit", 50)
	logs, err := h.stores.Triggers.ListLogs(c.Request.Context(), c.Param("id"), limit)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"logs": logs})
}

// ListPackageTriggers returns triggers for a specific package.
// GET /admin/packages/:id/triggers
func (h *TriggerHandler) ListPackageTriggers(c *gin.Context) {
	triggers, err := h.stores.Triggers.ListByPackage(c.Request.Context(), c.Param("id"))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"triggers": triggers})
}

func parseIntParam(c *gin.Context, key string, defaultVal int) int {
	if v := c.Query(key); v != "" {
		if n, err := strconv.Atoi(v); err == nil && n > 0 {
			return n
		}
	}
	return defaultVal
}
