<?php

namespace App\Services\Payments;

use App\Enums\TransactionStatus;
use App\Models\Transaction;
use Illuminate\Support\Str;

class TransactionService
{
    public function createPending(string $gateway, float $amount, string $currency, ?int $userId, array $metadata = []): Transaction
    {
        return Transaction::create([
            'user_id' => $userId,
            'gateway' => $gateway,
            'transaction_id' => null,
            'amount' => $amount,
            'currency' => strtoupper($currency),
            'status' => TransactionStatus::Pending->value,
            'payment_method' => null,
            'response_json' => null,
            'idempotency_key' => (string) Str::uuid(),
            'metadata' => $metadata,
        ]);
    }

    public function update(Transaction $transaction, array $attributes): Transaction
    {
        $transaction->update($attributes);

        return $transaction->fresh();
    }

    public function markSucceeded(Transaction $transaction, string $providerTransactionId, array $response, ?string $paymentMethod = null): Transaction
    {
        $transaction->update([
            'transaction_id' => $providerTransactionId,
            'status' => TransactionStatus::Succeeded->value,
            'payment_method' => $paymentMethod,
            'response_json' => $response,
        ]);

        return $transaction->fresh();
    }

    public function markFailed(Transaction $transaction, array $response, ?string $reason = null): Transaction
    {
        $transaction->update([
            'status' => TransactionStatus::Failed->value,
            'response_json' => array_merge($transaction->response_json ?? [], $response, array_filter(['failure_reason' => $reason])),
        ]);

        return $transaction->fresh();
    }

    public function markProcessing(Transaction $transaction, string $providerTransactionId, array $response): Transaction
    {
        $transaction->update([
            'transaction_id' => $providerTransactionId,
            'status' => TransactionStatus::Processing->value,
            'response_json' => $response,
        ]);

        return $transaction->fresh();
    }
}
