using CashLineERP.Contracts.Parties;

namespace CashLineERP.Application.Parties;

public sealed class OnboardingCaseService : IOnboardingCaseService
{
    private readonly IOnboardingCaseRepository _repository;

    public OnboardingCaseService(IOnboardingCaseRepository repository)
    {
        _repository = repository;
    }

    public IReadOnlyCollection<OnboardingCaseSummaryResponse> GetCases(string? subjectTypeCode = null, string? caseStatusCode = null, string? queueCode = null, long? submittedByUserId = null) =>
        _repository.GetCases(subjectTypeCode, caseStatusCode, queueCode, submittedByUserId)
            .Select(Map)
            .ToArray();

    public OnboardingCaseDetailResponse? GetCase(string subjectTypeCode, long subjectProfileId, long? submittedByUserId = null)
    {
        var view = _repository.GetCase(subjectTypeCode, subjectProfileId, submittedByUserId);
        return view is null ? null : Map(view);
    }

    private static OnboardingCaseSummaryResponse Map(OnboardingCaseSummaryView view) =>
        new(
            view.SubjectTypeCode,
            view.SubjectProfileId,
            view.BusinessPartyId,
            view.PartyCode,
            view.PartyName,
            view.ProfileCode,
            view.InitiationPathCode,
            view.SubmissionSourceCode,
            view.SubmissionSourceDisplayName,
            view.CaseStatusCode,
            view.QueueCode,
            view.WorkflowStatusCode,
            view.ChecklistItemCount,
            view.UnresolvedChecklistItemCount,
            view.FindingCount,
            view.OpenFindingCount,
            view.ReadyForApproval,
            view.ReadyForActivation,
            view.SubmittedAtUtc,
            view.SubmittedByLoginName,
            view.SubmittedByDisplayName,
            view.LastReviewActivityAtUtc,
            view.LastReviewActorLoginName);

    private static OnboardingCaseDetailResponse Map(OnboardingCaseDetailView view) =>
        new(
            view.SubjectTypeCode,
            view.SubjectProfileId,
            view.BusinessPartyId,
            view.PartyCode,
            view.PartyName,
            view.PartyTypeCode,
            view.ProfileCode,
            view.InitiationPathCode,
            view.SubmissionSourceCode,
            view.SubmissionSourceDisplayName,
            view.CaseStatusCode,
            view.QueueCode,
            view.WorkflowStatusCode,
            view.CountryCode,
            view.TaxRegistrationNumber,
            view.Email,
            view.MobileNumber,
            view.AddressLine1,
            view.DomainStatusCode,
            view.IsActive,
            view.IsOnHold,
            view.HoldReason,
            view.ReviewDecisionNotes,
            view.ChecklistItemCount,
            view.UnresolvedChecklistItemCount,
            view.FindingCount,
            view.OpenFindingCount,
            view.ReadyForApproval,
            view.ReadyForActivation,
            view.SubmittedAtUtc,
            view.SubmittedByLoginName,
            view.SubmittedByDisplayName,
            view.ApprovedAtUtc,
            view.ApprovedByLoginName,
            view.ActivatedAtUtc,
            view.ActivatedByLoginName,
            view.LastReviewActivityAtUtc,
            view.LastReviewActorLoginName,
            view.ChecklistItems.Select(item => new OnboardingReviewChecklistItemResponse(
                item.OnboardingReviewChecklistItemId,
                item.ChecklistItemCode,
                item.DisplayName,
                item.StatusCode,
                item.CoverageCode,
                item.ReviewerNotes,
                item.ReviewedAtUtc,
                item.ReviewedByUserId)).ToArray(),
            view.Findings.Select(finding => new OnboardingReviewFindingResponse(
                finding.OnboardingReviewFindingId,
                finding.FindingCode,
                finding.SeverityCode,
                finding.RelatedItemCode,
                finding.StatusCode,
                finding.FindingText,
                finding.LoggedAtUtc,
                finding.LoggedByUserId)).ToArray());
}
