using CashLineERP.Contracts.Finance;

namespace CashLineERP.Application.Finance;

public sealed class AccountingRuleService : IAccountingRuleService
{
    private readonly IAccountingRuleRepository _repository;

    public AccountingRuleService(IAccountingRuleRepository repository)
    {
        _repository = repository;
    }

    public IReadOnlyCollection<FinanceAccountingRuleResponse> GetAccountingRules(bool activeOnly = false) =>
        _repository.GetAccountingRules(activeOnly)
            .Select(Map)
            .ToArray();

    public FinanceAccountingRuleResponse? GetAccountingRule(long financeAccountingRuleId)
    {
        var rule = _repository.GetAccountingRule(financeAccountingRuleId);
        return rule is null ? null : Map(rule);
    }

    public FinanceAccountingRuleResponse CreateAccountingRule(CreateFinanceAccountingRuleRequest request) =>
        Map(_repository.Create(new CreateFinanceAccountingRuleCommand(
            request.RuleName,
            request.GeneralLedgerAccountId,
            request.GeneralLedgerAccountCode,
            request.GeneralLedgerAccountName,
            request.AccountCategoryCode,
            request.StatementSectionCode,
            request.CashFlowCategoryCode,
            request.IsCashAccount,
            request.DisplayOrder,
            request.EffectiveFromDate,
            request.EffectiveToDate,
            request.Notes)));

    public FinanceAccountingRuleResponse SubmitAccountingRule(long financeAccountingRuleId, long actorUserId) =>
        Map(_repository.Submit(financeAccountingRuleId, actorUserId));

    public FinanceAccountingRuleResponse ApproveAccountingRule(long financeAccountingRuleId, long actorUserId) =>
        Map(_repository.Approve(financeAccountingRuleId, actorUserId));

    public FinanceAccountingRuleResponse ActivateAccountingRule(long financeAccountingRuleId, long actorUserId) =>
        Map(_repository.Activate(financeAccountingRuleId, actorUserId));

    private static FinanceAccountingRuleResponse Map(FinanceAccountingRuleDetailView rule) =>
        new(
            rule.FinanceAccountingRuleId,
            rule.RuleCode,
            rule.RuleName,
            rule.GeneralLedgerAccountId,
            rule.GeneralLedgerAccountCode,
            rule.GeneralLedgerAccountName,
            rule.AccountCategoryCode,
            rule.StatementSectionCode,
            rule.CashFlowCategoryCode,
            rule.IsCashAccount,
            rule.DisplayOrder,
            rule.EffectiveFromDate,
            rule.EffectiveToDate,
            rule.StatusCode,
            rule.IsActive,
            rule.Notes,
            rule.SubmittedAtUtc,
            rule.SubmittedByUserId,
            rule.ApprovedAtUtc,
            rule.ApprovedByUserId,
            rule.ActivatedAtUtc,
            rule.ActivatedByUserId);
}
