package service

import (
	"encoding/json"
	"errors"
	"fmt"
	"netidhub-saas-be/app/database/entity"
	approvalWorkflowStepsRepo "netidhub-saas-be/app/module/approval_workflow_steps/repository"
	approvalWorkflowsRepo "netidhub-saas-be/app/module/approval_workflows/repository"
	"netidhub-saas-be/app/module/article_approval_flows/repository"
	"netidhub-saas-be/app/module/article_approval_flows/request"
	approvalStepLogsRepo "netidhub-saas-be/app/module/article_approval_step_logs/repository"
	articlesRepo "netidhub-saas-be/app/module/articles/repository"
	usersRepo "netidhub-saas-be/app/module/users/repository"
	"netidhub-saas-be/utils/paginator"
	utilSvc "netidhub-saas-be/utils/service"
	"time"

	"github.com/google/uuid"
	"github.com/rs/zerolog"
)

type articleApprovalFlowsService struct {
	ArticleApprovalFlowsRepository    repository.ArticleApprovalFlowsRepository
	ApprovalWorkflowsRepository       approvalWorkflowsRepo.ApprovalWorkflowsRepository
	ApprovalWorkflowStepsRepository   approvalWorkflowStepsRepo.ApprovalWorkflowStepsRepository
	ArticleApprovalStepLogsRepository approvalStepLogsRepo.ArticleApprovalStepLogsRepository
	ArticlesRepository                articlesRepo.ArticlesRepository
	UsersRepository                   usersRepo.UsersRepository
	Log                               zerolog.Logger
}

// ArticleApprovalFlowsService define interface of IArticleApprovalFlowsService
type ArticleApprovalFlowsService interface {
	// Basic CRUD
	GetAll(authToken string, req request.ArticleApprovalFlowsQueryRequest) (flows []*entity.ArticleApprovalFlows, paging paginator.Pagination, err error)
	FindOne(authToken string, id uint) (flow *entity.ArticleApprovalFlows, err error)
	Create(authToken string, flow *entity.ArticleApprovalFlows) (flowReturn *entity.ArticleApprovalFlows, err error)
	Update(id uint, flow *entity.ArticleApprovalFlows) (err error)
	Delete(authToken string, id uint) (err error)

	// Article submission and approval workflow
	SubmitArticleForApproval(authToken string, articleId uint, submittedById uint, workflowId *uint) (flow *entity.ArticleApprovalFlows, err error)
	ApproveStep(authToken string, flowId uint, approvedById uint, message string) (err error)
	ResubmitAfterRevision(authToken string, flowId uint, resubmittedById uint) (err error)

	// Dashboard and queue methods
	GetPendingApprovals(authToken string, userLevelId uint, page, limit int, filters map[string]interface{}) (flows []*entity.ArticleApprovalFlows, paging paginator.Pagination, err error)
	GetMyApprovalQueue(authToken string, userLevelId uint, page, limit int, includePreview bool, urgentOnly bool) (flows []*entity.ArticleApprovalFlows, paging paginator.Pagination, err error)
	GetApprovalHistory(authToken string, articleId uint, page, limit int) (logs []*entity.ArticleApprovalStepLogs, paging paginator.Pagination, err error)

	// Statistics and analytics
	GetPendingCountByLevel(authToken string, userLevelId uint) (count int64, err error)
	GetOverdueCountByLevel(authToken string, userLevelId uint) (count int64, err error)
	GetApprovalStatistics(authToken string, userLevelId uint, startDate, endDate time.Time) (stats map[string]interface{}, err error)
	GetWorkloadAnalytics(authToken string, userLevelId uint) (analytics map[string]interface{}, err error)

	// Workflow management
	CanUserApproveStep(authToken string, flowId uint, userId uint, userLevelId uint) (canApprove bool, reason string, err error)
	GetCurrentStepInfo(authToken string, flowId uint) (stepInfo map[string]interface{}, err error)
	GetNextStepPreview(authToken string, flowId uint) (nextStep *entity.ApprovalWorkflowSteps, err error)

	// Multi-branch support methods
	ProcessMultiBranchApproval(authToken string, flowId uint, approvedById uint, message string) (err error)
	ProcessApprovalAction(authToken string, flowId uint, action string, actionById uint, message string) (err error)
	FindNextStepsForBranch(authToken string, workflowId uint, currentStep int, submitterLevelId uint) (steps []*entity.ApprovalWorkflowSteps, err error)
	IsStepApplicableForLevel(step *entity.ApprovalWorkflowSteps, submitterLevelId uint) (isApplicable bool, err error)
	ProcessParallelBranches(authToken string, flow *entity.ArticleApprovalFlows, nextSteps []*entity.ApprovalWorkflowSteps, approvedById uint, message string) (err error)
	GetUserLevelId(authToken string, userId uint) (userLevelId uint, err error)
	FindActiveByArticleId(articleId uint) (flow *entity.ArticleApprovalFlows, err error)
}

func NewArticleApprovalFlowsService(
	articleApprovalFlowsRepository repository.ArticleApprovalFlowsRepository,
	approvalWorkflowsRepository approvalWorkflowsRepo.ApprovalWorkflowsRepository,
	approvalWorkflowStepsRepository approvalWorkflowStepsRepo.ApprovalWorkflowStepsRepository,
	articleApprovalStepLogsRepository approvalStepLogsRepo.ArticleApprovalStepLogsRepository,
	articlesRepository articlesRepo.ArticlesRepository,
	usersRepository usersRepo.UsersRepository,
	log zerolog.Logger,
) ArticleApprovalFlowsService {
	return &articleApprovalFlowsService{
		ArticleApprovalFlowsRepository:    articleApprovalFlowsRepository,
		ApprovalWorkflowsRepository:       approvalWorkflowsRepository,
		ApprovalWorkflowStepsRepository:   approvalWorkflowStepsRepository,
		ArticleApprovalStepLogsRepository: articleApprovalStepLogsRepository,
		ArticlesRepository:                articlesRepository,
		UsersRepository:                   usersRepository,
		Log:                               log,
	}
}

// Basic CRUD implementations
func (_i *articleApprovalFlowsService) GetAll(authToken string, req request.ArticleApprovalFlowsQueryRequest) (flows []*entity.ArticleApprovalFlows, paging paginator.Pagination, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return nil, paginator.Pagination{}, errors.New("clientId not found in auth token")
	}

	return _i.ArticleApprovalFlowsRepository.GetAll(clientId, req)
}
func (_i *articleApprovalFlowsService) FindOne(authToken string, id uint) (flow *entity.ArticleApprovalFlows, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return nil, errors.New("clientId not found in auth token")
	}

	return _i.ArticleApprovalFlowsRepository.FindOne(clientId, id)
}

func (_i *articleApprovalFlowsService) Create(authToken string, flow *entity.ArticleApprovalFlows) (flowReturn *entity.ArticleApprovalFlows, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return nil, errors.New("clientId not found in auth token")
	}

	return _i.ArticleApprovalFlowsRepository.Create(clientId, flow)
}

func (_i *articleApprovalFlowsService) Update(id uint, flow *entity.ArticleApprovalFlows) (err error) {
	return _i.ArticleApprovalFlowsRepository.Update(id, flow)
}

func (_i *articleApprovalFlowsService) Delete(authToken string, id uint) (err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return errors.New("clientId not found in auth token")
	}

	return _i.ArticleApprovalFlowsRepository.Delete(clientId, id)
}

// Article submission and approval workflow
func (_i *articleApprovalFlowsService) SubmitArticleForApproval(authToken string, articleId uint, submittedById uint, workflowId *uint) (flow *entity.ArticleApprovalFlows, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return nil, errors.New("clientId not found in auth token")
	}

	// Check if article already has an active approval flow
	existingFlow, err := _i.ArticleApprovalFlowsRepository.FindActiveByArticleId(articleId)
	if err == nil && existingFlow != nil {
		return nil, errors.New("article already has an active approval flow")
	}

	// Get workflow (use default if not specified)
	var workflow *entity.ApprovalWorkflows
	if workflowId != nil {
		workflow, err = _i.ApprovalWorkflowsRepository.FindOne(clientId, *workflowId)
	} else {
		workflow, err = _i.ApprovalWorkflowsRepository.FindDefault(clientId)
	}

	if err != nil {
		return nil, err
	}

	if workflow == nil {
		return nil, errors.New("no workflow found")
	}

	if workflow.IsActive != nil && !*workflow.IsActive {
		return nil, errors.New("workflow is not active")
	}

	// Get first step of workflow
	firstStep, err := _i.ApprovalWorkflowStepsRepository.FindByWorkflowAndStep(clientId, workflow.ID, 1)
	if err != nil {
		return nil, err
	}

	if firstStep == nil {
		return nil, errors.New("workflow has no steps")
	}

	// Create approval flow
	flow = &entity.ArticleApprovalFlows{
		ArticleId:     articleId,
		WorkflowId:    workflow.ID,
		CurrentStep:   1,
		StatusId:      1, // pending
		SubmittedById: submittedById,
		SubmittedAt:   time.Now(),
	}

	flow, err = _i.ArticleApprovalFlowsRepository.Create(clientId, flow)
	if err != nil {
		return nil, err
	}

	// Get current article data first
	currentArticle, err := _i.ArticlesRepository.FindOne(clientId, articleId)
	if err != nil {
		return nil, err
	}

	// Update only the necessary fields
	currentArticle.WorkflowId = &workflow.ID
	currentArticle.CurrentApprovalStep = &flow.CurrentStep
	currentArticle.StatusId = &[]int{1}[0] // pending approval

	err = _i.ArticlesRepository.UpdateSkipNull(clientId, articleId, currentArticle)
	if err != nil {
		return nil, err
	}

	// Process auto-skip logic based on user level
	err = _i.processAutoSkipSteps(authToken, flow, submittedById)
	if err != nil {
		return nil, err
	}

	return flow, nil
}

// processAutoSkipSteps handles automatic step skipping based on user level
func (_i *articleApprovalFlowsService) processAutoSkipSteps(authToken string, flow *entity.ArticleApprovalFlows, submittedById uint) error {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return errors.New("clientId not found in auth token")
	}

	// Get user level of the submitter
	userLevelId, err := _i.getUserLevelId(authToken, submittedById)
	if err != nil {
		return err
	}

	// Get all workflow steps
	steps, err := _i.ApprovalWorkflowStepsRepository.GetByWorkflowId(clientId, flow.WorkflowId)
	if err != nil {
		return err
	}

	// Sort steps by step order
	sortStepsByOrder(steps)

	// Process each step to determine if it should be auto-skipped
	for _, step := range steps {
		shouldSkip := _i.shouldSkipStep(userLevelId, step.RequiredUserLevelId)

		if shouldSkip {
			// Create skip log
			stepLog := &entity.ArticleApprovalStepLogs{
				ApprovalFlowId: flow.ID,
				StepOrder:      step.StepOrder,
				StepName:       step.StepName,
				ApprovedById:   &submittedById,
				Action:         "auto_skip",
				Message:        &[]string{"Step auto-skipped due to user level"}[0],
				ProcessedAt:    time.Now(),
				UserLevelId:    step.RequiredUserLevelId,
			}

			_, err = _i.ArticleApprovalStepLogsRepository.Create(clientId, stepLog)
			if err != nil {
				return err
			}

			// Update flow to next step (handle step order starting from 0)
			nextStepOrder := step.StepOrder + 1
			flow.CurrentStep = nextStepOrder
		} else {
			// Stop at first step that cannot be skipped
			break
		}
	}

	// Update flow with final current step
	err = _i.ArticleApprovalFlowsRepository.Update(flow.ID, flow)
	if err != nil {
		return err
	}

	// Get current article data first
	currentArticle, err := _i.ArticlesRepository.FindOne(clientId, flow.ArticleId)
	if err != nil {
		return err
	}

	// Update only the necessary fields
	currentArticle.CurrentApprovalStep = &flow.CurrentStep

	err = _i.ArticlesRepository.UpdateSkipNull(clientId, flow.ArticleId, currentArticle)
	if err != nil {
		return err
	}

	// Check if all steps were skipped (workflow complete)
	// Find the highest step order
	maxStepOrder := 0
	for _, step := range steps {
		if step.StepOrder > maxStepOrder {
			maxStepOrder = step.StepOrder
		}
	}

	if flow.CurrentStep > maxStepOrder {
		// All steps completed, mark as approved
		flow.StatusId = 2    // approved
		flow.CurrentStep = 0 // Set to 0 to indicate completion
		flow.CompletedAt = &[]time.Time{time.Now()}[0]

		err = _i.ArticleApprovalFlowsRepository.Update(flow.ID, flow)
		if err != nil {
			return err
		}

		// Get current article data first
		currentArticle, err := _i.ArticlesRepository.FindOne(clientId, flow.ArticleId)
		if err != nil {
			return err
		}

		// Update only the necessary fields
		currentArticle.StatusId = &[]int{2}[0]            // approved
		currentArticle.CurrentApprovalStep = &[]int{0}[0] // Set to 0 to indicate completion

		err = _i.ArticlesRepository.UpdateSkipNull(clientId, flow.ArticleId, currentArticle)
		if err != nil {
			return err
		}
	}

	return nil
}

// getUserLevelId gets the user level ID for a given user
func (_i *articleApprovalFlowsService) getUserLevelId(authToken string, userId uint) (uint, error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return 0, errors.New("clientId not found in auth token")
	}

	// Get user from database to retrieve user level
	user, err := _i.UsersRepository.FindOne(clientId, userId)
	if err != nil {
		_i.Log.Error().Err(err).Uint("userId", userId).Msg("Failed to find user")
		return 0, err
	}

	if user.UserLevel == nil {
		_i.Log.Error().Uint("userId", userId).Msg("User has no user level")
		return 0, errors.New("user has no user level")
	}

	_i.Log.Info().
		Uint("userId", userId).
		Uint("userLevelId", user.UserLevel.ID).
		Str("userLevelName", user.UserLevel.Name).
		Msg("Retrieved user level from database")

	return user.UserLevel.ID, nil
}

// shouldSkipStep determines if a step should be auto-skipped based on user level
func (_i *articleApprovalFlowsService) shouldSkipStep(userLevelId, requiredLevelId uint) bool {
	// Get user level details to compare level numbers
	// User level with lower level_number (higher authority) can skip steps requiring higher level_number
	// For now, we'll use a simple comparison based on IDs
	// In production, this should compare level_number fields

	// Simple logic: if user level ID is less than required level ID, they can skip
	// This assumes level 1 (ID=1) has higher authority than level 2 (ID=2), etc.
	return userLevelId < requiredLevelId
}

// sortStepsByOrder sorts workflow steps by their step order
func sortStepsByOrder(steps []*entity.ApprovalWorkflowSteps) {
	// Simple bubble sort for step order
	n := len(steps)
	for i := 0; i < n-1; i++ {
		for j := 0; j < n-i-1; j++ {
			if steps[j].StepOrder > steps[j+1].StepOrder {
				steps[j], steps[j+1] = steps[j+1], steps[j]
			}
		}
	}
}

func (_i *articleApprovalFlowsService) ApproveStep(authToken string, flowId uint, approvedById uint, message string) (err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return errors.New("clientId not found in auth token")
	}

	// Get approval flow
	flow, err := _i.ArticleApprovalFlowsRepository.FindOne(clientId, flowId)
	if err != nil {
		return err
	}

	if flow == nil {
		return errors.New("approval flow not found")
	}

	if flow.StatusId != 1 && flow.StatusId != 4 { // not pending or revision_requested
		return errors.New("approval flow is not in pending state")
	}

	// Get current step
	currentStep, err := _i.ApprovalWorkflowStepsRepository.FindByWorkflowAndStep(clientId, flow.WorkflowId, flow.CurrentStep)
	if err != nil {
		return err
	}

	if currentStep == nil {
		return errors.New("current step not found")
	}

	// Create step log
	stepLog := &entity.ArticleApprovalStepLogs{
		ApprovalFlowId: flow.ID,
		StepOrder:      flow.CurrentStep,
		StepName:       currentStep.StepName,
		ApprovedById:   &approvedById,
		Action:         "approve",
		Message:        &message,
		ProcessedAt:    time.Now(),
		UserLevelId:    currentStep.RequiredUserLevelId,
	}

	_, err = _i.ArticleApprovalStepLogsRepository.Create(clientId, stepLog)
	if err != nil {
		return err
	}

	// Check if there's a next step
	nextStep, err := _i.ApprovalWorkflowStepsRepository.GetNextStep(clientId, flow.WorkflowId, flow.CurrentStep)
	if err != nil && err.Error() != "record not found" {
		return err
	}

	if nextStep == nil || nextStep.ID == 0 {
		// No next step - approval complete
		flowUpdate := &entity.ArticleApprovalFlows{
			StatusId:    2, // approved
			CurrentStep: 0, // Set to 0 to indicate completion
			CompletedAt: &[]time.Time{time.Now()}[0],
		}

		// Debug logging
		_i.Log.Info().
			Interface("flowUpdate :: ", flowUpdate).
			Msg("Retrieved next step from database")

		err = _i.ArticleApprovalFlowsRepository.Update(flowId, flowUpdate)
		if err != nil {
			return err
		}

		// Get current article data first
		currentArticle, err := _i.ArticlesRepository.FindOne(clientId, flow.ArticleId)
		if err != nil {
			return err
		}

		// Update only the necessary fields
		currentArticle.StatusId = &[]int{2}[0]            // approved
		currentArticle.CurrentApprovalStep = &[]int{0}[0] // Set to 0 to indicate completion
		currentArticle.IsPublish = &[]bool{true}[0]       // Set to true to indicate publication
		currentArticle.IsDraft = &[]bool{false}[0]        // Set to false to indicate publication

		err = _i.ArticlesRepository.UpdateSkipNull(clientId, flow.ArticleId, currentArticle)
		if err != nil {
			return err
		}
	} else {
		// Move to next step
		flowUpdate := &entity.ArticleApprovalFlows{
			CurrentStep: nextStep.StepOrder,
			StatusId:    1, // pending
		}

		err = _i.ArticleApprovalFlowsRepository.Update(flowId, flowUpdate)
		if err != nil {
			return err
		}

		// Get current article data first
		currentArticle, err := _i.ArticlesRepository.FindOne(clientId, flow.ArticleId)
		if err != nil {
			return err
		}

		// Update only the necessary fields
		currentArticle.CurrentApprovalStep = &nextStep.StepOrder

		err = _i.ArticlesRepository.UpdateSkipNull(clientId, flow.ArticleId, currentArticle)
		if err != nil {
			return err
		}
	}

	return nil
}

func (_i *articleApprovalFlowsService) ResubmitAfterRevision(authToken string, flowId uint, resubmittedById uint) (err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return errors.New("clientId not found in auth token")
	}

	// Get approval flow
	flow, err := _i.ArticleApprovalFlowsRepository.FindOne(clientId, flowId)
	if err != nil {
		return err
	}

	if flow == nil {
		return errors.New("approval flow not found")
	}

	if flow.StatusId != 4 { // not revision_requested
		return errors.New("approval flow is not in revision requested state")
	}

	// Reset approval flow to pending
	flowUpdate := &entity.ArticleApprovalFlows{
		StatusId:          1, // pending
		RevisionRequested: &[]bool{false}[0],
		RevisionMessage:   nil,
		CurrentStep:       1, // restart from first step
	}

	err = _i.ArticleApprovalFlowsRepository.Update(flowId, flowUpdate)
	if err != nil {
		return err
	}

	// Get current article data first
	currentArticle, err := _i.ArticlesRepository.FindOne(clientId, flow.ArticleId)
	if err != nil {
		return err
	}

	// Update only the necessary fields
	currentArticle.StatusId = &[]int{1}[0] // pending approval
	currentArticle.CurrentApprovalStep = &[]int{1}[0]

	err = _i.ArticlesRepository.UpdateSkipNull(clientId, flow.ArticleId, currentArticle)
	if err != nil {
		return err
	}

	// Create resubmission log
	stepLog := &entity.ArticleApprovalStepLogs{
		ApprovalFlowId: flow.ID,
		StepOrder:      1,
		StepName:       "Resubmission",
		ApprovedById:   &resubmittedById,
		Action:         "resubmit",
		Message:        &[]string{"Article resubmitted after revision"}[0],
		ProcessedAt:    time.Now(),
	}

	_, err = _i.ArticleApprovalStepLogsRepository.Create(clientId, stepLog)
	if err != nil {
		return err
	}

	return nil
}

// Dashboard and queue methods
func (_i *articleApprovalFlowsService) GetPendingApprovals(authToken string, userLevelId uint, page, limit int, filters map[string]interface{}) (flows []*entity.ArticleApprovalFlows, paging paginator.Pagination, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return nil, paginator.Pagination{}, errors.New("clientId not found in auth token")
	}

	return _i.ArticleApprovalFlowsRepository.GetPendingApprovals(clientId, userLevelId, page, limit, filters)
}

func (_i *articleApprovalFlowsService) GetMyApprovalQueue(authToken string, userLevelId uint, page, limit int, includePreview bool, urgentOnly bool) (flows []*entity.ArticleApprovalFlows, paging paginator.Pagination, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return nil, paginator.Pagination{}, errors.New("clientId not found in auth token")
	}

	return _i.ArticleApprovalFlowsRepository.GetMyApprovalQueue(clientId, userLevelId, page, limit, includePreview, urgentOnly)
}

func (_i *articleApprovalFlowsService) GetApprovalHistory(authToken string, articleId uint, page, limit int) (logs []*entity.ArticleApprovalStepLogs, paging paginator.Pagination, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return nil, paginator.Pagination{}, errors.New("clientId not found in auth token")
	}

	return _i.ArticleApprovalStepLogsRepository.GetApprovalHistory(clientId, articleId, page, limit)
}

// Statistics and analytics
func (_i *articleApprovalFlowsService) GetPendingCountByLevel(authToken string, userLevelId uint) (count int64, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return 0, errors.New("clientId not found in auth token")
	}

	return _i.ArticleApprovalFlowsRepository.GetPendingCountByLevel(clientId, userLevelId)
}

func (_i *articleApprovalFlowsService) GetOverdueCountByLevel(authToken string, userLevelId uint) (count int64, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return 0, errors.New("clientId not found in auth token")
	}

	return _i.ArticleApprovalFlowsRepository.GetOverdueCountByLevel(clientId, userLevelId)
}

func (_i *articleApprovalFlowsService) GetApprovalStatistics(authToken string, userLevelId uint, startDate, endDate time.Time) (stats map[string]interface{}, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return nil, errors.New("clientId not found in auth token")
	}

	stats = make(map[string]interface{})

	// Get approved count
	approvedCount, err := _i.ArticleApprovalFlowsRepository.GetApprovedCountByPeriod(clientId, userLevelId, startDate, endDate)
	if err != nil {
		return nil, err
	}

	// Get rejected count
	rejectedCount, err := _i.ArticleApprovalFlowsRepository.GetRejectedCountByPeriod(clientId, userLevelId, startDate, endDate)
	if err != nil {
		return nil, err
	}

	// Get revision request count
	revisionCount, err := _i.ArticleApprovalFlowsRepository.GetRevisionRequestCountByPeriod(clientId, userLevelId, startDate, endDate)
	if err != nil {
		return nil, err
	}

	stats["approved_count"] = approvedCount
	stats["rejected_count"] = rejectedCount
	stats["revision_requested_count"] = revisionCount
	stats["total_processed"] = approvedCount + rejectedCount + revisionCount
	stats["period_start"] = startDate
	stats["period_end"] = endDate

	return stats, nil
}

func (_i *articleApprovalFlowsService) GetWorkloadAnalytics(authToken string, userLevelId uint) (analytics map[string]interface{}, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return nil, errors.New("clientId not found in auth token")
	}

	return _i.ArticleApprovalFlowsRepository.GetLevelWorkload(clientId, userLevelId)
}

// Workflow management
func (_i *articleApprovalFlowsService) CanUserApproveStep(authToken string, flowId uint, userId uint, userLevelId uint) (canApprove bool, reason string, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return false, "clientId not found in auth token", errors.New("clientId not found in auth token")
	}

	// Get approval flow
	flow, err := _i.ArticleApprovalFlowsRepository.FindOne(clientId, flowId)
	if err != nil {
		return false, "", err
	}

	if flow == nil {
		return false, "approval flow not found", nil
	}

	if flow.StatusId != 1 && flow.StatusId != 4 { // not pending or revision_requested
		return false, "approval flow is not in pending state", nil
	}

	// Get current step
	currentStep, err := _i.ApprovalWorkflowStepsRepository.FindByWorkflowAndStep(clientId, flow.WorkflowId, flow.CurrentStep)
	if err != nil {
		return false, "", err
	}

	if currentStep == nil {
		return false, "current step not found", nil
	}

	// Check if user level matches required level
	if currentStep.RequiredUserLevelId != userLevelId {
		return false, "user level does not match required level for this step", nil
	}

	// Check if user submitted the article (cannot approve own submission)
	if flow.SubmittedById == userId {
		return false, "cannot approve own submission", nil
	}

	return true, "", nil
}

func (_i *articleApprovalFlowsService) GetCurrentStepInfo(authToken string, flowId uint) (stepInfo map[string]interface{}, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return nil, errors.New("clientId not found in auth token")
	}

	stepInfo = make(map[string]interface{})

	// Get approval flow
	flow, err := _i.ArticleApprovalFlowsRepository.FindOne(clientId, flowId)
	if err != nil {
		return nil, err
	}

	if flow == nil {
		return nil, errors.New("approval flow not found")
	}

	// Get current step
	currentStep, err := _i.ApprovalWorkflowStepsRepository.FindByWorkflowAndStep(clientId, flow.WorkflowId, flow.CurrentStep)
	if err != nil {
		return nil, err
	}

	stepInfo["current_step"] = flow.CurrentStep
	stepInfo["step_name"] = currentStep.StepName
	stepInfo["required_user_level_id"] = currentStep.RequiredUserLevelId
	stepInfo["can_skip"] = currentStep.CanSkip
	stepInfo["auto_approve_after_hours"] = currentStep.AutoApproveAfterHours
	stepInfo["status"] = flow.StatusId

	return stepInfo, nil
}

func (_i *articleApprovalFlowsService) GetNextStepPreview(authToken string, flowId uint) (nextStep *entity.ApprovalWorkflowSteps, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return nil, errors.New("clientId not found in auth token")
	}

	// Get approval flow
	flow, err := _i.ArticleApprovalFlowsRepository.FindOne(clientId, flowId)
	if err != nil {
		return nil, err
	}

	if flow == nil {
		return nil, errors.New("approval flow not found")
	}

	// Get next step
	nextStep, err = _i.ApprovalWorkflowStepsRepository.GetNextStep(clientId, flow.WorkflowId, flow.CurrentStep)
	if err != nil {
		return nil, err
	}

	return nextStep, nil
}

// Multi-branch support methods implementation
func (_i *articleApprovalFlowsService) ProcessMultiBranchApproval(authToken string, flowId uint, approvedById uint, message string) (err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
			_i.Log.Info().Interface("clientId", clientId).Msg("Extracted clientId from auth token")
		}
	}

	if clientId == nil {
		return errors.New("clientId not found in auth token")
	}

	// Get current flow
	flow, err := _i.ArticleApprovalFlowsRepository.FindOne(clientId, flowId)
	if err != nil {
		return err
	}

	if flow == nil {
		return errors.New("approval flow not found")
	}

	if flow.StatusId != 1 && flow.StatusId != 4 { // not pending or revision_requested
		return errors.New("approval flow is not in pending state")
	}

	// Get current step
	currentStep, err := _i.ApprovalWorkflowStepsRepository.FindByWorkflowAndStep(clientId, flow.WorkflowId, flow.CurrentStep)
	if err != nil {
		return err
	}

	if currentStep == nil {
		return errors.New("current step not found")
	}

	// Create step log
	stepLog := &entity.ArticleApprovalStepLogs{
		ApprovalFlowId: flow.ID,
		StepOrder:      flow.CurrentStep,
		StepName:       currentStep.StepName,
		ApprovedById:   &approvedById,
		Action:         "approve",
		Message:        &message,
		ProcessedAt:    time.Now(),
		UserLevelId:    currentStep.RequiredUserLevelId,
	}

	_, err = _i.ArticleApprovalStepLogsRepository.Create(clientId, stepLog)
	if err != nil {
		return err
	}

	// Get submitter's user level to determine next steps
	submitterLevelId, err := _i.getUserLevelId(authToken, flow.SubmittedById)
	if err != nil {
		return err
	}

	// Find applicable next steps based on branching logic
	nextSteps, err := _i.FindNextStepsForBranch(authToken, flow.WorkflowId, flow.CurrentStep, submitterLevelId)
	if err != nil {
		return err
	}

	if len(nextSteps) == 0 {
		// No next steps - approval complete
		return _i.completeApprovalFlow(flow)
	} else if len(nextSteps) == 1 {
		// Single path - continue normally
		return _i.processSinglePathApproval(flow, nextSteps[0])
	} else {
		// Multiple paths - create parallel branches
		return _i.ProcessParallelBranches(authToken, flow, nextSteps, approvedById, message)
	}
}

func (_i *articleApprovalFlowsService) FindNextStepsForBranch(authToken string, workflowId uint, currentStep int, submitterLevelId uint) (steps []*entity.ApprovalWorkflowSteps, err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
		}
	}

	if clientId == nil {
		return nil, errors.New("clientId not found in auth token")
	}

	// Get all possible next steps
	allNextSteps, err := _i.ApprovalWorkflowStepsRepository.GetNextSteps(clientId, workflowId, currentStep)
	if err != nil {
		return nil, err
	}

	var applicableSteps []*entity.ApprovalWorkflowSteps

	for _, step := range allNextSteps {
		isApplicable, err := _i.IsStepApplicableForLevel(step, submitterLevelId)
		if err != nil {
			_i.Log.Error().Err(err).Uint("stepId", step.ID).Msg("Error checking step applicability")
			continue
		}

		if isApplicable {
			applicableSteps = append(applicableSteps, step)
		}
	}

	return applicableSteps, nil
}

func (_i *articleApprovalFlowsService) IsStepApplicableForLevel(step *entity.ApprovalWorkflowSteps, submitterLevelId uint) (isApplicable bool, err error) {
	if step.ConditionType == nil {
		return true, nil // Default: all steps apply
	}

	switch *step.ConditionType {
	case "user_level":
		// Parse condition value (JSON) to get allowed levels
		if step.ConditionValue == nil {
			return true, nil
		}

		var allowedLevels []uint
		err := json.Unmarshal([]byte(*step.ConditionValue), &allowedLevels)
		if err != nil {
			return false, err
		}

		for _, level := range allowedLevels {
			if level == submitterLevelId {
				return true, nil
			}
		}
		return false, nil

	case "user_level_hierarchy":
		// Check based on user level hierarchy
		return _i.checkUserLevelHierarchy(submitterLevelId, step)

	case "always":
		return true, nil

	default:
		return true, nil
	}
}

func (_i *articleApprovalFlowsService) checkUserLevelHierarchy(submitterLevelId uint, step *entity.ApprovalWorkflowSteps) (isApplicable bool, err error) {
	if step.ConditionValue == nil {
		return true, nil
	}

	var condition struct {
		AppliesToLevels []uint `json:"applies_to_levels"`
		MinLevel        *uint  `json:"min_level"`
		MaxLevel        *uint  `json:"max_level"`
	}

	err = json.Unmarshal([]byte(*step.ConditionValue), &condition)
	if err != nil {
		return false, err
	}

	// Check if submitter level is in the applies_to_levels array
	for _, level := range condition.AppliesToLevels {
		if level == submitterLevelId {
			return true, nil
		}
	}

	// Check min/max level constraints
	if condition.MinLevel != nil && submitterLevelId < *condition.MinLevel {
		return false, nil
	}
	if condition.MaxLevel != nil && submitterLevelId > *condition.MaxLevel {
		return false, nil
	}

	return false, nil
}

func (_i *articleApprovalFlowsService) ProcessParallelBranches(authToken string, flow *entity.ArticleApprovalFlows, nextSteps []*entity.ApprovalWorkflowSteps, approvedById uint, message string) (err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
		}
	}

	if clientId == nil {
		return errors.New("clientId not found in auth token")
	}

	// For parallel branches, we need to create separate approval flows
	// or handle them in a single flow with multiple current steps

	// For now, let's implement a simpler approach:
	// Take the first applicable step and continue
	if len(nextSteps) > 0 {
		return _i.processSinglePathApproval(flow, nextSteps[0])
	}

	return errors.New("no applicable next steps found")
}

func (_i *articleApprovalFlowsService) processSinglePathApproval(flow *entity.ArticleApprovalFlows, nextStep *entity.ApprovalWorkflowSteps) (err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	// Note: In a real implementation, you'd need to pass authToken or clientId

	// Update flow to next step
	flowUpdate := &entity.ArticleApprovalFlows{
		CurrentStep:   nextStep.StepOrder,
		StatusId:      1, // pending
		CurrentBranch: nextStep.BranchName,
	}

	err = _i.ArticleApprovalFlowsRepository.Update(flow.ID, flowUpdate)
	if err != nil {
		return err
	}

	// Update article current step
	currentArticle, err := _i.ArticlesRepository.FindOne(clientId, flow.ArticleId)
	if err != nil {
		return err
	}

	currentArticle.CurrentApprovalStep = &nextStep.StepOrder
	err = _i.ArticlesRepository.UpdateSkipNull(clientId, flow.ArticleId, currentArticle)
	if err != nil {
		return err
	}

	return nil
}

func (_i *articleApprovalFlowsService) completeApprovalFlow(flow *entity.ArticleApprovalFlows) (err error) {
	// Extract clientId from authToken
	var clientId *uuid.UUID
	// Note: In a real implementation, you'd need to pass authToken or clientId

	// Mark flow as approved
	flowUpdate := &entity.ArticleApprovalFlows{
		StatusId:    2, // approved
		CurrentStep: 0, // Set to 0 to indicate completion
		CompletedAt: &[]time.Time{time.Now()}[0],
	}

	err = _i.ArticleApprovalFlowsRepository.Update(flow.ID, flowUpdate)
	if err != nil {
		return err
	}

	// Update article status
	currentArticle, err := _i.ArticlesRepository.FindOne(clientId, flow.ArticleId)
	if err != nil {
		return err
	}

	currentArticle.StatusId = &[]int{2}[0]            // approved
	currentArticle.CurrentApprovalStep = &[]int{0}[0] // Set to 0 to indicate completion
	currentArticle.IsPublish = &[]bool{true}[0]       // Set to true to indicate publication
	currentArticle.IsDraft = &[]bool{false}[0]        // Set to false to indicate publication

	err = _i.ArticlesRepository.UpdateSkipNull(clientId, flow.ArticleId, currentArticle)
	if err != nil {
		return err
	}

	return nil
}

// GetUserLevelId gets the user level ID for a given user (public method)
func (_i *articleApprovalFlowsService) GetUserLevelId(authToken string, userId uint) (userLevelId uint, err error) {
	return _i.getUserLevelId(authToken, userId)
}

func (_i *articleApprovalFlowsService) FindActiveByArticleId(articleId uint) (flow *entity.ArticleApprovalFlows, err error) {
	return _i.ArticleApprovalFlowsRepository.FindActiveByArticleId(articleId)
}

// ProcessApprovalAction processes different approval actions (approve, request_update, reject)
func (_i *articleApprovalFlowsService) ProcessApprovalAction(authToken string, flowId uint, action string, actionById uint, message string) (err error) {
	_i.Log.Info().
		Uint("flowId", flowId).
		Str("action", action).
		Uint("actionById", actionById).
		Str("message", message).
		Msg("Processing approval action")

	// Extract clientId from authToken
	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
		}
	}

	// Get the approval flow
	flow, err := _i.ArticleApprovalFlowsRepository.FindOne(clientId, flowId)
	if err != nil {
		return fmt.Errorf("failed to find approval flow: %w", err)
	}

	// Get the article
	article, err := _i.ArticlesRepository.FindOne(clientId, flow.ArticleId)
	if err != nil {
		return fmt.Errorf("failed to find article: %w", err)
	}

	switch action {
	case "approve":
		return _i.processApproveAction(authToken, flow, article, actionById, message)
	case "revision":
		return _i.processRequestUpdateAction(authToken, flow, article, actionById, message)
	case "reject":
		return _i.processRejectAction(authToken, flow, article, actionById, message)
	default:
		return fmt.Errorf("invalid action: %s", action)
	}
}

// processApproveAction handles approve action - moves to next step
func (_i *articleApprovalFlowsService) processApproveAction(authToken string, flow *entity.ArticleApprovalFlows, article *entity.Articles, actionById uint, message string) error {
	_i.Log.Info().Uint("flowId", flow.ID).Msg("Processing approve action")

	// Use existing multi-branch approval logic
	return _i.ProcessMultiBranchApproval(authToken, flow.ID, actionById, message)
}

// processRequestUpdateAction handles request update action - moves back 1 step
func (_i *articleApprovalFlowsService) processRequestUpdateAction(authToken string, flow *entity.ArticleApprovalFlows, article *entity.Articles, actionById uint, message string) error {
	_i.Log.Info().Uint("flowId", flow.ID).Msg("Processing request update action")

	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
		}
	}

	// Reset to initial step (step 1) and status pending
	flow.CurrentStep = 1
	flow.StatusId = 1 // pending - seperti belum berjalan flow approval
	flow.RevisionRequested = &[]bool{true}[0]
	flow.RevisionMessage = &message

	err := _i.ArticleApprovalFlowsRepository.Update(flow.ID, flow)
	if err != nil {
		return fmt.Errorf("failed to update flow for request update: %w", err)
	}

	// Update article status to draft for revision
	article.StatusId = &[]int{1}[0] // 1 = draft
	article.IsDraft = &[]bool{true}[0]
	article.WorkflowId = &flow.WorkflowId      // Keep workflow ID for restart
	article.CurrentApprovalStep = &[]int{1}[0] // Reset to step 1

	err = _i.ArticlesRepository.Update(clientId, article.ID, article)
	if err != nil {
		return fmt.Errorf("failed to update article for revision: %w", err)
	}

	// Create step log
	stepLog := &entity.ArticleApprovalStepLogs{
		ApprovalFlowId: flow.ID,
		StepOrder:      flow.CurrentStep,
		Action:         "revision",
		ApprovedById:   &actionById,
		Message:        &message,
		CreatedAt:      time.Now(),
	}

	_, err = _i.ArticleApprovalStepLogsRepository.Create(clientId, stepLog)
	if err != nil {
		_i.Log.Error().Err(err).Msg("Failed to create step log for request update")
	}

	_i.Log.Info().
		Uint("flowId", flow.ID).
		Int("resetStep", 1).
		Msg("Revision request processed - flow reset to step 1")

	return nil
}

// processRejectAction handles reject action - returns to draft status
func (_i *articleApprovalFlowsService) processRejectAction(authToken string, flow *entity.ArticleApprovalFlows, article *entity.Articles, actionById uint, message string) error {
	_i.Log.Info().Uint("flowId", flow.ID).Msg("Processing reject action")

	var clientId *uuid.UUID
	if authToken != "" {
		user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepository, authToken)
		if user != nil && user.ClientId != nil {
			clientId = user.ClientId
		}
	}

	// Reset to initial step (step 1) and status pending
	flow.CurrentStep = 1
	flow.StatusId = 1               // pending - seperti belum berjalan flow approval
	flow.RevisionMessage = &message // Use same field for consistency
	// Don't set completedAt - flow is not completed, just reset

	err := _i.ArticleApprovalFlowsRepository.Update(flow.ID, flow)
	if err != nil {
		return fmt.Errorf("failed to update flow for rejection: %w", err)
	}
	// Update article status to draft
	article.StatusId = &[]int{1}[0] // 1 = draft
	article.IsDraft = &[]bool{true}[0]
	article.WorkflowId = &flow.WorkflowId      // Keep workflow ID for restart
	article.CurrentApprovalStep = &[]int{1}[0] // Reset to step 1

	err = _i.ArticlesRepository.Update(clientId, article.ID, article)
	if err != nil {
		return fmt.Errorf("failed to update article for rejection: %w", err)
	}

	// Create step log
	stepLog := &entity.ArticleApprovalStepLogs{
		ApprovalFlowId: flow.ID,
		StepOrder:      flow.CurrentStep,
		Action:         "reject",
		ApprovedById:   &actionById,
		Message:        &message,
		CreatedAt:      time.Now(),
	}

	_, err = _i.ArticleApprovalStepLogsRepository.Create(clientId, stepLog)
	if err != nil {
		_i.Log.Error().Err(err).Msg("Failed to create step log for rejection")
	}

	_i.Log.Info().
		Uint("flowId", flow.ID).
		Uint("articleId", article.ID).
		Msg("Rejection processed - flow reset to step 1, article returned to draft")

	return nil
}
