using CashLineERP.Contracts.Workflow;

namespace CashLineERP.Application.Workflow;

public sealed class WorkflowService : IWorkflowService
{
    private readonly IWorkflowReadRepository _workflowReadRepository;

    public WorkflowService(IWorkflowReadRepository workflowReadRepository)
    {
        _workflowReadRepository = workflowReadRepository;
    }

    public IReadOnlyCollection<WorkflowQueueItemResponse> GetPendingQueue()
    {
        return _workflowReadRepository
            .GetPendingQueue()
            .Select(item => new WorkflowQueueItemResponse(
                item.WorkflowInstanceId,
                item.ModuleCode,
                item.DocumentType,
                item.DocumentNumber,
                item.CurrentStatus,
                item.SubmittedBy,
                item.SubmittedAtUtc))
            .ToArray();
    }

    public IReadOnlyCollection<WorkflowRuleAdminResponse> GetWorkflowRules(bool activeOnly = false) =>
        _workflowReadRepository.GetWorkflowRules(activeOnly)
            .Select(rule => new WorkflowRuleAdminResponse(
                rule.WorkflowRuleId,
                rule.ModuleCode,
                rule.DocumentType,
                rule.ActionCode,
                rule.MakerRoleCode,
                rule.CheckerRoleCode,
                rule.ThresholdAmount,
                rule.CurrencyCode,
                rule.BranchId,
                rule.IsActive))
            .ToArray();

    public IReadOnlyCollection<WorkflowInstanceSummaryResponse> GetWorkflowInstances(string? moduleCode = null, string? documentType = null, string? statusCode = null) =>
        _workflowReadRepository.GetWorkflowInstances(moduleCode, documentType, statusCode)
            .Select(instance => new WorkflowInstanceSummaryResponse(
                instance.WorkflowInstanceId,
                instance.ModuleCode,
                instance.DocumentType,
                instance.DocumentId,
                instance.DocumentNumber,
                instance.WorkflowRuleId,
                instance.CurrentStatusCode,
                instance.MakerLoginName,
                instance.CheckerLoginName,
                instance.SubmittedAtUtc,
                instance.DecidedAtUtc))
            .ToArray();

    public WorkflowInstanceResponse? GetWorkflowInstance(long workflowInstanceId)
    {
        var instance = _workflowReadRepository.GetWorkflowInstance(workflowInstanceId);
        return instance is null
            ? null
            : new WorkflowInstanceResponse(
                instance.WorkflowInstanceId,
                instance.ModuleCode,
                instance.DocumentType,
                instance.DocumentId,
                instance.DocumentNumber,
                instance.WorkflowRuleId,
                instance.MakerUserId,
                instance.MakerLoginName,
                instance.CheckerUserId,
                instance.CheckerLoginName,
                instance.SubmittedAtUtc,
                instance.DecidedAtUtc,
                instance.CurrentStatusCode,
                instance.Actions.Select(action => new WorkflowActionResponse(
                    action.WorkflowActionId,
                    action.ActionCode,
                    action.PreviousStatusCode,
                    action.NewStatusCode,
                    action.ActorUserId,
                    action.ActorLoginName,
                    action.Comment,
                    action.OccurredAtUtc)).ToArray());
    }
}
