using CashLineERP.Domain.Common;

namespace CashLineERP.Domain.Reporting;

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

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

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

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

    public DateOnly? DateFrom { get; private set; }

    public DateOnly? DateTo { get; private set; }

    public DateOnly? AsOfDate { get; private set; }

    public int RowCount { get; private set; }

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

    public string? CsvPayloadText { get; private set; }

    public string? Notes { get; private set; }

    public DateTime GeneratedAtUtc { get; private set; }

    public long GeneratedByUserId { get; private set; }

    public ReportingSnapshot(
        string snapshotNumber,
        string reportCode,
        string reportTitle,
        DateOnly? dateFrom,
        DateOnly? dateTo,
        DateOnly? asOfDate,
        int rowCount,
        string jsonPayloadText,
        string? csvPayloadText,
        string? notes,
        long actorUserId)
    {
        if (string.IsNullOrWhiteSpace(snapshotNumber))
        {
            throw new InvalidOperationException("Reporting snapshot number is required.");
        }

        if (string.IsNullOrWhiteSpace(reportCode))
        {
            throw new InvalidOperationException("Reporting snapshot report code is required.");
        }

        if (string.IsNullOrWhiteSpace(reportTitle))
        {
            throw new InvalidOperationException("Reporting snapshot report title is required.");
        }

        if (dateFrom.HasValue && dateTo.HasValue && dateFrom.Value > dateTo.Value)
        {
            throw new InvalidOperationException("Reporting snapshot date range is invalid because dateFrom is after dateTo.");
        }

        if (rowCount < 0)
        {
            throw new InvalidOperationException("Reporting snapshot row count cannot be negative.");
        }

        if (string.IsNullOrWhiteSpace(jsonPayloadText))
        {
            throw new InvalidOperationException("Reporting snapshot JSON payload is required.");
        }

        SnapshotNumber = snapshotNumber.Trim().ToUpperInvariant();
        ReportCode = reportCode.Trim().ToUpperInvariant();
        ReportTitle = reportTitle.Trim();
        DateFrom = dateFrom;
        DateTo = dateTo;
        AsOfDate = asOfDate;
        RowCount = rowCount;
        JsonPayloadText = jsonPayloadText;
        CsvPayloadText = string.IsNullOrWhiteSpace(csvPayloadText) ? null : csvPayloadText;
        Notes = string.IsNullOrWhiteSpace(notes) ? null : notes.Trim();
        GeneratedAtUtc = DateTime.UtcNow;
        GeneratedByUserId = actorUserId;
        CreatedByUserId = actorUserId;
    }

    private ReportingSnapshot()
    {
    }
}
