package scst

import (
	"fmt"
	"net/http"
	"strings"

	"github.com/atlasos/calypso/internal/common/database"
	"github.com/atlasos/calypso/internal/common/logger"
	"github.com/atlasos/calypso/internal/tasks"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
)

// Handler handles SCST-related API requests
type Handler struct {
	service    *Service
	taskEngine *tasks.Engine
	db         *database.DB
	logger     *logger.Logger
}

// NewHandler creates a new SCST handler
func NewHandler(db *database.DB, log *logger.Logger) *Handler {
	return &Handler{
		service:    NewService(db, log),
		taskEngine: tasks.NewEngine(db, log),
		db:         db,
		logger:     log,
	}
}

// ListTargets lists all SCST targets
func (h *Handler) ListTargets(c *gin.Context) {
	targets, err := h.service.ListTargets(c.Request.Context())
	if err != nil {
		h.logger.Error("Failed to list targets", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list targets"})
		return
	}

	// Ensure we return an empty array instead of null
	if targets == nil {
		targets = []Target{}
	}

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

// GetTarget retrieves a target by ID
func (h *Handler) GetTarget(c *gin.Context) {
	targetID := c.Param("id")

	target, err := h.service.GetTarget(c.Request.Context(), targetID)
	if err != nil {
		if err.Error() == "target not found" {
			c.JSON(http.StatusNotFound, gin.H{"error": "target not found"})
			return
		}
		h.logger.Error("Failed to get target", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get target"})
		return
	}

	// Get LUNs
	luns, err := h.service.GetTargetLUNs(c.Request.Context(), targetID)
	if err != nil {
		h.logger.Warn("Failed to get LUNs", "target_id", targetID, "error", err)
		// Return empty array instead of nil
		luns = []LUN{}
	}

	// Get initiator groups
	groups, err2 := h.service.GetTargetInitiatorGroups(c.Request.Context(), targetID)
	if err2 != nil {
		h.logger.Warn("Failed to get initiator groups", "target_id", targetID, "error", err2)
		groups = []InitiatorGroup{}
	}

	c.JSON(http.StatusOK, gin.H{
		"target":           target,
		"luns":             luns,
		"initiator_groups": groups,
	})
}

// CreateTargetRequest represents a target creation request
type CreateTargetRequest struct {
	IQN                 string `json:"iqn" binding:"required"`
	TargetType          string `json:"target_type" binding:"required"`
	Name                string `json:"name" binding:"required"`
	Description         string `json:"description"`
	SingleInitiatorOnly bool   `json:"single_initiator_only"`
}

// CreateTarget creates a new SCST target
func (h *Handler) CreateTarget(c *gin.Context) {
	var req CreateTargetRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
		return
	}

	userID, _ := c.Get("user_id")

	target := &Target{
		IQN:                 req.IQN,
		TargetType:          req.TargetType,
		Name:                req.Name,
		Description:         req.Description,
		IsActive:            true,
		SingleInitiatorOnly: req.SingleInitiatorOnly || req.TargetType == "vtl" || req.TargetType == "physical_tape",
		CreatedBy:           userID.(string),
	}

	if err := h.service.CreateTarget(c.Request.Context(), target); err != nil {
		h.logger.Error("Failed to create target", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// Set alias to name for frontend compatibility (same as ListTargets)
	target.Alias = target.Name
	// LUNCount will be 0 for newly created target
	target.LUNCount = 0

	c.JSON(http.StatusCreated, target)
}

// AddLUNRequest represents a LUN addition request
type AddLUNRequest struct {
	DeviceName  string `json:"device_name" binding:"required"`
	DevicePath  string `json:"device_path" binding:"required"`
	LUNNumber   int    `json:"lun_number"` // Note: cannot use binding:"required" for int as 0 is valid
	HandlerType string `json:"handler_type" binding:"required"`
}

// AddLUN adds a LUN to a target
func (h *Handler) AddLUN(c *gin.Context) {
	targetID := c.Param("id")

	target, err := h.service.GetTarget(c.Request.Context(), targetID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "target not found"})
		return
	}

	var req AddLUNRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		h.logger.Error("Failed to bind AddLUN request", "error", err)
		// Provide more detailed error message
		if validationErr, ok := err.(validator.ValidationErrors); ok {
			var errorMessages []string
			for _, fieldErr := range validationErr {
				errorMessages = append(errorMessages, fmt.Sprintf("%s is required", fieldErr.Field()))
			}
			c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("validation failed: %s", strings.Join(errorMessages, ", "))})
		} else {
			// Extract error message without full struct name
			errMsg := err.Error()
			if idx := strings.Index(errMsg, "Key: '"); idx >= 0 {
				// Extract field name from error message
				fieldStart := idx + 6 // Length of "Key: '"
				if fieldEnd := strings.Index(errMsg[fieldStart:], "'"); fieldEnd >= 0 {
					fieldName := errMsg[fieldStart : fieldStart+fieldEnd]
					c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("invalid or missing field: %s", fieldName)})
				} else {
					c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request format"})
				}
			} else {
				c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("invalid request: %v", err)})
			}
		}
		return
	}

	// Validate required fields (additional check in case binding doesn't catch it)
	if req.DeviceName == "" || req.DevicePath == "" || req.HandlerType == "" {
		h.logger.Error("Missing required fields in AddLUN request", "device_name", req.DeviceName, "device_path", req.DevicePath, "handler_type", req.HandlerType)
		c.JSON(http.StatusBadRequest, gin.H{"error": "device_name, device_path, and handler_type are required"})
		return
	}

	// Validate LUN number range
	if req.LUNNumber < 0 || req.LUNNumber > 255 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "lun_number must be between 0 and 255"})
		return
	}

	if err := h.service.AddLUN(c.Request.Context(), target.IQN, req.DeviceName, req.DevicePath, req.LUNNumber, req.HandlerType); err != nil {
		h.logger.Error("Failed to add LUN", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "LUN added successfully"})
}

// RemoveLUN removes a LUN from a target
func (h *Handler) RemoveLUN(c *gin.Context) {
	targetID := c.Param("id")
	lunID := c.Param("lunId")

	// Get target
	target, err := h.service.GetTarget(c.Request.Context(), targetID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "target not found"})
		return
	}

	// Get LUN to get the LUN number
	var lunNumber int
	err = h.db.QueryRowContext(c.Request.Context(),
		"SELECT lun_number FROM scst_luns WHERE id = $1 AND target_id = $2",
		lunID, targetID,
	).Scan(&lunNumber)
	if err != nil {
		if strings.Contains(err.Error(), "no rows") {
			// LUN already deleted from database - check if it still exists in SCST
			// Try to get LUN number from URL or try common LUN numbers
			// For now, return success since it's already deleted (idempotent)
			h.logger.Info("LUN not found in database, may already be deleted", "lun_id", lunID, "target_id", targetID)
			c.JSON(http.StatusOK, gin.H{"message": "LUN already removed or not found"})
			return
		}
		h.logger.Error("Failed to get LUN", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get LUN"})
		return
	}

	// Remove LUN
	if err := h.service.RemoveLUN(c.Request.Context(), target.IQN, lunNumber); err != nil {
		h.logger.Error("Failed to remove LUN", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "LUN removed successfully"})
}

// AddInitiatorRequest represents an initiator addition request
type AddInitiatorRequest struct {
	InitiatorIQN string `json:"initiator_iqn" binding:"required"`
}

// AddInitiator adds an initiator to a target
func (h *Handler) AddInitiator(c *gin.Context) {
	targetID := c.Param("id")

	target, err := h.service.GetTarget(c.Request.Context(), targetID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "target not found"})
		return
	}

	var req AddInitiatorRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
		return
	}

	if err := h.service.AddInitiator(c.Request.Context(), target.IQN, req.InitiatorIQN); err != nil {
		h.logger.Error("Failed to add initiator", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Initiator added successfully"})
}

// AddInitiatorToGroupRequest represents a request to add an initiator to a group
type AddInitiatorToGroupRequest struct {
	InitiatorIQN string `json:"initiator_iqn" binding:"required"`
}

// AddInitiatorToGroup adds an initiator to a specific group
func (h *Handler) AddInitiatorToGroup(c *gin.Context) {
	groupID := c.Param("id")

	var req AddInitiatorToGroupRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		validationErrors := make(map[string]string)
		if ve, ok := err.(validator.ValidationErrors); ok {
			for _, fe := range ve {
				field := strings.ToLower(fe.Field())
				validationErrors[field] = fmt.Sprintf("Field '%s' is required", field)
			}
		}
		c.JSON(http.StatusBadRequest, gin.H{
			"error":             "invalid request",
			"validation_errors": validationErrors,
		})
		return
	}

	err := h.service.AddInitiatorToGroup(c.Request.Context(), groupID, req.InitiatorIQN)
	if err != nil {
		if strings.Contains(err.Error(), "not found") || strings.Contains(err.Error(), "already exists") || strings.Contains(err.Error(), "single initiator only") {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}
		h.logger.Error("Failed to add initiator to group", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to add initiator to group"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Initiator added to group successfully"})
}

// ListAllInitiators lists all initiators across all targets
func (h *Handler) ListAllInitiators(c *gin.Context) {
	initiators, err := h.service.ListAllInitiators(c.Request.Context())
	if err != nil {
		h.logger.Error("Failed to list initiators", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list initiators"})
		return
	}

	if initiators == nil {
		initiators = []InitiatorWithTarget{}
	}

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

// RemoveInitiator removes an initiator
func (h *Handler) RemoveInitiator(c *gin.Context) {
	initiatorID := c.Param("id")

	if err := h.service.RemoveInitiator(c.Request.Context(), initiatorID); err != nil {
		if err.Error() == "initiator not found" {
			c.JSON(http.StatusNotFound, gin.H{"error": "initiator not found"})
			return
		}
		h.logger.Error("Failed to remove initiator", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Initiator removed successfully"})
}

// GetInitiator retrieves an initiator by ID
func (h *Handler) GetInitiator(c *gin.Context) {
	initiatorID := c.Param("id")

	initiator, err := h.service.GetInitiator(c.Request.Context(), initiatorID)
	if err != nil {
		if err.Error() == "initiator not found" {
			c.JSON(http.StatusNotFound, gin.H{"error": "initiator not found"})
			return
		}
		h.logger.Error("Failed to get initiator", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get initiator"})
		return
	}

	c.JSON(http.StatusOK, initiator)
}

// ListExtents lists all device extents
func (h *Handler) ListExtents(c *gin.Context) {
	extents, err := h.service.ListExtents(c.Request.Context())
	if err != nil {
		h.logger.Error("Failed to list extents", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list extents"})
		return
	}

	if extents == nil {
		extents = []Extent{}
	}

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

// CreateExtentRequest represents a request to create an extent
type CreateExtentRequest struct {
	DeviceName  string `json:"device_name" binding:"required"`
	DevicePath  string `json:"device_path" binding:"required"`
	HandlerType string `json:"handler_type" binding:"required"`
}

// CreateExtent creates a new device extent
func (h *Handler) CreateExtent(c *gin.Context) {
	var req CreateExtentRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
		return
	}

	if err := h.service.CreateExtent(c.Request.Context(), req.DeviceName, req.DevicePath, req.HandlerType); err != nil {
		h.logger.Error("Failed to create extent", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, gin.H{"message": "Extent created successfully"})
}

// DeleteExtent deletes a device extent
func (h *Handler) DeleteExtent(c *gin.Context) {
	deviceName := c.Param("device")

	if err := h.service.DeleteExtent(c.Request.Context(), deviceName); err != nil {
		h.logger.Error("Failed to delete extent", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Extent deleted successfully"})
}

// ApplyConfig applies SCST configuration
func (h *Handler) ApplyConfig(c *gin.Context) {
	userID, _ := c.Get("user_id")

	// Create async task
	taskID, err := h.taskEngine.CreateTask(c.Request.Context(),
		tasks.TaskTypeApplySCST, userID.(string), map[string]interface{}{
			"operation": "apply_scst_config",
		})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create task"})
		return
	}

	// Run apply in background
	go func() {
		ctx := c.Request.Context()
		h.taskEngine.StartTask(ctx, taskID)
		h.taskEngine.UpdateProgress(ctx, taskID, 50, "Writing SCST configuration...")

		configPath := "/etc/calypso/scst/generated.conf"
		if err := h.service.WriteConfig(ctx, configPath); err != nil {
			h.taskEngine.FailTask(ctx, taskID, err.Error())
			return
		}

		h.taskEngine.UpdateProgress(ctx, taskID, 100, "SCST configuration applied")
		h.taskEngine.CompleteTask(ctx, taskID, "SCST configuration applied successfully")
	}()

	c.JSON(http.StatusAccepted, gin.H{"task_id": taskID})
}

// ListHandlers lists available SCST handlers
func (h *Handler) ListHandlers(c *gin.Context) {
	handlers, err := h.service.DetectHandlers(c.Request.Context())
	if err != nil {
		h.logger.Error("Failed to list handlers", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list handlers"})
		return
	}

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

// ListPortals lists all iSCSI portals
func (h *Handler) ListPortals(c *gin.Context) {
	portals, err := h.service.ListPortals(c.Request.Context())
	if err != nil {
		h.logger.Error("Failed to list portals", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list portals"})
		return
	}

	// Ensure we return an empty array instead of null
	if portals == nil {
		portals = []Portal{}
	}

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

// CreatePortal creates a new portal
func (h *Handler) CreatePortal(c *gin.Context) {
	var portal Portal
	if err := c.ShouldBindJSON(&portal); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
		return
	}

	if err := h.service.CreatePortal(c.Request.Context(), &portal); err != nil {
		h.logger.Error("Failed to create portal", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, portal)
}

// UpdatePortal updates a portal
func (h *Handler) UpdatePortal(c *gin.Context) {
	id := c.Param("id")

	var portal Portal
	if err := c.ShouldBindJSON(&portal); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
		return
	}

	if err := h.service.UpdatePortal(c.Request.Context(), id, &portal); err != nil {
		if err.Error() == "portal not found" {
			c.JSON(http.StatusNotFound, gin.H{"error": "portal not found"})
			return
		}
		h.logger.Error("Failed to update portal", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, portal)
}

// EnableTarget enables a target
func (h *Handler) EnableTarget(c *gin.Context) {
	targetID := c.Param("id")

	target, err := h.service.GetTarget(c.Request.Context(), targetID)
	if err != nil {
		if err.Error() == "target not found" {
			c.JSON(http.StatusNotFound, gin.H{"error": "target not found"})
			return
		}
		h.logger.Error("Failed to get target", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get target"})
		return
	}

	if err := h.service.EnableTarget(c.Request.Context(), target.IQN); err != nil {
		h.logger.Error("Failed to enable target", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Target enabled successfully"})
}

// DisableTarget disables a target
func (h *Handler) DisableTarget(c *gin.Context) {
	targetID := c.Param("id")

	target, err := h.service.GetTarget(c.Request.Context(), targetID)
	if err != nil {
		if err.Error() == "target not found" {
			c.JSON(http.StatusNotFound, gin.H{"error": "target not found"})
			return
		}
		h.logger.Error("Failed to get target", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get target"})
		return
	}

	if err := h.service.DisableTarget(c.Request.Context(), target.IQN); err != nil {
		h.logger.Error("Failed to disable target", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Target disabled successfully"})
}

// DeleteTarget deletes a target
func (h *Handler) DeleteTarget(c *gin.Context) {
	targetID := c.Param("id")

	if err := h.service.DeleteTarget(c.Request.Context(), targetID); err != nil {
		if err.Error() == "target not found" {
			c.JSON(http.StatusNotFound, gin.H{"error": "target not found"})
			return
		}
		h.logger.Error("Failed to delete target", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Target deleted successfully"})
}

// DeletePortal deletes a portal
func (h *Handler) DeletePortal(c *gin.Context) {
	id := c.Param("id")

	if err := h.service.DeletePortal(c.Request.Context(), id); err != nil {
		if err.Error() == "portal not found" {
			c.JSON(http.StatusNotFound, gin.H{"error": "portal not found"})
			return
		}
		h.logger.Error("Failed to delete portal", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Portal deleted successfully"})
}

// GetPortal retrieves a portal by ID
func (h *Handler) GetPortal(c *gin.Context) {
	id := c.Param("id")

	portal, err := h.service.GetPortal(c.Request.Context(), id)
	if err != nil {
		if err.Error() == "portal not found" {
			c.JSON(http.StatusNotFound, gin.H{"error": "portal not found"})
			return
		}
		h.logger.Error("Failed to get portal", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get portal"})
		return
	}

	c.JSON(http.StatusOK, portal)
}

// CreateInitiatorGroupRequest represents a request to create an initiator group
type CreateInitiatorGroupRequest struct {
	TargetID  string `json:"target_id" binding:"required"`
	GroupName string `json:"group_name" binding:"required"`
}

// CreateInitiatorGroup creates a new initiator group
func (h *Handler) CreateInitiatorGroup(c *gin.Context) {
	var req CreateInitiatorGroupRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		validationErrors := make(map[string]string)
		if ve, ok := err.(validator.ValidationErrors); ok {
			for _, fe := range ve {
				field := strings.ToLower(fe.Field())
				validationErrors[field] = fmt.Sprintf("Field '%s' is required", field)
			}
		}
		c.JSON(http.StatusBadRequest, gin.H{
			"error":             "invalid request",
			"validation_errors": validationErrors,
		})
		return
	}

	group, err := h.service.CreateInitiatorGroup(c.Request.Context(), req.TargetID, req.GroupName)
	if err != nil {
		if strings.Contains(err.Error(), "already exists") || strings.Contains(err.Error(), "not found") {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}
		h.logger.Error("Failed to create initiator group", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create initiator group"})
		return
	}

	c.JSON(http.StatusOK, group)
}

// UpdateInitiatorGroupRequest represents a request to update an initiator group
type UpdateInitiatorGroupRequest struct {
	GroupName string `json:"group_name" binding:"required"`
}

// UpdateInitiatorGroup updates an initiator group
func (h *Handler) UpdateInitiatorGroup(c *gin.Context) {
	groupID := c.Param("id")

	var req UpdateInitiatorGroupRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		validationErrors := make(map[string]string)
		if ve, ok := err.(validator.ValidationErrors); ok {
			for _, fe := range ve {
				field := strings.ToLower(fe.Field())
				validationErrors[field] = fmt.Sprintf("Field '%s' is required", field)
			}
		}
		c.JSON(http.StatusBadRequest, gin.H{
			"error":             "invalid request",
			"validation_errors": validationErrors,
		})
		return
	}

	group, err := h.service.UpdateInitiatorGroup(c.Request.Context(), groupID, req.GroupName)
	if err != nil {
		if strings.Contains(err.Error(), "not found") || strings.Contains(err.Error(), "already exists") {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}
		h.logger.Error("Failed to update initiator group", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to update initiator group"})
		return
	}

	c.JSON(http.StatusOK, group)
}

// DeleteInitiatorGroup deletes an initiator group
func (h *Handler) DeleteInitiatorGroup(c *gin.Context) {
	groupID := c.Param("id")

	err := h.service.DeleteInitiatorGroup(c.Request.Context(), groupID)
	if err != nil {
		if strings.Contains(err.Error(), "not found") {
			c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
			return
		}
		if strings.Contains(err.Error(), "cannot delete") || strings.Contains(err.Error(), "contains") {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}
		h.logger.Error("Failed to delete initiator group", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to delete initiator group"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "initiator group deleted successfully"})
}

// GetInitiatorGroup retrieves an initiator group by ID
func (h *Handler) GetInitiatorGroup(c *gin.Context) {
	groupID := c.Param("id")

	group, err := h.service.GetInitiatorGroup(c.Request.Context(), groupID)
	if err != nil {
		if strings.Contains(err.Error(), "not found") {
			c.JSON(http.StatusNotFound, gin.H{"error": "initiator group not found"})
			return
		}
		h.logger.Error("Failed to get initiator group", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get initiator group"})
		return
	}

	c.JSON(http.StatusOK, group)
}

// ListAllInitiatorGroups lists all initiator groups
func (h *Handler) ListAllInitiatorGroups(c *gin.Context) {
	groups, err := h.service.ListAllInitiatorGroups(c.Request.Context())
	if err != nil {
		h.logger.Error("Failed to list initiator groups", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list initiator groups"})
		return
	}

	if groups == nil {
		groups = []InitiatorGroup{}
	}

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

// GetConfigFile reads the SCST configuration file content
func (h *Handler) GetConfigFile(c *gin.Context) {
	configPath := c.DefaultQuery("path", "/etc/scst.conf")
	
	content, err := h.service.ReadConfigFile(c.Request.Context(), configPath)
	if err != nil {
		h.logger.Error("Failed to read config file", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"content": content,
		"path":    configPath,
	})
}

// UpdateConfigFile writes content to SCST configuration file
func (h *Handler) UpdateConfigFile(c *gin.Context) {
	var req struct {
		Content string `json:"content" binding:"required"`
		Path    string `json:"path"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
		return
	}

	configPath := req.Path
	if configPath == "" {
		configPath = "/etc/scst.conf"
	}

	if err := h.service.WriteConfigFile(c.Request.Context(), configPath, req.Content); err != nil {
		h.logger.Error("Failed to write config file", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "Configuration file updated successfully",
		"path":    configPath,
	})
}
