<?php

namespace App\Services;

use App\Http\Controllers\MailController;
use App\Models\Cars;
use App\Models\Orders;
use App\Models\PendingPayments;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class PaymentService
{
    const PAYMENT_STATUS_SUCCESSFUL = ['finished', 'partially_paid'];

    protected $mailer;

    public function __construct()
    {
        $this->mailer = new MailController;
    }

    public function confirmPayment(): void
    {
        $apiKey = config("app.payment_key");

        $pendingTx = PendingPayments::all();

        $batchSize = 5;
        $sleepDuration = 5;

        foreach ($pendingTx->chunk($batchSize) as $batch) {
            foreach ($batch as $tx) {
                $user = User::find($tx->user_id);
                if (!$user) {
                    Log::warning('User not found', ['user_id' => $tx->user_id, 'payment_id' => $tx->payment_id]);
                    continue;
                }

                $endPoint = "https://api.nowpayments.io/v1/payment/{$tx->payment_id}";

                try {
                    $response = Http::withHeaders(['x-api-key' => $apiKey])->get($endPoint);

                    if ($response->successful()) {
                        $responseData = $response->json();
                        if (in_array($responseData['payment_status'], self::PAYMENT_STATUS_SUCCESSFUL)) {
                            // Log::info($responseData);
                            $this->handleSuccessfulPayment($user, $tx->car_id, $tx->duration, $tx->monthly_plan, $tx->car_price, $responseData);
                            $tx->delete();
                        }
                    } else {
                        Log::error('Payment API call failed', [
                            'status_code' => $response->status(),
                            'payment_id' => $tx->payment_id,
                        ]);
                    }
                } catch (\Exception $e) {
                    Log::error('Error processing transaction', [
                        'payment_id' => $tx->payment_id,
                        'error' => $e->getMessage(),
                    ]);
                }
            }

            sleep($sleepDuration);
        }
    }

    protected function handleSuccessfulPayment($user, $car_id, $duration, $plan, $car_price, $response): void
    {
        $paymentDate = now()->format('d-m-Y'); // Use today's date for the payment
        $paymentAmount = intval($response['pay_amount']); // Extract the paid amount

        // If the order was already existing, update it instead
        DB::transaction(function() use ($user, $car_id, $duration, $plan, $car_price, $paymentDate, $paymentAmount) {

            $order = Orders::where('car_id', $car_id)->first();

            if(!$order) {
                Orders::create([
                    'car_id' => $car_id,
                    'user_id' => $user->id,
                    'car_price' => $car_price ?? 0, // Store car price if available
                    'amount_paid' => $paymentAmount, // Initial amount paid
                    'duration' => $duration, // duration of payment
                    'monthly_plan' => $plan, // monthly installment amount
                    'payment_history' => [$paymentDate => $paymentAmount], // Store initial history
                ]);

            } else {
                // Get the current payment history or initialize it properly
                $paymentHistory = $order->payment_history ?? [];

                // Append the new payment entry
                $paymentHistory[$paymentDate] = $paymentAmount;

                // Update order details
                $order->amount_paid += $paymentAmount;
                $order->payment_history = $paymentHistory;

                // Save the updated order
                $order->save();
            }
        });

        // Send an email notification about the payment
        try {
            $this->mailer->finance($user, 'USDT', $car_price, $paymentAmount, $response['payment_id']);
        } catch (\Exception $e) {
            Log::error('Failed to send funding email', ['error' => $e->getMessage()]);
        }
    }

}
