<?php

declare(strict_types=1);

namespace ImovelZapAi\Financial\Application\Queries;

use ImovelZapAi\Financial\Domain\Exceptions\FinancialException;
use ImovelZapAi\Financial\Infrastructure\Persistence\Eloquent\FinancialCommissionModel;
use ImovelZapAi\Financial\Infrastructure\Persistence\Eloquent\FinancialPaymentModel;
use ImovelZapAi\Financial\Infrastructure\Persistence\Eloquent\FinancialReceiptModel;
use ImovelZapAi\Financial\Infrastructure\Persistence\Eloquent\FinancialTransactionModel;
use ImovelZapAi\Financial\Infrastructure\Persistence\Eloquent\FinancialTransferModel;
use ImovelZapAi\Sales\Infrastructure\Persistence\Eloquent\DealModel;

final class GetDealFinancialStatementQuery
{
    /**
     * @return array<string, mixed>
     */
    public function execute(string $tenantId, string $dealId): array
    {
        $deal = DealModel::query()
            ->where('tenant_id', $tenantId)
            ->with(['contact', 'responsible', 'property'])
            ->find($dealId);

        if ($deal === null) {
            throw FinancialException::notFound('Oportunidade');
        }

        $transactions = FinancialTransactionModel::query()
            ->where('tenant_id', $tenantId)
            ->where('deal_id', $dealId)
            ->with(['schedules', 'payments'])
            ->orderBy('created_at')
            ->get();

        $payments = FinancialPaymentModel::query()
            ->where('tenant_id', $tenantId)
            ->where('deal_id', $dealId)
            ->with(['receipt', 'schedule', 'transaction'])
            ->orderBy('paid_at')
            ->get();

        $commissions = FinancialCommissionModel::query()
            ->where('tenant_id', $tenantId)
            ->where('deal_id', $dealId)
            ->with(['splits.beneficiaryUser', 'rule'])
            ->orderBy('calculated_at')
            ->get();

        $transfers = FinancialTransferModel::query()
            ->where('tenant_id', $tenantId)
            ->where('deal_id', $dealId)
            ->with(['commissionSplit', 'payeeUser'])
            ->orderBy('created_at')
            ->get();

        $receipts = FinancialReceiptModel::query()
            ->where('tenant_id', $tenantId)
            ->where('deal_id', $dealId)
            ->with('payment')
            ->orderBy('issued_at')
            ->get();

        $timeline = collect()
            ->merge($transactions->map(fn ($t) => [
                'kind' => 'transaction',
                'at' => $t->created_at,
                'item' => $t,
            ]))
            ->merge($payments->map(fn ($p) => [
                'kind' => 'payment',
                'at' => $p->paid_at,
                'item' => $p,
            ]))
            ->merge($commissions->map(fn ($c) => [
                'kind' => 'commission',
                'at' => $c->calculated_at ?? $c->created_at,
                'item' => $c,
            ]))
            ->merge($transfers->map(fn ($t) => [
                'kind' => 'transfer',
                'at' => $t->paid_at ?? $t->created_at,
                'item' => $t,
            ]))
            ->merge($receipts->map(fn ($r) => [
                'kind' => 'receipt',
                'at' => $r->issued_at,
                'item' => $r,
            ]))
            ->sortBy('at')
            ->values();

        $totalNegotiated = (float) ($deal->amount ?? 0);
        $totalReceived = (float) $payments->sum('amount');
        $totalCommission = (float) $commissions->sum('total_amount');
        $pendingTransfers = (float) $transfers
            ->where('status', \ImovelZapAi\Financial\Domain\Enums\TransferStatus::Pending)
            ->sum('amount');

        return [
            'deal' => $deal,
            'summary' => [
                'negotiated' => $totalNegotiated,
                'received' => $totalReceived,
                'pending' => max(0, $totalNegotiated - $totalReceived),
                'commission_total' => $totalCommission,
                'pending_transfers' => $pendingTransfers,
            ],
            'transactions' => $transactions,
            'payments' => $payments,
            'commissions' => $commissions,
            'transfers' => $transfers,
            'receipts' => $receipts,
            'timeline' => $timeline,
        ];
    }
}
