package graph

// This file will be automatically regenerated based on the schema, any resolver
// implementations
// will be copied through when generating and any unknown code will be moved to the end.
// Code generated by github.com/99designs/gqlgen version v0.17.87

import (
	"context"
	"errors"
	"fmt"
	"time"

	"gogs.dmsc.dev/arp/auth"
	"gogs.dmsc.dev/arp/graph/model"
	"gogs.dmsc.dev/arp/logging"
	"gogs.dmsc.dev/arp/models"
	"gogs.dmsc.dev/arp/workflow"
)

// Login is the resolver for the login field.
func (r *mutationResolver) Login(ctx context.Context, email string, password string) (*model.AuthPayload, error) {
	var user models.User
	if err := r.DB.Preload("Roles.Permissions").Where("email = ?", email).First(&user).Error; err != nil {
		return nil, errors.New("invalid credentials")
	}

	// Check password
	if !auth.CheckPassword(password, user.Password) {
		return nil, errors.New("invalid credentials")
	}

	token, err := auth.GenerateToken(user)
	if err != nil {
		return nil, fmt.Errorf("failed to generate token: %w", err)
	}

	return &model.AuthPayload{
		Token: token,
		User:  convertUser(user),
	}, nil
}

// CreateUser is the resolver for the createUser field.
func (r *mutationResolver) CreateUser(ctx context.Context, input model.NewUser) (*model.User, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	roles := make([]models.Role, len(input.Roles))
	for i, roleIDStr := range input.Roles {
		roleID, err := toID(roleIDStr)
		if err != nil {
			return nil, fmt.Errorf("invalid role ID: %w", err)
		}
		var role models.Role
		if err := r.DB.First(&role, roleID).Error; err != nil {
			return nil, fmt.Errorf("role not found: %w", err)
		}
		roles[i] = role
	}

	// Hash the password before storing
	hashedPassword, err := auth.HashPassword(input.Password)
	if err != nil {
		return nil, fmt.Errorf("failed to hash password: %w", err)
	}

	user := models.User{
		Email:    input.Email,
		Password: hashedPassword,
		Roles:    roles,
	}

	if err := r.DB.Create(&user).Error; err != nil {
		return nil, fmt.Errorf("failed to create user: %w", err)
	}

	logging.LogMutation(ctx, "CREATE", "USER", user.Email)
	return convertUser(user), nil
}

// UpdateUser is the resolver for the updateUser field.
func (r *mutationResolver) UpdateUser(ctx context.Context, id string, input model.UpdateUserInput) (*model.User, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "user:update") {
		return nil, errors.New("unauthorized: missing user:update permission")
	}

	userID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid user ID: %w", err)
	}

	var existing models.User
	if err := r.DB.First(&existing, userID).Error; err != nil {
		return nil, fmt.Errorf("user not found: %w", err)
	}

	if input.Email != nil {
		existing.Email = *input.Email
	}
	if input.Password != nil {
		// Hash the new password
		hashedPassword, err := auth.HashPassword(*input.Password)
		if err != nil {
			return nil, fmt.Errorf("failed to hash password: %w", err)
		}
		existing.Password = hashedPassword
	}
	if len(input.Roles) > 0 {
		roles := make([]models.Role, len(input.Roles))
		for i, roleIDStr := range input.Roles {
			roleID, err := toID(roleIDStr)
			if err != nil {
				return nil, fmt.Errorf("invalid role ID: %w", err)
			}
			var role models.Role
			if err := r.DB.First(&role, roleID).Error; err != nil {
				return nil, fmt.Errorf("role not found: %w", err)
			}
			roles[i] = role
		}
		existing.Roles = roles
	}

	if err := r.DB.Save(&existing).Error; err != nil {
		return nil, fmt.Errorf("failed to update user: %w", err)
	}

	logging.LogMutation(ctx, "UPDATE", "USER", existing.Email)
	return convertUser(existing), nil
}

// DeleteUser is the resolver for the deleteUser field.
func (r *mutationResolver) DeleteUser(ctx context.Context, id string) (bool, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return false, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "user:delete") {
		return false, errors.New("unauthorized: missing user:delete permission")
	}

	userID, err := toID(id)
	if err != nil {
		return false, fmt.Errorf("invalid user ID: %w", err)
	}

	result := r.DB.Delete(&models.User{}, userID)
	if result.Error != nil {
		return false, fmt.Errorf("failed to delete user: %w", result.Error)
	}

	logging.LogMutation(ctx, "DELETE", "USER", id)
	return result.RowsAffected > 0, nil
}

// CreateNote is the resolver for the createNote field.
func (r *mutationResolver) CreateNote(ctx context.Context, input model.NewNote) (*model.Note, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	userID, err := toID(input.UserID)
	if err != nil {
		return nil, fmt.Errorf("invalid user ID: %w", err)
	}

	serviceID, err := toID(input.ServiceID)
	if err != nil {
		return nil, fmt.Errorf("invalid service ID: %w", err)
	}

	note := models.Note{
		Title:     input.Title,
		Content:   input.Content,
		UserID:    userID,
		ServiceID: serviceID,
	}

	if err := r.DB.Create(&note).Error; err != nil {
		return nil, fmt.Errorf("failed to create note: %w", err)
	}

	logging.LogMutation(ctx, "CREATE", "NOTE", note.Title)
	return convertNote(note), nil
}

// UpdateNote is the resolver for the updateNote field.
func (r *mutationResolver) UpdateNote(ctx context.Context, id string, input model.UpdateNoteInput) (*model.Note, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "note:update") {
		return nil, errors.New("unauthorized: missing note:update permission")
	}

	noteID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid note ID: %w", err)
	}

	var existing models.Note
	if err := r.DB.First(&existing, noteID).Error; err != nil {
		return nil, fmt.Errorf("note not found: %w", err)
	}

	if input.Title != nil {
		existing.Title = *input.Title
	}
	if input.Content != nil {
		existing.Content = *input.Content
	}
	if input.UserID != nil {
		userID, err := toID(*input.UserID)
		if err != nil {
			return nil, fmt.Errorf("invalid user ID: %w", err)
		}
		existing.UserID = userID
	}
	if input.ServiceID != nil {
		serviceID, err := toID(*input.ServiceID)
		if err != nil {
			return nil, fmt.Errorf("invalid service ID: %w", err)
		}
		existing.ServiceID = serviceID
	}

	if err := r.DB.Save(&existing).Error; err != nil {
		return nil, fmt.Errorf("failed to update note: %w", err)
	}

	logging.LogMutation(ctx, "UPDATE", "NOTE", existing.Title)
	return convertNote(existing), nil
}

// DeleteNote is the resolver for the deleteNote field.
func (r *mutationResolver) DeleteNote(ctx context.Context, id string) (bool, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return false, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "note:delete") {
		return false, errors.New("unauthorized: missing note:delete permission")
	}

	noteID, err := toID(id)
	if err != nil {
		return false, fmt.Errorf("invalid note ID: %w", err)
	}

	result := r.DB.Delete(&models.Note{}, noteID)
	if result.Error != nil {
		return false, fmt.Errorf("failed to delete note: %w", result.Error)
	}

	logging.LogMutation(ctx, "DELETE", "NOTE", id)
	return result.RowsAffected > 0, nil
}

// CreateRole is the resolver for the createRole field.
func (r *mutationResolver) CreateRole(ctx context.Context, input model.NewRole) (*model.Role, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	permissions := make([]models.Permission, len(input.Permissions))
	for i, permIDStr := range input.Permissions {
		permID, err := toID(permIDStr)
		if err != nil {
			return nil, fmt.Errorf("invalid permission ID: %w", err)
		}
		var perm models.Permission
		if err := r.DB.First(&perm, permID).Error; err != nil {
			return nil, fmt.Errorf("permission not found: %w", err)
		}
		permissions[i] = perm
	}

	role := models.Role{
		Name:        input.Name,
		Description: input.Description,
		Permissions: permissions,
	}

	if err := r.DB.Create(&role).Error; err != nil {
		return nil, fmt.Errorf("failed to create role: %w", err)
	}

	logging.LogMutation(ctx, "CREATE", "ROLE", role.Name)
	return convertRole(role), nil
}

// UpdateRole is the resolver for the updateRole field.
func (r *mutationResolver) UpdateRole(ctx context.Context, id string, input model.UpdateRoleInput) (*model.Role, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "role:update") {
		return nil, errors.New("unauthorized: missing role:update permission")
	}

	roleID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid role ID: %w", err)
	}

	var existing models.Role
	if err := r.DB.First(&existing, roleID).Error; err != nil {
		return nil, fmt.Errorf("role not found: %w", err)
	}

	if input.Name != nil {
		existing.Name = *input.Name
	}
	if input.Description != nil {
		existing.Description = *input.Description
	}
	if len(input.Permissions) > 0 {
		permissions := make([]models.Permission, len(input.Permissions))
		for i, permIDStr := range input.Permissions {
			permID, err := toID(permIDStr)
			if err != nil {
				return nil, fmt.Errorf("invalid permission ID: %w", err)
			}
			var perm models.Permission
			if err := r.DB.First(&perm, permID).Error; err != nil {
				return nil, fmt.Errorf("permission not found: %w", err)
			}
			permissions[i] = perm
		}
		existing.Permissions = permissions
	}

	if err := r.DB.Save(&existing).Error; err != nil {
		return nil, fmt.Errorf("failed to update role: %w", err)
	}

	logging.LogMutation(ctx, "UPDATE", "ROLE", existing.Name)
	return convertRole(existing), nil
}

// DeleteRole is the resolver for the deleteRole field.
func (r *mutationResolver) DeleteRole(ctx context.Context, id string) (bool, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return false, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "role:delete") {
		return false, errors.New("unauthorized: missing role:delete permission")
	}

	roleID, err := toID(id)
	if err != nil {
		return false, fmt.Errorf("invalid role ID: %w", err)
	}

	result := r.DB.Delete(&models.Role{}, roleID)
	if result.Error != nil {
		return false, fmt.Errorf("failed to delete role: %w", result.Error)
	}

	logging.LogMutation(ctx, "DELETE", "ROLE", id)
	return result.RowsAffected > 0, nil
}

// CreatePermission is the resolver for the createPermission field.
func (r *mutationResolver) CreatePermission(ctx context.Context, input model.NewPermission) (*model.Permission, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	permission := models.Permission{
		Code:        input.Code,
		Description: input.Description,
	}

	if err := r.DB.Create(&permission).Error; err != nil {
		return nil, fmt.Errorf("failed to create permission: %w", err)
	}

	logging.LogMutation(ctx, "CREATE", "PERMISSION", permission.Code)
	return convertPermission(permission), nil
}

// UpdatePermission is the resolver for the updatePermission field.
func (r *mutationResolver) UpdatePermission(ctx context.Context, id string, input model.UpdatePermissionInput) (*model.Permission, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "permission:update") {
		return nil, errors.New("unauthorized: missing permission:update permission")
	}

	permID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid permission ID: %w", err)
	}

	var existing models.Permission
	if err := r.DB.First(&existing, permID).Error; err != nil {
		return nil, fmt.Errorf("permission not found: %w", err)
	}

	if input.Code != nil {
		existing.Code = *input.Code
	}
	if input.Description != nil {
		existing.Description = *input.Description
	}

	if err := r.DB.Save(&existing).Error; err != nil {
		return nil, fmt.Errorf("failed to update permission: %w", err)
	}

	logging.LogMutation(ctx, "UPDATE", "PERMISSION", existing.Code)
	return convertPermission(existing), nil
}

// DeletePermission is the resolver for the deletePermission field.
func (r *mutationResolver) DeletePermission(ctx context.Context, id string) (bool, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return false, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "permission:delete") {
		return false, errors.New("unauthorized: missing permission:delete permission")
	}

	permID, err := toID(id)
	if err != nil {
		return false, fmt.Errorf("invalid permission ID: %w", err)
	}

	result := r.DB.Delete(&models.Permission{}, permID)
	if result.Error != nil {
		return false, fmt.Errorf("failed to delete permission: %w", result.Error)
	}

	logging.LogMutation(ctx, "DELETE", "PERMISSION", id)
	return result.RowsAffected > 0, nil
}

// CreateService is the resolver for the createService field.
func (r *mutationResolver) CreateService(ctx context.Context, input model.NewService) (*model.Service, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	createdByID, err := toID(input.CreatedByID)
	if err != nil {
		return nil, fmt.Errorf("invalid created by ID: %w", err)
	}

	service := models.Service{
		Name:        input.Name,
		CreatedByID: createdByID,
	}
	if input.Description != nil {
		service.Description = *input.Description
	}

	// Add participants
	for _, participantIDStr := range input.Participants {
		participantID, err := toID(participantIDStr)
		if err != nil {
			return nil, fmt.Errorf("invalid participant ID: %w", err)
		}
		var user models.User
		if err := r.DB.First(&user, participantID).Error; err != nil {
			return nil, fmt.Errorf("participant not found: %w", err)
		}
		service.Participants = append(service.Participants, user)
	}

	if err := r.DB.Create(&service).Error; err != nil {
		return nil, fmt.Errorf("failed to create service: %w", err)
	}

	// Reload with associations
	r.DB.Preload("CreatedBy").Preload("Participants").Preload("Tasks").First(&service, service.ID)

	logging.LogMutation(ctx, "CREATE", "SERVICE", service.Name)
	return convertService(service), nil
}

// UpdateService is the resolver for the updateService field.
func (r *mutationResolver) UpdateService(ctx context.Context, id string, input model.UpdateServiceInput) (*model.Service, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "service:update") {
		return nil, errors.New("unauthorized: missing service:update permission")
	}

	serviceID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid service ID: %w", err)
	}

	var existing models.Service
	if err := r.DB.Preload("Participants").First(&existing, serviceID).Error; err != nil {
		return nil, fmt.Errorf("service not found: %w", err)
	}

	if input.Name != nil {
		existing.Name = *input.Name
	}
	if input.Description != nil {
		existing.Description = *input.Description
	}
	if len(input.Participants) > 0 {
		participants := []models.User{}
		for _, participantIDStr := range input.Participants {
			participantID, err := toID(participantIDStr)
			if err != nil {
				return nil, fmt.Errorf("invalid participant ID: %w", err)
			}
			var user models.User
			if err := r.DB.First(&user, participantID).Error; err != nil {
				return nil, fmt.Errorf("participant not found: %w", err)
			}
			participants = append(participants, user)
		}
		existing.Participants = participants
	}

	if err := r.DB.Save(&existing).Error; err != nil {
		return nil, fmt.Errorf("failed to update service: %w", err)
	}

	// Reload with associations for response
	r.DB.Preload("CreatedBy").Preload("Participants").Preload("Tasks").First(&existing, existing.ID)

	logging.LogMutation(ctx, "UPDATE", "SERVICE", existing.Name)
	return convertService(existing), nil
}

// DeleteService is the resolver for the deleteService field.
func (r *mutationResolver) DeleteService(ctx context.Context, id string) (bool, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return false, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "service:delete") {
		return false, errors.New("unauthorized: missing service:delete permission")
	}

	serviceID, err := toID(id)
	if err != nil {
		return false, fmt.Errorf("invalid service ID: %w", err)
	}

	result := r.DB.Delete(&models.Service{}, serviceID)
	if result.Error != nil {
		return false, fmt.Errorf("failed to delete service: %w", result.Error)
	}

	logging.LogMutation(ctx, "DELETE", "SERVICE", id)
	return result.RowsAffected > 0, nil
}

// CreateTask is the resolver for the createTask field.
func (r *mutationResolver) CreateTask(ctx context.Context, input model.NewTask) (*model.Task, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	createdByID, err := toID(input.CreatedByID)
	if err != nil {
		return nil, fmt.Errorf("invalid created by ID: %w", err)
	}

	task := models.Task{
		Title:       input.Title,
		Content:     input.Content,
		CreatedByID: createdByID,
		Priority:    input.Priority,
	}
	if input.AssigneeID != nil {
		assigneeID, err := toID(*input.AssigneeID)
		if err != nil {
			return nil, fmt.Errorf("invalid assignee ID: %w", err)
		}
		task.AssigneeID = &assigneeID
	}
	if input.StatusID != nil {
		statusID, err := toID(*input.StatusID)
		if err != nil {
			return nil, fmt.Errorf("invalid status ID: %w", err)
		}
		task.StatusID = statusID
	}
	if input.DueDate != nil {
		parsedTime, parseErr := time.Parse(time.RFC3339, *input.DueDate)
		if parseErr != nil {
			return nil, fmt.Errorf("invalid due date format: %w", parseErr)
		}
		task.DueDate = &parsedTime
	}

	if err := r.DB.Create(&task).Error; err != nil {
		return nil, fmt.Errorf("failed to create task: %w", err)
	}

	// Reload with associations
	r.DB.Preload("CreatedBy").Preload("Assignee").Preload("Status").First(&task, task.ID)

	// Publish task created event to assignee
	graphqlTask := convertTask(task)
	r.PublishTaskEvent(graphqlTask, task.AssigneeID, "created")

	logging.LogMutation(ctx, "CREATE", "TASK", task.Title)
	return graphqlTask, nil
}

// UpdateTask is the resolver for the updateTask field.
func (r *mutationResolver) UpdateTask(ctx context.Context, id string, input model.UpdateTaskInput) (*model.Task, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "task:update") {
		return nil, errors.New("unauthorized: missing task:update permission")
	}

	// Get current user for UpdatedBy
	currentUser, err := auth.CurrentUser(ctx)
	if err != nil {
		return nil, fmt.Errorf("failed to get current user: %w", err)
	}

	taskID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid task ID: %w", err)
	}

	var existing models.Task
	if err := r.DB.Preload("CreatedBy").Preload("Assignee").Preload("Status").First(&existing, taskID).Error; err != nil {
		return nil, fmt.Errorf("task not found: %w", err)
	}

	if input.Title != nil {
		existing.Title = *input.Title
	}
	if input.Content != nil {
		existing.Content = *input.Content
	}
	if input.AssigneeID != nil {
		if *input.AssigneeID == "" {
			existing.AssigneeID = nil
		} else {
			assigneeID, err := toID(*input.AssigneeID)
			if err != nil {
				return nil, fmt.Errorf("invalid assignee ID: %w", err)
			}
			existing.AssigneeID = &assigneeID
		}
	}
	if input.StatusID != nil {
		if *input.StatusID == "" {
			existing.StatusID = 0
		} else {
			statusID, err := toID(*input.StatusID)
			if err != nil {
				return nil, fmt.Errorf("invalid status ID: %w", err)
			}
			existing.StatusID = statusID
		}
	}
	if input.DueDate != nil {
		if *input.DueDate == "" {
			existing.DueDate = nil
		} else {
			parsedTime, parseErr := time.Parse(time.RFC3339, *input.DueDate)
			if parseErr != nil {
				return nil, fmt.Errorf("invalid due date format: %w", parseErr)
			}
			existing.DueDate = &parsedTime
		}
	}
	if input.Priority != nil {
		existing.Priority = *input.Priority
	}

	// Set UpdatedByID to current user
	existing.UpdatedByID = currentUser.ID

	if err := r.DB.Save(&existing).Error; err != nil {
		return nil, fmt.Errorf("failed to update task: %w", err)
	}

	// Reload with associations for response
	r.DB.Preload("CreatedBy").Preload("UpdatedBy").Preload("Assignee").Preload("Status").First(&existing, existing.ID)

	// Publish task updated event to assignee
	graphqlTask := convertTask(existing)
	r.PublishTaskEvent(graphqlTask, existing.AssigneeID, "updated")

	// Workflow integration: Check if task is associated with a workflow node
	// Look up the workflow node by task ID
	var workflowNode models.WorkflowNode
	if err := r.DB.Where("task_id = ?", existing.ID).First(&workflowNode).Error; err == nil && workflowNode.ID > 0 {
		// Get the workflow engine
		workflowEngine := workflow.NewEngine(r.DB)

		// Check if status changed to "done" (status code "done")
		if input.StatusID != nil && *input.StatusID != "" {
			var newStatus models.TaskStatus
			if err := r.DB.First(&newStatus, existing.StatusID).Error; err == nil && newStatus.Code == "done" {
				// Mark node as completed
				if err := workflowEngine.MarkNodeCompleted(workflowNode.ID); err != nil {
					fmt.Printf("ERROR: workflow_node_complete node_id=%d error=%v\n", workflowNode.ID, err)
				}
			} else if input.StatusID != nil && *input.StatusID != "" {
				// Check for cancelled/failed status
				if err := r.DB.First(&newStatus, existing.StatusID).Error; err == nil {
					if newStatus.Code == "cancelled" || newStatus.Code == "failed" {
						// Mark node as failed
						if err := workflowEngine.MarkNodeFailed(workflowNode.ID, fmt.Sprintf("task status changed to %s", newStatus.Code)); err != nil {
							fmt.Printf("ERROR: workflow_node_fail node_id=%d error=%v\n", workflowNode.ID, err)
						}
					}
				}
			}
		}
	}

	logging.LogMutation(ctx, "UPDATE", "TASK", existing.Title)
	return graphqlTask, nil
}

// DeleteTask is the resolver for the deleteTask field.
func (r *mutationResolver) DeleteTask(ctx context.Context, id string) (bool, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return false, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "task:delete") {
		return false, errors.New("unauthorized: missing task:delete permission")
	}

	taskID, err := toID(id)
	if err != nil {
		return false, fmt.Errorf("invalid task ID: %w", err)
	}

	result := r.DB.Delete(&models.Task{}, taskID)
	if result.Error != nil {
		return false, fmt.Errorf("failed to delete task: %w", result.Error)
	}

	logging.LogMutation(ctx, "DELETE", "TASK", id)
	return result.RowsAffected > 0, nil
}

// CreateTaskStatus is the resolver for the createTaskStatus field.
func (r *mutationResolver) CreateTaskStatus(ctx context.Context, input model.NewTaskStatus) (*model.TaskStatus, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	taskStatus := models.TaskStatus{
		Code:  input.Code,
		Label: input.Label,
	}

	if err := r.DB.Create(&taskStatus).Error; err != nil {
		return nil, fmt.Errorf("failed to create task status: %w", err)
	}

	logging.LogMutation(ctx, "CREATE", "TASKSTATUS", taskStatus.Code)
	return convertTaskStatus(taskStatus), nil
}

// UpdateTaskStatus is the resolver for the updateTaskStatus field.
func (r *mutationResolver) UpdateTaskStatus(ctx context.Context, id string, input model.UpdateTaskStatusInput) (*model.TaskStatus, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "taskstatus:update") {
		return nil, errors.New("unauthorized: missing taskstatus:update permission")
	}

	statusID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid task status ID: %w", err)
	}

	var existing models.TaskStatus
	if err := r.DB.First(&existing, statusID).Error; err != nil {
		return nil, fmt.Errorf("task status not found: %w", err)
	}

	if input.Code != nil {
		existing.Code = *input.Code
	}
	if input.Label != nil {
		existing.Label = *input.Label
	}

	if err := r.DB.Save(&existing).Error; err != nil {
		return nil, fmt.Errorf("failed to update task status: %w", err)
	}

	// Reload with tasks for response
	r.DB.Preload("Tasks").First(&existing, existing.ID)

	logging.LogMutation(ctx, "UPDATE", "TASKSTATUS", existing.Code)
	return convertTaskStatus(existing), nil
}

// DeleteTaskStatus is the resolver for the deleteTaskStatus field.
func (r *mutationResolver) DeleteTaskStatus(ctx context.Context, id string) (bool, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return false, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "taskstatus:delete") {
		return false, errors.New("unauthorized: missing taskstatus:delete permission")
	}

	statusID, err := toID(id)
	if err != nil {
		return false, fmt.Errorf("invalid task status ID: %w", err)
	}

	result := r.DB.Delete(&models.TaskStatus{}, statusID)
	if result.Error != nil {
		return false, fmt.Errorf("failed to delete task status: %w", result.Error)
	}

	logging.LogMutation(ctx, "DELETE", "TASKSTATUS", id)
	return result.RowsAffected > 0, nil
}

// CreateMessage is the resolver for the createMessage field.
func (r *mutationResolver) CreateMessage(ctx context.Context, input model.NewMessage) (*model.Message, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	// Get sender from authenticated user
	currentUser, err := auth.CurrentUser(ctx)
	if err != nil {
		return nil, fmt.Errorf("failed to get current user: %w", err)
	}

	// Build receivers list
	receivers := make([]models.User, 0, len(input.Receivers))
	receiverIDs := make([]uint, 0, len(input.Receivers))
	for _, receiverIDStr := range input.Receivers {
		receiverID, err := toID(receiverIDStr)
		if err != nil {
			return nil, fmt.Errorf("invalid receiver ID: %w", err)
		}
		var user models.User
		if err := r.DB.First(&user, receiverID).Error; err != nil {
			return nil, fmt.Errorf("receiver not found: %w", err)
		}
		receivers = append(receivers, user)
		receiverIDs = append(receiverIDs, receiverID)
	}

	message := models.Message{
		SenderID:  currentUser.ID,
		Content:   input.Content,
		Receivers: receivers,
	}

	if err := r.DB.Create(&message).Error; err != nil {
		return nil, fmt.Errorf("failed to create message: %w", err)
	}

	// Reload with associations
	r.DB.Preload("Sender").Preload("Receivers").First(&message, message.ID)

	// Publish message event to receivers (excluding the sender to prevent notification loops)
	notifyReceiverIDs := make([]uint, 0, len(receiverIDs))
	for _, receiverID := range receiverIDs {
		if receiverID != currentUser.ID {
			notifyReceiverIDs = append(notifyReceiverIDs, receiverID)
		}
	}

	graphqlMessage := convertMessage(message)
	r.PublishMessageEvent(graphqlMessage, notifyReceiverIDs)

	logging.LogMutation(ctx, "CREATE", "MESSAGE", fmt.Sprintf("id=%d content=%s", message.ID, message.Content))
	return graphqlMessage, nil
}

// UpdateMessage is the resolver for the updateMessage field.
func (r *mutationResolver) UpdateMessage(ctx context.Context, id string, input model.UpdateMessageInput) (*model.Message, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "message:update") {
		return nil, errors.New("unauthorized: missing message:update permission")
	}

	messageID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid message ID: %w", err)
	}

	var existing models.Message
	if err := r.DB.Preload("Sender").Preload("Receivers").First(&existing, messageID).Error; err != nil {
		return nil, fmt.Errorf("message not found: %w", err)
	}

	if input.Content != nil {
		existing.Content = *input.Content
	}
	if len(input.Receivers) > 0 {
		receivers := make([]models.User, 0, len(input.Receivers))
		for _, receiverIDStr := range input.Receivers {
			receiverID, err := toID(receiverIDStr)
			if err != nil {
				return nil, fmt.Errorf("invalid receiver ID: %w", err)
			}
			var user models.User
			if err := r.DB.First(&user, receiverID).Error; err != nil {
				return nil, fmt.Errorf("receiver not found: %w", err)
			}
			receivers = append(receivers, user)
		}
		existing.Receivers = receivers
	}

	if err := r.DB.Save(&existing).Error; err != nil {
		return nil, fmt.Errorf("failed to update message: %w", err)
	}

	// Reload with associations
	r.DB.Preload("Sender").Preload("Receivers").First(&existing, existing.ID)

	logging.LogMutation(ctx, "UPDATE", "MESSAGE", id)
	return convertMessage(existing), nil
}

// DeleteMessage is the resolver for the deleteMessage field.
func (r *mutationResolver) DeleteMessage(ctx context.Context, id string) (bool, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return false, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "message:delete") {
		return false, errors.New("unauthorized: missing message:delete permission")
	}

	messageID, err := toID(id)
	if err != nil {
		return false, fmt.Errorf("invalid message ID: %w", err)
	}

	result := r.DB.Delete(&models.Message{}, messageID)
	if result.Error != nil {
		return false, fmt.Errorf("failed to delete message: %w", result.Error)
	}

	logging.LogMutation(ctx, "DELETE", "MESSAGE", id)
	return result.RowsAffected > 0, nil
}

// CreateWorkflowTemplate is the resolver for the createWorkflowTemplate field.
func (r *mutationResolver) CreateWorkflowTemplate(ctx context.Context, input model.NewWorkflowTemplate) (*model.WorkflowTemplate, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "workflow:create") {
		return nil, errors.New("unauthorized: missing workflow:create permission")
	}

	currentUser, err := auth.CurrentUser(ctx)
	if err != nil {
		return nil, fmt.Errorf("failed to get current user: %w", err)
	}

	var isActive bool
	if input.IsActive != nil {
		isActive = *input.IsActive
	} else {
		isActive = true
	}

	workflowTemplate := models.WorkflowTemplate{
		Name: input.Name,
		Description: func() string {
			if input.Description != nil {
				return *input.Description
			}
			return ""
		}(),
		Definition:  input.Definition,
		IsActive:    isActive,
		CreatedByID: currentUser.ID,
	}

	if err := r.DB.Create(&workflowTemplate).Error; err != nil {
		return nil, fmt.Errorf("failed to create workflow template: %w", err)
	}

	// Reload with associations
	r.DB.Preload("CreatedBy").First(&workflowTemplate, workflowTemplate.ID)

	logging.LogMutation(ctx, "CREATE", "WORKFLOW_TEMPLATE", workflowTemplate.Name)
	return convertWorkflowTemplate(workflowTemplate), nil
}

// UpdateWorkflowTemplate is the resolver for the updateWorkflowTemplate field.
func (r *mutationResolver) UpdateWorkflowTemplate(ctx context.Context, id string, input model.UpdateWorkflowTemplateInput) (*model.WorkflowTemplate, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "workflow:manage") {
		return nil, errors.New("unauthorized: missing workflow:manage permission")
	}

	templateID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid workflow template ID: %w", err)
	}

	var existing models.WorkflowTemplate
	if err := r.DB.First(&existing, templateID).Error; err != nil {
		return nil, fmt.Errorf("workflow template not found: %w", err)
	}

	if input.Name != nil {
		existing.Name = *input.Name
	}
	if input.Description != nil {
		existing.Description = *input.Description
	}
	if input.Definition != nil {
		existing.Definition = *input.Definition
	}
	if input.IsActive != nil {
		existing.IsActive = *input.IsActive
	}

	if err := r.DB.Save(&existing).Error; err != nil {
		return nil, fmt.Errorf("failed to update workflow template: %w", err)
	}

	// Reload with associations for response
	r.DB.Preload("CreatedBy").First(&existing, existing.ID)

	logging.LogMutation(ctx, "UPDATE", "WORKFLOW_TEMPLATE", existing.Name)
	return convertWorkflowTemplate(existing), nil
}

// DeleteWorkflowTemplate is the resolver for the deleteWorkflowTemplate field.
func (r *mutationResolver) DeleteWorkflowTemplate(ctx context.Context, id string) (bool, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return false, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "workflow:manage") {
		return false, errors.New("unauthorized: missing workflow:manage permission")
	}

	templateID, err := toID(id)
	if err != nil {
		return false, fmt.Errorf("invalid workflow template ID: %w", err)
	}

	result := r.DB.Delete(&models.WorkflowTemplate{}, templateID)
	if result.Error != nil {
		return false, fmt.Errorf("failed to delete workflow template: %w", result.Error)
	}

	logging.LogMutation(ctx, "DELETE", "WORKFLOW_TEMPLATE", id)
	return result.RowsAffected > 0, nil
}

// StartWorkflow is the resolver for the startWorkflow field.
func (r *mutationResolver) StartWorkflow(ctx context.Context, templateID string, input model.StartWorkflowInput) (*model.WorkflowInstance, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "workflow:start") {
		return nil, errors.New("unauthorized: missing workflow:start permission")
	}

	templateIDUint, err := toID(templateID)
	if err != nil {
		return nil, fmt.Errorf("invalid workflow template ID: %w", err)
	}

	var template models.WorkflowTemplate
	if err := r.DB.First(&template, templateIDUint).Error; err != nil {
		return nil, fmt.Errorf("workflow template not found: %w", err)
	}

	// Parse the workflow definition (JSON DAG)
	workflowEngine := workflow.NewEngine(r.DB)
	instance, nodes, err := workflowEngine.CreateInstance(template, workflow.StartWorkflowInput{
		ServiceID: func() *uint {
			if input.ServiceID != nil {
				id, _ := toID(*input.ServiceID)
				return &id
			}
			return nil
		}(),
		Context: func() string {
			if input.Context != nil {
				return *input.Context
			}
			return ""
		}(),
	})
	if err != nil {
		return nil, fmt.Errorf("failed to create workflow instance: %w", err)
	}

	// Save the workflow instance
	if err := r.DB.Create(&instance).Error; err != nil {
		return nil, fmt.Errorf("failed to save workflow instance: %w", err)
	}

	// Save the workflow nodes
	for i := range nodes {
		nodes[i].WorkflowInstanceID = instance.ID
		if err := r.DB.Create(&nodes[i]).Error; err != nil {
			return nil, fmt.Errorf("failed to save workflow node: %w", err)
		}
	}

	// Reload with associations
	r.DB.Preload("WorkflowTemplate").Preload("Service").First(&instance, instance.ID)

	logging.LogMutation(ctx, "START_WORKFLOW", "WORKFLOW_INSTANCE", fmt.Sprintf("template=%s", template.Name))
	return convertWorkflowInstance(instance), nil
}

// CancelWorkflow is the resolver for the cancelWorkflow field.
func (r *mutationResolver) CancelWorkflow(ctx context.Context, id string) (*model.WorkflowInstance, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "workflow:manage") {
		return nil, errors.New("unauthorized: missing workflow:manage permission")
	}

	instanceID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid workflow instance ID: %w", err)
	}

	var instance models.WorkflowInstance
	if err := r.DB.First(&instance, instanceID).Error; err != nil {
		return nil, fmt.Errorf("workflow instance not found: %w", err)
	}

	instance.Status = "failed"
	now := time.Now()
	instance.CompletedAt = &now

	if err := r.DB.Save(&instance).Error; err != nil {
		return nil, fmt.Errorf("failed to cancel workflow: %w", err)
	}

	// Update all running nodes to failed
	r.DB.Model(&models.WorkflowNode{}).
		Where("workflow_instance_id = ? AND status = ?", instanceID, "running").
		Update("status", "failed")

	// Reload with associations for response
	r.DB.Preload("WorkflowTemplate").Preload("Service").First(&instance, instance.ID)

	logging.LogMutation(ctx, "CANCEL_WORKFLOW", "WORKFLOW_INSTANCE", id)
	return convertWorkflowInstance(instance), nil
}

// RetryWorkflowNode is the resolver for the retryWorkflowNode field.
func (r *mutationResolver) RetryWorkflowNode(ctx context.Context, nodeID string) (*model.WorkflowNode, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "workflow:intervene") {
		return nil, errors.New("unauthorized: missing workflow:intervene permission")
	}

	nodeIDUint, err := toID(nodeID)
	if err != nil {
		return nil, fmt.Errorf("invalid workflow node ID: %w", err)
	}

	var node models.WorkflowNode
	if err := r.DB.Preload("WorkflowInstance").First(&node, nodeIDUint).Error; err != nil {
		return nil, fmt.Errorf("workflow node not found: %w", err)
	}

	// Reset node status to pending and clear task association
	node.Status = "pending"
	node.TaskID = nil
	node.RetryCount++
	node.OutputData = ""

	if err := r.DB.Save(&node).Error; err != nil {
		return nil, fmt.Errorf("failed to retry workflow node: %w", err)
	}

	// Reload with task for response
	r.DB.Preload("Task").First(&node, node.ID)

	logging.LogMutation(ctx, "RETRY_NODE", "WORKFLOW_NODE", nodeID)
	return convertWorkflowNode(node), nil
}

// Users is the resolver for the users field.
func (r *queryResolver) Users(ctx context.Context) ([]*model.User, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	var users []models.User
	if err := r.DB.Preload("Roles").Find(&users).Error; err != nil {
		return nil, fmt.Errorf("failed to fetch users: %w", err)
	}
	logging.LogQuery(ctx, "USERS", "all")
	return convertUsers(users), nil
}

// User is the resolver for the user field.
func (r *queryResolver) User(ctx context.Context, id string) (*model.User, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	userID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid user ID: %w", err)
	}

	var user models.User
	if err := r.DB.Preload("Roles.Permissions").First(&user, userID).Error; err != nil {
		return nil, fmt.Errorf("user not found: %w", err)
	}

	logging.LogQuery(ctx, "USER", id)
	return convertUser(user), nil
}

// Notes is the resolver for the notes field.
func (r *queryResolver) Notes(ctx context.Context) ([]*model.Note, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	var notes []models.Note
	if err := r.DB.Preload("User").Preload("Service").Find(&notes).Error; err != nil {
		return nil, fmt.Errorf("failed to fetch notes: %w", err)
	}
	logging.LogQuery(ctx, "NOTES", "all")
	return convertNotes(notes), nil
}

// Note is the resolver for the note field.
func (r *queryResolver) Note(ctx context.Context, id string) (*model.Note, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	noteID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid note ID: %w", err)
	}

	var note models.Note
	if err := r.DB.Preload("User").Preload("Service").First(&note, noteID).Error; err != nil {
		return nil, fmt.Errorf("note not found: %w", err)
	}

	logging.LogQuery(ctx, "NOTE", id)
	return convertNote(note), nil
}

// Roles is the resolver for the roles field.
func (r *queryResolver) Roles(ctx context.Context) ([]*model.Role, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	var roles []models.Role
	if err := r.DB.Preload("Permissions").Find(&roles).Error; err != nil {
		return nil, fmt.Errorf("failed to fetch roles: %w", err)
	}
	logging.LogQuery(ctx, "ROLES", "all")
	return convertRoles(roles), nil
}

// Role is the resolver for the role field.
func (r *queryResolver) Role(ctx context.Context, id string) (*model.Role, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	roleID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid role ID: %w", err)
	}

	var role models.Role
	if err := r.DB.Preload("Permissions").First(&role, roleID).Error; err != nil {
		return nil, fmt.Errorf("role not found: %w", err)
	}

	logging.LogQuery(ctx, "ROLE", id)
	return convertRole(role), nil
}

// Permissions is the resolver for the permissions field.
func (r *queryResolver) Permissions(ctx context.Context) ([]*model.Permission, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	var perms []models.Permission
	if err := r.DB.Find(&perms).Error; err != nil {
		return nil, fmt.Errorf("failed to fetch permissions: %w", err)
	}
	logging.LogQuery(ctx, "PERMISSIONS", "all")
	return convertPermissions(perms), nil
}

// Permission is the resolver for the permission field.
func (r *queryResolver) Permission(ctx context.Context, id string) (*model.Permission, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	permID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid permission ID: %w", err)
	}

	var perm models.Permission
	if err := r.DB.First(&perm, permID).Error; err != nil {
		return nil, fmt.Errorf("permission not found: %w", err)
	}

	logging.LogQuery(ctx, "PERMISSION", id)
	return convertPermission(perm), nil
}

// Services is the resolver for the services field.
func (r *queryResolver) Services(ctx context.Context) ([]*model.Service, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	var services []models.Service
	if err := r.DB.Preload("CreatedBy").Preload("Participants").Preload("Tasks").Find(&services).Error; err != nil {
		return nil, fmt.Errorf("failed to fetch services: %w", err)
	}
	logging.LogQuery(ctx, "SERVICES", "all")
	return convertServices(services), nil
}

// Service is the resolver for the service field.
func (r *queryResolver) Service(ctx context.Context, id string) (*model.Service, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	serviceID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid service ID: %w", err)
	}

	var service models.Service
	if err := r.DB.Preload("CreatedBy").Preload("Participants").Preload("Tasks").First(&service, serviceID).Error; err != nil {
		return nil, fmt.Errorf("service not found: %w", err)
	}

	logging.LogQuery(ctx, "SERVICE", id)
	return convertService(service), nil
}

// Tasks is the resolver for the tasks field.
func (r *queryResolver) Tasks(ctx context.Context) ([]*model.Task, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	var tasks []models.Task
	if err := r.DB.Preload("CreatedBy").Preload("UpdatedBy").Preload("Assignee").Preload("Status").Find(&tasks).Error; err != nil {
		return nil, fmt.Errorf("failed to fetch tasks: %w", err)
	}
	logging.LogQuery(ctx, "TASKS", "all")
	return convertTasks(tasks), nil
}

// Task is the resolver for the task field.
func (r *queryResolver) Task(ctx context.Context, id string) (*model.Task, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	taskID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid task ID: %w", err)
	}

	var task models.Task
	if err := r.DB.Preload("CreatedBy").Preload("UpdatedBy").Preload("Assignee").Preload("Status").First(&task, taskID).Error; err != nil {
		return nil, fmt.Errorf("task not found: %w", err)
	}

	logging.LogQuery(ctx, "TASK", id)
	return convertTask(task), nil
}

// TaskStatuses is the resolver for the taskStatuses field.
func (r *queryResolver) TaskStatuses(ctx context.Context) ([]*model.TaskStatus, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	var statuses []models.TaskStatus
	if err := r.DB.Preload("Tasks").Find(&statuses).Error; err != nil {
		return nil, fmt.Errorf("failed to fetch task statuses: %w", err)
	}
	logging.LogQuery(ctx, "TASKSTATUSES", "all")
	return convertTaskStatuses(statuses), nil
}

// TaskStatus
func (r *queryResolver) TaskStatus(ctx context.Context, id string) (*model.TaskStatus, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	statusID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid task status ID: %w", err)
	}

	var status models.TaskStatus
	if err := r.DB.Preload("Tasks").First(&status, statusID).Error; err != nil {
		return nil, fmt.Errorf("task status not found: %w", err)
	}

	logging.LogQuery(ctx, "TASKSTATUS", id)
	return convertTaskStatus(status), nil
}

// Messages is the resolver for the messages field.
func (r *queryResolver) Messages(ctx context.Context) ([]*model.Message, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	var messages []models.Message
	if err := r.DB.Preload("Sender").Preload("Receivers").Find(&messages).Error; err != nil {
		return nil, fmt.Errorf("failed to fetch messages: %w", err)
	}
	logging.LogQuery(ctx, "MESSAGES", "all")
	return convertMessages(messages), nil
}

// Message is the resolver for the message field.
func (r *queryResolver) Message(ctx context.Context, id string) (*model.Message, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}

	messageID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid message ID: %w", err)
	}

	var message models.Message
	if err := r.DB.Preload("Sender").Preload("Receivers").First(&message, messageID).Error; err != nil {
		return nil, fmt.Errorf("message not found: %w", err)
	}

	logging.LogQuery(ctx, "MESSAGE", id)
	return convertMessage(message), nil
}

// WorkflowTemplates is the resolver for the workflowTemplates field.
func (r *queryResolver) WorkflowTemplates(ctx context.Context) ([]*model.WorkflowTemplate, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "workflow:view") {
		return nil, errors.New("unauthorized: missing workflow:view permission")
	}

	var templates []models.WorkflowTemplate
	if err := r.DB.Preload("CreatedBy").Find(&templates).Error; err != nil {
		return nil, fmt.Errorf("failed to fetch workflow templates: %w", err)
	}
	logging.LogQuery(ctx, "WORKFLOW_TEMPLATES", "all")
	return convertWorkflowTemplates(templates), nil
}

// WorkflowTemplate is the resolver for the workflowTemplate field.
func (r *queryResolver) WorkflowTemplate(ctx context.Context, id string) (*model.WorkflowTemplate, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "workflow:view") {
		return nil, errors.New("unauthorized: missing workflow:view permission")
	}

	templateID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid workflow template ID: %w", err)
	}

	var template models.WorkflowTemplate
	if err := r.DB.Preload("CreatedBy").First(&template, templateID).Error; err != nil {
		return nil, fmt.Errorf("workflow template not found: %w", err)
	}

	logging.LogQuery(ctx, "WORKFLOW_TEMPLATE", id)
	return convertWorkflowTemplate(template), nil
}

// WorkflowInstances is the resolver for the workflowInstances field.
func (r *queryResolver) WorkflowInstances(ctx context.Context) ([]*model.WorkflowInstance, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "workflow:view") {
		return nil, errors.New("unauthorized: missing workflow:view permission")
	}

	var instances []models.WorkflowInstance
	if err := r.DB.Preload("WorkflowTemplate").Preload("Service").Find(&instances).Error; err != nil {
		return nil, fmt.Errorf("failed to fetch workflow instances: %w", err)
	}
	logging.LogQuery(ctx, "WORKFLOW_INSTANCES", "all")
	return convertWorkflowInstances(instances), nil
}

// WorkflowInstance is the resolver for the workflowInstance field.
func (r *queryResolver) WorkflowInstance(ctx context.Context, id string) (*model.WorkflowInstance, error) {
	// Auth check
	if !auth.IsAuthenticated(ctx) {
		return nil, errors.New("unauthorized: authentication required")
	}
	if !auth.HasPermission(ctx, "workflow:view") {
		return nil, errors.New("unauthorized: missing workflow:view permission")
	}

	instanceID, err := toID(id)
	if err != nil {
		return nil, fmt.Errorf("invalid workflow instance ID: %w", err)
	}

	var instance models.WorkflowInstance
	if err := r.DB.Preload("WorkflowTemplate").Preload("Service").First(&instance, instanceID).Error; err != nil {
		return nil, fmt.Errorf("workflow instance not found: %w", err)
	}

	logging.LogQuery(ctx, "WORKFLOW_INSTANCE", id)
	return convertWorkflowInstance(instance), nil
}

// TaskCreated is the resolver for the taskCreated field.
// Users only receive events for tasks where they are the assignee.
func (r *subscriptionResolver) TaskCreated(ctx context.Context) (<-chan *model.Task, error) {
	// Get current user
	user, err := auth.CurrentUser(ctx)
	if err != nil {
		return nil, errors.New("unauthorized: authentication required")
	}

	// Subscribe to task events
	eventChan := r.SubscribeToTasks(user.ID)

	// Create output channel
	outputChan := make(chan *model.Task, 10)

	// Start goroutine to filter and forward events
	go func() {
		defer close(outputChan)

		for {
			select {
			case <-ctx.Done():
				return
			case event, ok := <-eventChan:
				if !ok {
					return
				}
				// Only forward "created" events
				if event.EventType == "created" && event.Task != nil {
					select {
					case outputChan <- event.Task:
					default:
						// Channel full, skip
					}
				}
			}
		}
	}()

	return outputChan, nil
}

// TaskUpdated is the resolver for the taskUpdated field.
// Users only receive events for tasks where they are the assignee.
func (r *subscriptionResolver) TaskUpdated(ctx context.Context) (<-chan *model.Task, error) {
	// Get current user
	user, err := auth.CurrentUser(ctx)
	if err != nil {
		return nil, errors.New("unauthorized: authentication required")
	}

	// Subscribe to task events
	eventChan := r.SubscribeToTasks(user.ID)

	// Create output channel
	outputChan := make(chan *model.Task, 10)

	// Start goroutine to filter and forward events
	go func() {
		defer close(outputChan)

		for {
			select {
			case <-ctx.Done():
				return
			case event, ok := <-eventChan:
				if !ok {
					return
				}
				// Only forward "updated" events
				if event.EventType == "updated" && event.Task != nil {
					select {
					case outputChan <- event.Task:
					default:
						// Channel full, skip
					}
				}
			}
		}
	}()

	return outputChan, nil
}

// TaskDeleted is the resolver for the taskDeleted field.
// Users only receive events for tasks where they are the assignee.
func (r *subscriptionResolver) TaskDeleted(ctx context.Context) (<-chan *model.Task, error) {
	// Get current user
	user, err := auth.CurrentUser(ctx)
	if err != nil {
		return nil, errors.New("unauthorized: authentication required")
	}

	// Subscribe to task events
	eventChan := r.SubscribeToTasks(user.ID)

	// Create output channel
	outputChan := make(chan *model.Task, 10)

	// Start goroutine to filter and forward events
	go func() {
		defer close(outputChan)

		for {
			select {
			case <-ctx.Done():
				return
			case event, ok := <-eventChan:
				if !ok {
					return
				}
				// Only forward "deleted" events
				if event.EventType == "deleted" && event.Task != nil {
					select {
					case outputChan <- event.Task:
					default:
						// Channel full, skip
					}
				}
			}
		}
	}()

	return outputChan, nil
}

// MessageAdded is the resolver for the messageAdded field.
// Users only receive events for messages where they are in the receivers list.
func (r *subscriptionResolver) MessageAdded(ctx context.Context) (<-chan *model.Message, error) {
	// Get current user
	user, err := auth.CurrentUser(ctx)
	if err != nil {
		return nil, errors.New("unauthorized: authentication required")
	}

	// Subscribe to message events
	eventChan := r.SubscribeToMessages(user.ID)

	// Create output channel
	outputChan := make(chan *model.Message, 10)

	// Start goroutine to filter and forward events
	go func() {
		defer close(outputChan)

		for {
			select {
			case <-ctx.Done():
				return
			case event, ok := <-eventChan:
				if !ok {
					return
				}
				// Check if user is in the receiver list
				isReceiver := false
				for _, receiverID := range event.ReceiverIDs {
					if receiverID == user.ID {
						isReceiver = true
						break
					}
				}
				if isReceiver && event.Message != nil {
					select {
					case outputChan <- event.Message:
					default:
						// Channel full, skip
					}
				}
			}
		}
	}()

	return outputChan, nil
}

// Mutation returns MutationResolver implementation.
func (r *Resolver) Mutation() MutationResolver { return &mutationResolver{r} }

// Query returns QueryResolver implementation.
func (r *Resolver) Query() QueryResolver { return &queryResolver{r} }

// Subscription returns SubscriptionResolver implementation.
func (r *Resolver) Subscription() SubscriptionResolver { return &subscriptionResolver{r} }

type mutationResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }
type subscriptionResolver struct{ *Resolver }
