package service

import (
	"errors"
	"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)
	RejectArticle(authToken string, flowId uint, rejectedById uint, reason string) (err error)
	RequestRevision(authToken string, flowId uint, requestedById uint, revisionMessage 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)
}

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(clientId *uuid.UUID, flow *entity.ArticleApprovalFlows) (flowReturn *entity.ArticleApprovalFlows, err error) {
	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(clientId *uuid.UUID, id uint) (err error) {
	return _i.ArticleApprovalFlowsRepository.Delete(clientId, id)
}

// Article submission and approval workflow
func (_i *articleApprovalFlowsService) SubmitArticleForApproval(clientId *uuid.UUID, articleId uint, submittedById uint, workflowId *uint) (flow *entity.ArticleApprovalFlows, err error) {
	// 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(clientId, flow, submittedById)
	if err != nil {
		return nil, err
	}

	return flow, nil
}

// processAutoSkipSteps handles automatic step skipping based on user level
func (_i *articleApprovalFlowsService) processAutoSkipSteps(clientId *uuid.UUID, flow *entity.ArticleApprovalFlows, submittedById uint) error {
	// Get user level of the submitter
	userLevelId, err := _i.getUserLevelId(clientId, 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(clientId *uuid.UUID, userId uint) (uint, error) {
	// 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(clientId *uuid.UUID, flowId uint, approvedById uint, message string) (err error) {
	// 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) RejectArticle(clientId *uuid.UUID, flowId uint, rejectedById uint, reason string) (err error) {
	// 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
	}

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

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

	// Update approval flow status
	flowUpdate := &entity.ArticleApprovalFlows{
		StatusId:        3, // rejected
		RejectionReason: &reason,
		CompletedAt:     &[]time.Time{time.Now()}[0],
	}

	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{3}[0] // rejected
	currentArticle.CurrentApprovalStep = nil

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

	return nil
}

func (_i *articleApprovalFlowsService) RequestRevision(clientId *uuid.UUID, flowId uint, requestedById uint, revisionMessage string) (err error) {
	// 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 { // not pending
		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
	}

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

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

	// Update approval flow status
	flowUpdate := &entity.ArticleApprovalFlows{
		StatusId:          4, // revision_requested
		RevisionRequested: &[]bool{true}[0],
		RevisionMessage:   &revisionMessage,
	}

	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{4}[0] // revision_requested

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

	return nil
}

func (_i *articleApprovalFlowsService) ResubmitAfterRevision(clientId *uuid.UUID, flowId uint, resubmittedById uint) (err error) {
	// 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(clientId *uuid.UUID, userLevelId uint, page, limit int, filters map[string]interface{}) (flows []*entity.ArticleApprovalFlows, paging paginator.Pagination, err error) {
	return _i.ArticleApprovalFlowsRepository.GetPendingApprovals(clientId, userLevelId, page, limit, filters)
}

func (_i *articleApprovalFlowsService) GetMyApprovalQueue(clientId *uuid.UUID, userLevelId uint, page, limit int, includePreview bool, urgentOnly bool) (flows []*entity.ArticleApprovalFlows, paging paginator.Pagination, err error) {
	return _i.ArticleApprovalFlowsRepository.GetMyApprovalQueue(clientId, userLevelId, page, limit, includePreview, urgentOnly)
}

func (_i *articleApprovalFlowsService) GetApprovalHistory(clientId *uuid.UUID, articleId uint, page, limit int) (logs []*entity.ArticleApprovalStepLogs, paging paginator.Pagination, err error) {
	return _i.ArticleApprovalStepLogsRepository.GetApprovalHistory(clientId, articleId, page, limit)
}

// Statistics and analytics
func (_i *articleApprovalFlowsService) GetPendingCountByLevel(clientId *uuid.UUID, userLevelId uint) (count int64, err error) {
	return _i.ArticleApprovalFlowsRepository.GetPendingCountByLevel(clientId, userLevelId)
}

func (_i *articleApprovalFlowsService) GetOverdueCountByLevel(clientId *uuid.UUID, userLevelId uint) (count int64, err error) {
	return _i.ArticleApprovalFlowsRepository.GetOverdueCountByLevel(clientId, userLevelId)
}

func (_i *articleApprovalFlowsService) GetApprovalStatistics(clientId *uuid.UUID, userLevelId uint, startDate, endDate time.Time) (stats map[string]interface{}, err error) {
	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(clientId *uuid.UUID, userLevelId uint) (analytics map[string]interface{}, err error) {
	return _i.ArticleApprovalFlowsRepository.GetLevelWorkload(clientId, userLevelId)
}

// Workflow management
func (_i *articleApprovalFlowsService) CanUserApproveStep(clientId *uuid.UUID, flowId uint, userId uint, userLevelId uint) (canApprove bool, reason string, err error) {
	// 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(clientId *uuid.UUID, flowId uint) (stepInfo map[string]interface{}, err error) {
	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(clientId *uuid.UUID, flowId uint) (nextStep *entity.ApprovalWorkflowSteps, err error) {
	// 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
}
