<?php

namespace App\Services;

use App\Models\Order;
use App\Models\PaymentTransactionLog;
use App\Support\PaymentFailure;
use App\User;

class PaymentTransactionLogger
{
    public static function log(array $data): PaymentTransactionLog
    {
        return PaymentTransactionLog::create([
            'order_id' => $data['order_id'] ?? null,
            'user_id' => $data['user_id'] ?? null,
            'gateway' => $data['gateway'] ?? 'easykash',
            'event' => $data['event'] ?? 'unknown',
            'status' => $data['status'] ?? 'info',
            'currency' => $data['currency'] ?? null,
            'amount' => $data['amount'] ?? null,
            'failure_reason' => $data['failure_reason'] ?? null,
            'http_status' => $data['http_status'] ?? null,
            'request_payload' => isset($data['request_payload'])
                ? (is_string($data['request_payload']) ? $data['request_payload'] : json_encode($data['request_payload'], JSON_UNESCAPED_UNICODE))
                : null,
            'response_body' => $data['response_body'] ?? null,
            'created_at' => time(),
        ]);
    }

    public static function logForOrder(Order $order, string $event, string $status, ?string $reason = null, array $extra = []): PaymentTransactionLog
    {
        if ($reason && in_array($status, ['failed', 'error'], true)) {
            if (in_array($order->status, [Order::$pending, Order::$paying], true)) {
                PaymentFailure::markOrderFailed($order, $reason);
            } elseif (\Illuminate\Support\Facades\Schema::hasColumn('orders', 'payment_failure_reason')) {
                $order->update(['payment_failure_reason' => $reason]);
                PaymentFailure::flash($reason);
            } else {
                PaymentFailure::flash($reason);
            }
        }

        return self::log(array_merge([
            'order_id' => $order->id,
            'user_id' => $order->user_id,
            'currency' => $order->currency ?? null,
            'amount' => $order->total_amount ?? $order->amount,
            'event' => $event,
            'status' => $status,
            'failure_reason' => $reason,
        ], $extra));
    }

    public static function logEasyKashLinkFailed(Order $order, User $user, string $reason, ?int $httpStatus = null, $requestPayload = null, ?string $responseBody = null): void
    {
        self::logForOrder($order, 'easykash_create_link', 'failed', $reason, [
            'user_id' => $user->id,
            'http_status' => $httpStatus,
            'request_payload' => $requestPayload,
            'response_body' => $responseBody,
        ]);
    }
}
