<?php

namespace App\Http\Controllers;

use App\Models\User;
use App\Models\Status;
use App\Models\SbiPayment;
use App\Models\ServiceName;
use App\Models\Transaction;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
use App\Services\BOBEncryptionService;



class BobPaymentController extends Controller
{
    protected $encryptionService;
    protected $key;
    protected $working_key;
    protected $access_code;
    protected $merchantId;
    const PAYMENT_STATUS_SUCCESSFUL = 1;

    public function __construct(BOBEncryptionService $encryptionService)
    {
        $this->encryptionService = $encryptionService;
        $this->key = config('payment.key');
        $this->merchantId = config('payment.merchant_id');
        $this->working_key = config('payment.working_key');
        $this->access_code = config('payment.access_code');


    }


//    public function initPaymentRequest($id)
//     {
//         return view('payment.create',compact('id'));
//     }

    public function redirectPayment(Request $request)
    {

        $requestServiceId = $request->serviceid;
        $tableId = $request->id;
        $authUser = auth()->user();
        $status = Status::where('service_id', $requestServiceId)->where('table_id', $tableId)->first();
        // $table_id = Status::where('service_id', $requestServiceId)->where('table_id', $tableId)->first();
        $serviceName = ServiceName::select('model', 'service_id', 'service_name')->where('service_id', $requestServiceId)->get();

        $items = collect();
        $targetServices = $serviceName;
        foreach ($targetServices as $serviceId => $modelClass) {
            if ($modelClass) {
                $modelData = $modelClass->model::with(['status' => function ($query) use ($serviceId) {
                    $query->where('service_id', $serviceId);
                }])
                ->where('user_id', Auth::id())
                ->get();
                $items = $items->merge($modelData);
            }
        }
        $request_data = $request->all();
        $amount = $status->fees_amount ?? $request->amount;
        $request_data['amount'] = $amount;
        $data = $items[0];
        $transaction = new Transaction();
        $transaction = $transaction->create([
                            'service_id' => $requestServiceId,
                            'table_id' => $tableId,
                            'user_id' => $authUser->id,
                            'amount' => $amount ,
                            'orderno' => $request->order_id,
                            'status' => 0,
                            'ip' => request()->ip(),
                        ]);

        $working_key = config('payment.working_key');
        $access_code = config('payment.access_code');

        $merchant_data = '';
        foreach ($request_data as $keys => $value) {
            $merchant_data .= $keys . '=' . $value . '&';
        }

        $merchant_data = rtrim($merchant_data, '&');
        $encrypted_data = $this->encryptionService->encrypt($merchant_data, $working_key);

        $serviceId = $request->input('serviceid');

        $id = $request->input('id');

        return view('payment.redirect', [
            'encRequest' => $encrypted_data,
            'accessCode' => $access_code,
            'serviceId' => $serviceId,
            'id' => $id
        ]);
    }


  public function successResponse(Request $request)
    {

        if (!$request->filled('encResp')) {
            return response("Please try again...", 400);
        }

        $encrypted = $request->input('encResp');
        $decryptedString = $this->encryptionService->decrypt($encrypted, $this->key);

        $data = [];
        $pairs = explode('&', $decryptedString);
        foreach ($pairs as $pair) {
            if (strpos($pair, '=') !== false) {
                [$keys, $value] = explode('=', $pair, 2);
                $data[$keys] = $value;
                Log::info('Payment Response Pair', [
                    'key' => $keys,
                    'value' => $value
                ]);
            }
        }


        try {
            DB::beginTransaction();

            if (!isset($data['order_id'])) {
                throw new \Exception("Order ID is missing from the response.");
            }
            $transaction = Transaction::where('orderno', $data['order_id'])->first();

            if (!$transaction) {
                Log::error("Transaction not found for order ID: " . $data['order_id']);
                DB::rollBack();
                return response("Transaction not found for this order number.", 404);
            }

            $user = User::find($transaction->user_id);
                if ($user) {
                    Auth::login($user);
                }

            if($data['order_status'] == "Success"){
                $sbiPayment = new SbiPayment();
                $sbiPayment->orderno = $transaction->orderno;
                $sbiPayment->amount = $data['amount'] ?? null;
                $sbiPayment->status = self::PAYMENT_STATUS_SUCCESSFUL;
                $sbiPayment->service_id = $transaction->service_id;
                $sbiPayment->table_id = $transaction->table_id;
                $sbiPayment->save();

                $service = DB::table('service_names')->where('service_id', $transaction->service_id)->first();

                if (!$service) {
                    throw new \Exception("Invalid service configuration.");
                }

                $modelClass = $service->model;

                $targetRecord = $modelClass::find($transaction->table_id);

                if (!$targetRecord) {
                    throw new \Exception("Associated record not found.");
                }

                $targetRecord->is_payment_paid = true;
                $targetRecord->payment_date = Carbon::now()->toDateString();
                $targetRecord->save();


                DB::commit();
                return view('payment.success', [
                    'message' => 'Payment successful!',
                    'responseData' => $data
                ]);
            }else{
                DB::commit();
                return view('payment.failed');
            }
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error("Payment update failure: " . $e->getMessage());
            return response("Something went wrong while processing your payment. Please contact support.", 500);
        }
    }

    public function failedResponse(Request $request)
    {
        if (!$request->filled('encResp')) {
            return response("Please try again...", 400);
        }

        $encrypted = $request->input('encResp');
        $decryptedString = $this->encryptionService->decrypt($encrypted, $this->key);

        $data = [];
        $pairs = explode('&', $decryptedString);
        foreach ($pairs as $pair) {
            if (strpos($pair, '=') !== false) {
                [$keys, $value] = explode('=', $pair, 2);
                $data[$keys] = $value;
                Log::info('Payment Response Pair', [
                    'key' => $keys,
                    'value' => $value
                ]);
            }
        }
         $transaction = Transaction::where('orderno', $data['order_id'])->first();

          $user = User::find($transaction->user_id);
                if ($user) {
                    Auth::login($user);
                }
        return view('payment.failed');
    }



   public function cancelResponse(Request $request)
{
     if (!$request->filled('encResp')) {
            return response("Please try again...", 400);
        }

        $encrypted = $request->input('encResp');
        $decryptedString = $this->encryptionService->decrypt($encrypted, $this->key);

        $data = [];
        $pairs = explode('&', $decryptedString);
        foreach ($pairs as $pair) {
            if (strpos($pair, '=') !== false) {
                [$keys, $value] = explode('=', $pair, 2);
                $data[$keys] = $value;
                Log::info('Payment Response Pair', [
                    'key' => $keys,
                    'value' => $value
                ]);
            }
        }
         $transaction = Transaction::where('orderno', $data['order_id'])->first();

          $user = User::find($transaction->user_id);
                if ($user) {
                    Auth::login($user);
                }


    return view('payment.cancel');
}
}






