package rest

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/nexuscrm/backend/internal/application/services"
	"github.com/nexuscrm/backend/pkg/apierr"
	"github.com/nexuscrm/shared/pkg/constants"
)

// QuickActionHandler handles Salesforce QuickActions API endpoints
// Quick Actions are queried from _System_Action metadata, populated at bootstrap.
type QuickActionHandler struct {
	svcMgr *services.ServiceManager
}

// NewQuickActionHandler creates a new QuickActionHandler
func NewQuickActionHandler(svcMgr *services.ServiceManager) *QuickActionHandler {
	return &QuickActionHandler{svcMgr: svcMgr}
}

// QuickActionDescribe represents the Salesforce QuickAction describe format
type QuickActionDescribe struct {
	ActionEnumOrId      string               `json:"actionEnumOrId"`
	Label               string               `json:"label"`
	Name                string               `json:"name"`
	Type                string               `json:"type"`
	TargetSobjectType   string               `json:"targetSobjectType,omitempty"`
	TargetRecordTypeId  string               `json:"targetRecordTypeId,omitempty"`
	Urls                map[string]string    `json:"urls"`
	Layout              interface{}          `json:"layout,omitempty"`
	VisualforcePageName string               `json:"visualforcePageName,omitempty"`
	CanvasApplicationId string               `json:"canvasApplicationId,omitempty"`
	IconUrl             string               `json:"iconUrl,omitempty"`
	Width               int                  `json:"width,omitempty"`
	Height              int                  `json:"height,omitempty"`
	DefaultValues       []QuickActionDefault `json:"defaultValues,omitempty"`
}

// QuickActionDefault represents default field values for a quick action
type QuickActionDefault struct {
	DefaultValue interface{} `json:"defaultValue"`
	Field        string      `json:"field"`
}

// ListGlobalQuickActions handles GET /quickActions
// Returns all global quick actions available to the user
func (h *QuickActionHandler) ListGlobalQuickActions(c *gin.Context) {
	MustGetUser(c)

	// Global quick actions are not object-scoped — return empty per Salesforce spec
	c.JSON(http.StatusOK, []QuickActionDescribe{})
}

// ListObjectQuickActions handles GET /sobjects/:sobject/quickActions
// Returns quick actions available for a specific object, driven by _System_Action metadata
func (h *QuickActionHandler) ListObjectQuickActions(c *gin.Context) {
	objectName := c.Param("sobject")
	user := MustGetUser(c)

	// Verify object exists
	schema := h.svcMgr.Metadata.GetSchema(c.Request.Context(), objectName)
	if schema == nil {
		c.JSON(http.StatusNotFound, apierr.SFErrorResponse(apierr.SFCodeNotFound, "Object not found"))
		return
	}

	// Check read permission
	canRead := h.svcMgr.Permissions.CheckObjectPermissionWithUser(c.Request.Context(), objectName, constants.PermRead, user)
	if !canRead {
		c.JSON(http.StatusForbidden, apierr.SFErrorResponse(apierr.SFCodeForbidden, "Insufficient access"))
		return
	}

	// Query actions from _System_Action metadata (SSoT)
	metaActions := h.svcMgr.Metadata.GetActions(c.Request.Context(), objectName)

	// Map to ActionMetadata format (matches frontend ActionMetadata interface),
	// filtered by user permissions
	type actionResponse struct {
		ID            string                 `json:"id"`
		ObjectAPIName string                 `json:"objectApiName"`
		Name          string                 `json:"name"`
		Label         string                 `json:"label"`
		Type          string                 `json:"type"`
		Icon          string                 `json:"icon"`
		TargetObject  *string                `json:"targetObject,omitempty"`
		Config        map[string]interface{} `json:"config,omitempty"`
	}

	var actions []actionResponse
	for _, a := range metaActions {
		// Check permission for each action type
		switch a.Name {
		case "Edit":
			if !h.svcMgr.Permissions.CheckObjectPermissionWithUser(c.Request.Context(), objectName, constants.PermEdit, user) {
				continue
			}
		case "Delete":
			if !h.svcMgr.Permissions.CheckObjectPermissionWithUser(c.Request.Context(), objectName, constants.PermDelete, user) {
				continue
			}
		case "Clone":
			if !h.svcMgr.Permissions.CheckObjectPermissionWithUser(c.Request.Context(), objectName, constants.PermCreate, user) {
				continue
			}
		}

		resp := actionResponse{
			ID:            a.ID,
			ObjectAPIName: a.ObjectAPIName,
			Name:          a.Name,
			Label:         a.Label,
			Type:          a.Type,
			Icon:          a.Icon,
			TargetObject:  a.TargetObject,
			Config:        a.Config,
		}
		actions = append(actions, resp)
	}

	if actions == nil {
		actions = []actionResponse{}
	}

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

// DescribeQuickAction handles GET /quickActions/:actionName/describe
// Returns detailed information about a specific quick action
func (h *QuickActionHandler) DescribeQuickAction(c *gin.Context) {
	actionName := c.Param("actionName")
	MustGetUser(c)

	// Quick action describe is not yet implemented — return not found per Salesforce convention
	c.JSON(http.StatusNotFound, apierr.SFErrorResponse(apierr.SFCodeNotFound, "Quick action not found: "+actionName))
}

// ExecuteQuickAction handles POST /quickActions/:actionName
// Executes a quick action
func (h *QuickActionHandler) ExecuteQuickAction(c *gin.Context) {
	actionName := c.Param("actionName")
	MustGetUser(c)

	var body map[string]interface{}
	if err := c.ShouldBindJSON(&body); err != nil {
		c.JSON(http.StatusBadRequest, apierr.SFErrorResponse(apierr.SFCodeInvalidRequest, err.Error()))
		return
	}

	// Execute is not yet implemented — return not-implemented error
	c.JSON(http.StatusBadRequest, apierr.SFErrorResponse(apierr.SFCodeInvalidOperation, "Quick action execution not yet implemented: "+actionName))
}
