<?php

declare(strict_types=1);

namespace App\Providers;

use App\Services\CreditCalculator;
use App\Services\CreditManager;
use App\Services\Credits\CreditOperationOrchestrator;
use App\Services\Credits\CreditOperationValidator;
use App\Services\Credits\Operations\ExtendCreditOperation;
use App\Services\Credits\Operations\RefinanceCreditOperation;
use App\Services\Credits\Operations\RenewCreditOperation;
use App\Services\Credits\Operations\RestructureCreditOperation;
use App\Services\FinanceAutoLogger;
use Illuminate\Support\ServiceProvider;

/**
 * Service Provider para operaciones estructurales de crédito.
 *
 * Registra los servicios necesarios para:
 * - Extensión
 * - Refinanciación
 * - Reestructuración
 * - Renovación
 */
class CreditOperationServiceProvider extends ServiceProvider
{
    /**
     * Servicios que deben ser singletons.
     */
    public array $singletons = [
        CreditOperationValidator::class,
        CreditOperationOrchestrator::class,
    ];

    /**
     * Register services.
     */
    public function register(): void
    {
        // Registrar el validador
        $this->app->singleton(CreditOperationValidator::class, function ($app) {
            return new CreditOperationValidator(
                creditManager: $app->make(CreditManager::class),
            );
        });

        // Registrar operaciones individuales
        $this->app->bind(ExtendCreditOperation::class, function ($app) {
            return new ExtendCreditOperation(
                creditManager: $app->make(CreditManager::class),
                creditCalculator: $app->make(CreditCalculator::class),
                financeAutoLogger: $app->make(FinanceAutoLogger::class),
            );
        });

        $this->app->bind(RefinanceCreditOperation::class, function ($app) {
            return new RefinanceCreditOperation(
                creditManager: $app->make(CreditManager::class),
                creditCalculator: $app->make(CreditCalculator::class),
                financeAutoLogger: $app->make(FinanceAutoLogger::class),
            );
        });

        $this->app->bind(RestructureCreditOperation::class, function ($app) {
            return new RestructureCreditOperation(
                creditManager: $app->make(CreditManager::class),
                creditCalculator: $app->make(CreditCalculator::class),
                financeAutoLogger: $app->make(FinanceAutoLogger::class),
            );
        });

        $this->app->bind(RenewCreditOperation::class, function ($app) {
            return new RenewCreditOperation(
                creditManager: $app->make(CreditManager::class),
                creditCalculator: $app->make(CreditCalculator::class),
                financeAutoLogger: $app->make(FinanceAutoLogger::class),
            );
        });

        // Registrar el orquestador principal
        $this->app->singleton(CreditOperationOrchestrator::class, function ($app) {
            return new CreditOperationOrchestrator(
                validator: $app->make(CreditOperationValidator::class),
                extendOperation: $app->make(ExtendCreditOperation::class),
                refinanceOperation: $app->make(RefinanceCreditOperation::class),
                restructureOperation: $app->make(RestructureCreditOperation::class),
                renewOperation: $app->make(RenewCreditOperation::class),
            );
        });
    }

    /**
     * Bootstrap services.
     */
    public function boot(): void
    {
        //
    }
}
