namespace TaxBaik.Application.Services;

using TaxBaik.Domain.Entities;
using TaxBaik.Domain.Interfaces;

public class RevenueTrackingService(IRevenueTrackingRepository repository)
{
    public async Task<int> CreateAsync(int clientId, string invoiceNumber, DateTime invoiceDate,
        decimal amount, string? serviceType = null, DateTime? dueDate = null, CancellationToken ct = default)
    {
        if (clientId <= 0)
            throw new ValidationException("유효한 고객을 선택하세요.");
        if (string.IsNullOrWhiteSpace(invoiceNumber))
            throw new ValidationException("인보이스 번호를 입력하세요.");
        if (amount <= 0)
            throw new ValidationException("금액은 0보다 커야 합니다.");

        var revenue = new RevenueTracking
        {
            ClientId = clientId,
            InvoiceNumber = invoiceNumber.Trim(),
            InvoiceDate = invoiceDate,
            Amount = amount,
            ServiceType = string.IsNullOrWhiteSpace(serviceType) ? null : serviceType.Trim(),
            DueDate = dueDate,
            PaymentStatus = "pending",
            CreatedAt = DateTime.UtcNow,
            UpdatedAt = DateTime.UtcNow
        };

        return await repository.CreateAsync(revenue, ct);
    }

    public async Task<IEnumerable<RevenueTracking>> GetByClientIdAsync(int clientId, CancellationToken ct = default) =>
        await repository.GetByClientIdAsync(clientId, ct);

    public async Task<IEnumerable<RevenueTracking>> GetAllAsync(CancellationToken ct = default) =>
        await repository.GetAllAsync(ct);

    public async Task<IEnumerable<RevenueTracking>> GetPendingPaymentsAsync(CancellationToken ct = default) =>
        await repository.GetPendingPaymentsAsync(ct);

    public async Task<IEnumerable<RevenueTracking>> GetMonthlyRevenueAsync(DateTime month, CancellationToken ct = default)
    {
        var startDate = new DateTime(month.Year, month.Month, 1);
        var endDate = startDate.AddMonths(1).AddDays(-1);
        return await repository.GetByDateRangeAsync(startDate, endDate, ct);
    }

    public async Task MarkPaidAsync(int id, DateTime paymentDate, CancellationToken ct = default) =>
        await repository.MarkPaidAsync(id, paymentDate, ct);

    public async Task<decimal> GetTotalRevenueAsync(DateTime startDate, DateTime endDate, CancellationToken ct = default) =>
        await repository.GetTotalRevenueAsync(startDate, endDate, ct);
}
