using CashLineERP.Domain.Common;

namespace CashLineERP.Domain.Finance;

public sealed class ReceiptReconciliationRun : Entity
{
    public long Id { get; private set; }

    public string RunNumber { get; private set; } = string.Empty;

    public long AccountingPeriodId { get; private set; }

    public long BankStatementId { get; private set; }

    public string RunStatusCode { get; private set; } = "DRAFT";

    public int MatchedItemCount { get; private set; }

    public int ExceptionItemCount { get; private set; }

    public int UnmatchedItemCount { get; private set; }

    public DateTime StartedAtUtc { get; private set; } = DateTime.UtcNow;

    public DateTime? CompletedAtUtc { get; private set; }

    public List<ReceiptReconciliationItem> Items { get; private set; } = [];

    public ReceiptReconciliationRun(
        string runNumber,
        long accountingPeriodId,
        long bankStatementId)
    {
        RunNumber = runNumber;
        AccountingPeriodId = accountingPeriodId;
        BankStatementId = bankStatementId;
    }

    private ReceiptReconciliationRun()
    {
    }

    public void AddItem(ReceiptReconciliationItem item)
    {
        Items.Add(item);
        if (string.Equals(item.MatchStatusCode, "MATCHED", StringComparison.OrdinalIgnoreCase))
        {
            MatchedItemCount++;
            return;
        }

        if (string.Equals(item.MatchStatusCode, "EXCEPTION", StringComparison.OrdinalIgnoreCase))
        {
            ExceptionItemCount++;
            return;
        }

        UnmatchedItemCount++;
    }

    public void Complete(long actorUserId)
    {
        RunStatusCode = "COMPLETED";
        CompletedAtUtc = DateTime.UtcNow;
        Touch(actorUserId);
    }

    public void RecalculateCounters()
    {
        MatchedItemCount = Items.Count(item =>
            string.Equals(item.MatchStatusCode, "MATCHED", StringComparison.OrdinalIgnoreCase)
            || string.Equals(item.MatchStatusCode, "MANUAL_MATCHED", StringComparison.OrdinalIgnoreCase)
            || string.Equals(item.MatchStatusCode, "OVERRIDDEN", StringComparison.OrdinalIgnoreCase));

        ExceptionItemCount = Items.Count(item => string.Equals(item.MatchStatusCode, "EXCEPTION", StringComparison.OrdinalIgnoreCase));
        UnmatchedItemCount = Items.Count(item => string.Equals(item.MatchStatusCode, "UNMATCHED", StringComparison.OrdinalIgnoreCase));
    }
}
