using CashLineERP.Domain.Common;

namespace CashLineERP.Domain.Finance;

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

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

    public DateOnly StartDate { get; private set; }

    public DateOnly EndDate { get; private set; }

    public string CloseStatusCode { get; private set; } = "OPEN";

    public bool IsYearEnd { get; private set; }

    public DateTime? ReadyForCloseAtUtc { get; private set; }

    public long? ReadyForCloseByUserId { get; private set; }

    public DateTime? ClosedAtUtc { get; private set; }

    public long? ClosedByUserId { get; private set; }

    public AccountingPeriod(
        string periodCode,
        DateOnly startDate,
        DateOnly endDate,
        bool isYearEnd)
    {
        PeriodCode = periodCode;
        StartDate = startDate;
        EndDate = endDate;
        IsYearEnd = isYearEnd;
    }

    private AccountingPeriod()
    {
    }

    public void MarkReadyForClose(long actorUserId)
    {
        CloseStatusCode = "READY_TO_CLOSE";
        ReadyForCloseAtUtc = DateTime.UtcNow;
        ReadyForCloseByUserId = actorUserId;
        Touch(actorUserId);
    }

    public void Close(long actorUserId)
    {
        if (!string.Equals(CloseStatusCode, "READY_TO_CLOSE", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("Accounting period must be ready to close before closure.");
        }

        CloseStatusCode = "CLOSED";
        ClosedAtUtc = DateTime.UtcNow;
        ClosedByUserId = actorUserId;
        Touch(actorUserId);
    }
}
