using CashLineERP.Contracts.IslamicFinance;
using CashLineERP.SharedKernel.IslamicFinance;

namespace CashLineERP.Application.IslamicFinance.Shariah;

public sealed class ShariahReviewService : IShariahReviewService
{
    private readonly IShariahReviewRepository _repository;

    public ShariahReviewService(IShariahReviewRepository repository)
    {
        _repository = repository;
    }

    public IReadOnlyCollection<IslamicFinanceShariahReviewResponse> GetReviewCases(
        string? statusCode = null,
        long? financingRequestId = null,
        long? productProfileId = null) =>
        _repository.GetReviewCases(statusCode, financingRequestId, productProfileId).Select(Map).ToArray();

    public IslamicFinanceShariahReviewResponse? GetReviewCase(long shariahReviewCaseId)
    {
        var entry = _repository.GetReviewCase(shariahReviewCaseId);
        return entry is null ? null : Map(entry);
    }

    public IslamicFinanceShariahReviewResponse CreateReviewCase(CreateIslamicFinanceShariahReviewRequest request) =>
        Map(_repository.Create(new CreateIslamicFinanceShariahReviewCommand(
            request.ReviewCaseNumber,
            request.ProductProfileId,
            request.FinancingRequestId,
            IslamicFinanceGovernanceCatalog.NormalizeReasonCode(request.ReviewReasonCode))));

    public IslamicFinanceShariahReviewResponse SubmitReviewCase(long shariahReviewCaseId, long actorUserId) =>
        Map(_repository.Submit(shariahReviewCaseId, actorUserId));

    public IslamicFinanceShariahReviewResponse RecommendOutcome(
        long shariahReviewCaseId,
        RecommendIslamicFinanceShariahOutcomeRequest request,
        long actorUserId) =>
        Map(_repository.RecommendOutcome(
            shariahReviewCaseId,
            new RecommendIslamicFinanceShariahOutcomeCommand(
                IslamicFinanceShariahOutcomeCatalog.NormalizeOutcomeCode(request.ReviewOutcomeCode),
                request.ReviewNotes,
                actorUserId)));

    public IslamicFinanceShariahReviewResponse ApproveOutcome(long shariahReviewCaseId, long actorUserId) =>
        Map(_repository.ApproveOutcome(shariahReviewCaseId, actorUserId));

    private static IslamicFinanceShariahReviewResponse Map(IslamicFinanceShariahReviewDetailView entry) =>
        new()
        {
            Id = entry.ShariahReviewCaseId,
            ReviewCaseNumber = entry.ReviewCaseNumber,
            ProductProfileId = entry.ProductProfileId,
            FinancingRequestId = entry.FinancingRequestId,
            ReviewReasonCode = entry.ReviewReasonCode,
            ReviewOutcomeCode = entry.ReviewOutcomeCode,
            ReviewNotes = entry.ReviewNotes,
            StatusCode = entry.StatusCode,
            WorkflowInstanceId = entry.WorkflowInstanceId,
            SubmittedAtUtc = entry.SubmittedAtUtc,
            SubmittedByUserId = entry.SubmittedByUserId,
            ReviewedAtUtc = entry.ReviewedAtUtc,
            ReviewedByUserId = entry.ReviewedByUserId,
            ApprovedAtUtc = entry.ApprovedAtUtc,
            ApprovedByUserId = entry.ApprovedByUserId
        };
}
