<?php

declare(strict_types=1);

namespace App\Modules\Ledger\Application;

use App\Modules\Ledger\Domain\LedgerEntry;

class LedgerService
{
    /**
     * @return array<int, LedgerEntry>
     */
    public function recentEntries(string $tenantId, string $memberId): array
    {
        return [
            new LedgerEntry(
                id: 'ledger-demo-1',
                tenantId: $tenantId,
                memberId: $memberId,
                entryType: 'payment',
                amount: 10.00,
                bookedAt: '2026-03-20 09:00:00',
                referenceType: 'payment',
                referenceId: 'payment-demo-1'
            ),
            new LedgerEntry(
                id: 'ledger-demo-2',
                tenantId: $tenantId,
                memberId: $memberId,
                entryType: 'consumption',
                amount: -2.50,
                bookedAt: '2026-03-20 10:30:00',
                referenceType: 'coffee_entry',
                referenceId: 'coffee-demo-1'
            ),
            new LedgerEntry(
                id: 'ledger-demo-3',
                tenantId: $tenantId,
                memberId: $memberId,
                entryType: 'adjustment',
                amount: 0.50,
                bookedAt: '2026-03-21 08:00:00',
                referenceType: 'manual-correction',
                referenceId: 'correction-demo-1'
            ),
        ];
    }

    public function balanceForMember(string $tenantId, string $memberId): float
    {
        $balance = 0.0;

        foreach ($this->recentEntries($tenantId, $memberId) as $entry) {
            $balance += $entry->amount();
        }

        return $balance;
    }

    /**
     * @return array<string, mixed>
     */
    public function accountingOverview(string $tenantId, string $memberId): array
    {
        $entries = $this->recentEntries($tenantId, $memberId);

        return [
            'entries' => array_map(static fn (LedgerEntry $entry): array => $entry->toArray(), $entries),
            'summary' => [
                'balance' => $this->balanceForMember($tenantId, $memberId),
                'payments' => count(array_filter($entries, static fn (LedgerEntry $entry): bool => $entry->isPayment())),
                'consumptions' => count(array_filter($entries, static fn (LedgerEntry $entry): bool => $entry->isConsumption())),
                'corrections' => count(array_filter($entries, static fn (LedgerEntry $entry): bool => $entry->isCorrection())),
                'strike_entries' => count(array_filter($entries, static fn (LedgerEntry $entry): bool => $entry->isStrikeEntry())),
                'cancelable_payments' => count(array_filter($entries, static fn (LedgerEntry $entry): bool => $entry->canBeCancelledByResponsible())),
            ],
            'correction_policy' => [
                'payments' => 'Einzahlungen werden per Storno korrigiert und nur durch den Verantwortlichen freigegeben.',
                'coffee_entries' => 'Stricheintraege bleiben loeschbar, wenn der Verantwortliche das veranlasst.',
                'audit' => 'Jede Korrektur braucht einen nachvollziehbaren Ursprungseintrag und bleibt auditiert sichtbar.',
            ],
        ];
    }
}
