<?php

declare(strict_types=1);

namespace ImovelZapAi\Financial\Presentation\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use ImovelZapAi\Financial\Application\Actions\RecordPaymentAction;
use ImovelZapAi\Financial\Application\Queries\GetDealFinancialStatementQuery;
use ImovelZapAi\Financial\Application\Queries\GetFinancialDashboardQuery;
use ImovelZapAi\Financial\Application\Queries\ListFinancialTransactionsQuery;
use ImovelZapAi\Financial\Domain\Exceptions\FinancialException;
use ImovelZapAi\Tenancy\Support\TenantContext;

final class FinancialController extends Controller
{
    public function index(Request $request, ListFinancialTransactionsQuery $query): JsonResponse
    {
        return response()->json($query->execute((string) TenantContext::id(), [
            'deal_id' => $request->query('deal_id'),
            'status' => $request->query('status'),
            'search' => $request->query('search'),
            'per_page' => (int) $request->query('per_page', 20),
        ]));
    }

    public function dashboard(Request $request, GetFinancialDashboardQuery $query): JsonResponse
    {
        return response()->json($query->execute((string) TenantContext::id(), [
            'from' => $request->query('from'),
            'to' => $request->query('to'),
        ]));
    }

    public function show(string $dealId, GetDealFinancialStatementQuery $query): JsonResponse
    {
        try {
            return response()->json($query->execute((string) TenantContext::id(), $dealId));
        } catch (FinancialException $e) {
            return response()->json(['message' => $e->getMessage()], 404);
        }
    }

    public function storePayment(string $dealId, Request $request, RecordPaymentAction $action): JsonResponse
    {
        $data = $request->validate([
            'amount' => ['required', 'numeric', 'min:0.01'],
            'method' => ['required', 'string'],
            'schedule_id' => ['nullable', 'uuid'],
            'transaction_id' => ['nullable', 'uuid'],
            'reference' => ['nullable', 'string'],
            'generate_receipt' => ['nullable', 'boolean'],
        ]);
        $data['deal_id'] = $dealId;

        try {
            $payment = $action->execute((string) TenantContext::id(), $request->user(), $data);
        } catch (FinancialException $e) {
            return response()->json(['message' => $e->getMessage()], 422);
        }

        return response()->json($payment->load('receipt'), 201);
    }

    public function commissions(string $dealId, GetDealFinancialStatementQuery $query): JsonResponse
    {
        try {
            $statement = $query->execute((string) TenantContext::id(), $dealId);
        } catch (FinancialException $e) {
            return response()->json(['message' => $e->getMessage()], 404);
        }

        return response()->json($statement['commissions']);
    }

    public function transfers(string $dealId, GetDealFinancialStatementQuery $query): JsonResponse
    {
        try {
            $statement = $query->execute((string) TenantContext::id(), $dealId);
        } catch (FinancialException $e) {
            return response()->json(['message' => $e->getMessage()], 404);
        }

        return response()->json($statement['transfers']);
    }

    public function receipts(string $dealId, GetDealFinancialStatementQuery $query): JsonResponse
    {
        try {
            $statement = $query->execute((string) TenantContext::id(), $dealId);
        } catch (FinancialException $e) {
            return response()->json(['message' => $e->getMessage()], 404);
        }

        return response()->json($statement['receipts']);
    }
}
