using Books.Api.EventFlow.ReadModels;

namespace Books.Api.EventFlow.Repositories;

public interface IInvoiceRepository
{
    Task<InvoiceReadModelDto?> GetByIdAsync(string id, CancellationToken cancellationToken = default);

    Task<IReadOnlyList<InvoiceReadModelDto>> GetByCompanyIdAsync(
        string companyId,
        string? status = null,
        CancellationToken cancellationToken = default);

    Task<IReadOnlyList<InvoiceReadModelDto>> GetByCustomerIdAsync(
        string customerId,
        string? status = null,
        CancellationToken cancellationToken = default);

    Task<IReadOnlyList<InvoiceReadModelDto>> GetByFiscalYearIdAsync(
        string fiscalYearId,
        string? status = null,
        CancellationToken cancellationToken = default);

    Task<IReadOnlyList<InvoiceReadModelDto>> GetUnpaidByCompanyIdAsync(
        string companyId,
        CancellationToken cancellationToken = default);

    Task<IReadOnlyList<InvoiceReadModelDto>> GetOverdueByCompanyIdAsync(
        string companyId,
        DateOnly asOfDate,
        CancellationToken cancellationToken = default);

    Task<InvoiceReadModelDto?> GetByInvoiceNumberAsync(
        string companyId,
        string invoiceNumber,
        CancellationToken cancellationToken = default);

    // Credit note specific queries

    /// <summary>
    /// Gets all credit notes for a company (invoice_type = 'credit_note').
    /// </summary>
    Task<IReadOnlyList<InvoiceReadModelDto>> GetCreditNotesByCompanyIdAsync(
        string companyId,
        string? status = null,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets all credit notes referencing a specific invoice.
    /// </summary>
    Task<IReadOnlyList<InvoiceReadModelDto>> GetCreditNotesForInvoiceAsync(
        string invoiceId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets credit notes that have remaining credit to apply (status = issued or partially_applied).
    /// </summary>
    Task<IReadOnlyList<InvoiceReadModelDto>> GetUnappliedCreditNotesAsync(
        string companyId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets only invoices (not credit notes) for a company.
    /// </summary>
    Task<IReadOnlyList<InvoiceReadModelDto>> GetInvoicesOnlyByCompanyIdAsync(
        string companyId,
        string? status = null,
        CancellationToken cancellationToken = default);
}
