<?php
declare(strict_types=1);

namespace App\Modules\Rentals\Services;

use App\Core\EventBus;
use App\Core\Logger;
use App\Modules\Rentals\Models\RentalContract;

final class RentalDepositService
{
    /**
     * Record deposit collection for a contract.
     */
    public static function collectDeposit(int $contractId, int $paymentId): void
    {
        $contract = RentalContract::find($contractId);
        if (!$contract) {
            throw new \RuntimeException('Contract not found');
        }

        $contract->update([
            'deposit_status'     => 'collected',
            'deposit_payment_id' => $paymentId,
        ]);

        EventBus::dispatch('rental.deposit_collected', [
            'contract_id' => $contractId,
            'payment_id'  => $paymentId,
        ]);

        Logger::info('Rental deposit collected', ['contract_id' => $contractId, 'payment_id' => $paymentId]);
    }

    /**
     * Request a deposit refund.
     *
     * Validates that the technical report has been submitted.
     * Sets deposit_status to 'partially_refunded' or 'refunded' depending on context.
     */
    public static function requestRefund(int $contractId): void
    {
        $contract = RentalContract::find($contractId);
        if (!$contract) {
            throw new \RuntimeException('Contract not found');
        }

        $techReport = (int) ($contract->technical_report_submitted ?? $contract['technical_report_submitted'] ?? 0);
        if (!$techReport) {
            throw new \RuntimeException('Technical report must be submitted before requesting deposit refund');
        }

        $contract->update([
            'deposit_status' => 'partially_refunded',
        ]);

        EventBus::dispatch('rental.deposit_refund_requested', [
            'contract_id' => $contractId,
        ]);

        Logger::info('Rental deposit refund requested', ['contract_id' => $contractId]);
    }

    /**
     * Process a deposit refund.
     */
    public static function processRefund(int $contractId, int $paymentId): void
    {
        $contract = RentalContract::find($contractId);
        if (!$contract) {
            throw new \RuntimeException('Contract not found');
        }

        $contract->update([
            'deposit_status' => 'refunded',
        ]);

        EventBus::dispatch('rental.deposit_refunded', [
            'contract_id' => $contractId,
            'payment_id'  => $paymentId,
        ]);

        Logger::info('Rental deposit refunded', ['contract_id' => $contractId, 'payment_id' => $paymentId]);
    }
}
