<?php

declare(strict_types=1);

namespace App\DTOs;

use App\ValueObjects\Money;
use Carbon\Carbon;
use InvalidArgumentException;

/**
 * DTO para operación de Renovación de crédito.
 *
 * Renovación: Nuevo crédito que PAGA TOTALMENTE el anterior.
 * La diferencia entre nuevo monto y saldo pendiente se desembolsa al cliente.
 * Requiere que el cliente haya realizado pagos previos.
 */
readonly class RenewCreditData extends CreditOperationData
{
    public Money $newCreditAmount;

    public ?string $newInterestRate;

    public function __construct(
        int $creditId,
        int $newInstallmentsCount,
        Money|float|string $newCreditAmount,
        ?string $newInterestRate = null,
        ?string $periodicity = null,
        ?Carbon $startDate = null,
        ?Carbon $firstDueDateOverride = null,
        ?int $dueDay1 = null,
        ?int $dueDay2 = null,
        ?string $reason = null,
    ) {
        $this->newCreditAmount = $newCreditAmount instanceof Money
            ? $newCreditAmount
            : Money::of($newCreditAmount);

        if ($this->newCreditAmount->lessThanOrEqual(0)) {
            throw new InvalidArgumentException(
                'El monto del nuevo crédito debe ser mayor a cero.'
            );
        }

        $this->newInterestRate = $newInterestRate;

        parent::__construct(
            creditId: $creditId,
            newInstallmentsCount: $newInstallmentsCount,
            periodicity: $periodicity,
            startDate: $startDate ?? Carbon::today(),
            firstDueDateOverride: $firstDueDateOverride,
            dueDay1: $dueDay1,
            dueDay2: $dueDay2,
            reason: $reason,
        );
    }

    public function operationType(): string
    {
        return 'renewal';
    }

    public function toArray(): array
    {
        return array_merge(parent::toArray(), [
            'new_credit_amount' => $this->newCreditAmount->value(),
            'new_interest_rate' => $this->newInterestRate,
        ]);
    }
}
