using Books.Api.Commands.Accounts;
using Books.Api.Domain.Accounts;
using Books.Api.EventFlow.Repositories;
using EventFlow;
using Microsoft.Extensions.Logging;

namespace Books.Api.Invoicing.Services;

/// <summary>
/// Implementation of customer sub-ledger account management.
/// Creates accounts in the format 1900-XXXX as children of the main Debitorer account (1900).
/// </summary>
public class CustomerSubLedgerService(
    ICommandBus commandBus,
    IAccountRepository accountRepository,
    ILogger<CustomerSubLedgerService> logger) : ICustomerSubLedgerService
{
    private const string DebitorsControlAccountNumber = "1900";

    public async Task<string> CreateSubLedgerAccountAsync(
        string companyId,
        string customerNumber,
        string customerName,
        CancellationToken cancellationToken = default)
    {
        // Generate sub-ledger account number: 1900XXXX (e.g., 19000001 for customer 0001)
        // Remove leading zeros and pad to ensure valid account number format
        var customerNum = customerNumber.TrimStart('0');
        if (string.IsNullOrEmpty(customerNum)) customerNum = "0";
        var subLedgerAccountNumber = $"1900{customerNum.PadLeft(4, '0')}";

        // Create deterministic account ID based on company and account number
        var accountId = AccountId.FromCompanyAndNumber(companyId, subLedgerAccountNumber);

        // Get the parent Debitorer account (1900) for hierarchy
        var parentAccount = await accountRepository.GetByCompanyAndNumberAsync(
            companyId, DebitorsControlAccountNumber, cancellationToken);

        var command = new CreateAccountCommand(
            accountId,
            companyId,
            subLedgerAccountNumber,
            $"Debitor: {customerName}",
            AccountType.Asset, // Sub-ledger accounts are assets (receivables)
            parentAccount?.Id, // Parent is 1900 Debitorer
            $"Sub-ledger account for customer {customerNumber}",
            vatCodeId: null, // No VAT on sub-ledger accounts
            isSystemAccount: true); // System-managed, cannot be manually edited

        await commandBus.PublishAsync(command, cancellationToken);

        logger.LogInformation(
            "Created sub-ledger account {AccountNumber} for customer {CustomerNumber} in company {CompanyId}",
            subLedgerAccountNumber, customerNumber, companyId);

        return accountId.Value;
    }

    public async Task<decimal> GetCustomerBalanceAsync(
        string subLedgerAccountId,
        DateOnly? asOfDate = null,
        CancellationToken cancellationToken = default)
    {
        // For now, return 0 - will be implemented when Ledger query integration is added
        // This would query the Ledger service using:
        // var query = new EntriesQuery { AccountIds = [accountGuid], To = asOfDate, Aggregate = true };
        // var result = await ledgerService.QueryEntriesAsync(query, cancellationToken);
        // return result.Aggregates?.FirstOrDefault()?.NetChange ?? 0m;

        await Task.CompletedTask;
        return 0m;
    }
}
