<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Http\Requests\StoreContractAPIRequest;
use App\Models\Contract;
use App\Models\Payments;
use App\Models\Tokens;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Redis;
use Firebase\JWT\JWT;

class PaymentsAPI extends Controller
{
    public  $apiDetails='';
    public  $jsonData;

    public function show($contract_id)
    {
        //@ToDo change this code
        $payment = Payments::where('contract_id', $contract_id)->with('user')->get();
        return response()->json([
            "status" => "success",
            "data" =>[
                "payment" => $payment
            ]
        ]);
    }
// wOLD VERSION WITH NO TOKEN ADDED
    /*  public function store(StoreContractAPIRequest $request)
      {
          try {
              $validated = $request->validated();
              $contract= Contract::where('RID',$validated['contract_id'])->with('client')->first();
              $consumer_name = str_replace( ' ', '_', strtoupper($contract->client->name_sh));

              try {
                  $consumerKey = "search_quota:max:".$consumer_name;
                  $keyValue= null;
                  if($keyValue == null) {
                      //@TODO clean returned data api ContractCon
                      //$this->apiDetails = $this->apiContract($consumer_name, $validated['tokens'], $validated['contract_id']);
                      $api_res = $this->apiContractCon($consumer_name, $validated['tokens'], $validated['contract_id']);
                      if ($api_res['status'] === true) {
                          $data = $api_res['body'];
                          $data = json_decode($api_res['body'], true);
                          //$data = json_decode($api_res['body'], true);
                          $this->jsonData = $data;
                          //$this->jsonData = json_encode($data, JSON_PRETTY_PRINT);
                          //Redis::set($consumerKey, $validated['tokens']);
                      }else{
                          return response()->json([
                              'success' => false,
                              'message' => 'Failed to create payment',
                              'error'   => "Error creating/updating consumer",
                          ], 500);
                      }
                  }else{
                     //update
                      $value=$keyValue+$validated['tokens'];
                      //Redis::set($consumerKey, $value);
                  };
              } catch (\Predis\Connection\ConnectionException $redisException) {
                  return response()->json([
                      'success' => false,
                      'message' => 'Failed to update search quota',
                      'error'   => $redisException->getMessage(),
                  ], 500);
              }
              // Attempt to insert the payment
              $payment = Payments::create([
                  'PAYMENT_REF'   => $validated['payment_ref'],
                  'PAYMENT_MODE'  => $validated['payment_mode'],
                  'AMOUNT'        => $validated['amount'],
                  'TOKENS'        => $validated['tokens'],
                  'contract_id'   => $validated['contract_id'],
                  'USER_ID'       => $validated['user_id'],
              ]);

              // Return success JSON response
              return response()->json([
                  'success' => true,
                  'message' => 'Payment created successfully',
                   $this->jsonData,
              ], 201);

          } catch (\Exception $e) {
              // Return failure JSON response
              return response()->json([
                  'success' => false,
                  'message' => 'Failed to create payment',
                  'error'   => $e->getMessage(),
              ], 500);
          }
      }*/

    public function store(StoreContractAPIRequest $request)
    {
        $validated = $request->validated();
        $contract= Contract::where('RID',$validated['contract_id'])->with('client')->first();
        $consumer_name = str_replace( ' ', '_', strtoupper($contract->client->name_sh));
        //$res=Redis::set('name', 'mikee');
        //$checkKey = Redis::get('search_quota:countsse:user23');
        try{
            if (Redis::exists("search_quota:max:".$consumer_name)) {
                $tokens = $validated['tokens'];
                $maxToken = Redis::get("search_quota:max:".$consumer_name);
                // added tokens
                $newMax = $tokens + $maxToken;
                //set tokens
                $tokenRes = Redis::set("search_quota:max:".$consumer_name, $newMax);

                // Attempt to insert the payment
                if($tokenRes){
                    $payment = Payments::create([
                        'PAYMENT_REF'   => $validated['payment_ref'],
                        'PAYMENT_MODE'  => $validated['payment_mode'],
                        'AMOUNT'        => $validated['amount'],
                        'TOKENS'        => $tokens,
                        'contract_id'   => $validated['contract_id'],
                        'USER_ID'       => $validated['user_id'],
                    ]);

                    //update tokens
                    Tokens::where('contract_id', $validated['contract_id'])->update([
                        'total_tokens' => $newMax,
                    ]);

                    // Return success JSON response
                    return response()->json([
                        'success' => true,
                        'message' => 'Payment created successfully',
                    ], 201);
                }
            }else{
                //create new
                $res = $this->apiContract($consumer_name, $validated['tokens'], $validated['contract_id']);
                $payment = Payments::create([
                    'PAYMENT_REF'   => $validated['payment_ref'],
                    'PAYMENT_MODE'  => $validated['payment_mode'],
                    'AMOUNT'        => $validated['amount'],
                    'TOKENS'        => $validated['tokens'],
                    'contract_id'   => $validated['contract_id'],
                    'USER_ID'       => $validated['user_id'],
                ]);
                // Return success JSON response
                return response()->json([
                    'success' => true,
                    'message' => 'Payment created successfully',
                ], 201);
            }
        }catch (\Predis\Connection\ConnectionException $redisException) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update search quota',
                'error'   => $redisException->getMessage(),
            ], 500);
        }
        return response()->json([
            'success' => false,
            'message' => 'Failed to create payment',
        ], 500);
    }

    private function apiContractCon($consumerName, $tokens, $cid)
    {
        $apiGateway = config('services.api_gateway.api_gateway_host').':'.
            config('services.api_gateway.api_gateway_port').'/'.
            config('services.api_gateway.api_gateway_admin').'/consumers';
        $response = Http::withHeaders([
            'X-API-KEY' => env('API_GATEWAY_APIKEY')
        ])->put($apiGateway, [
            "username" => $consumerName,
            "plugins" => [
                "jwt-auth" => [
                    "key" => base64_encode($consumerName),
                    "secret" => $consumerName,
                    "exp" => 172800
                ],
                "limit-count" => [
                    "count" => $tokens,
                    "time_window"=> 30,
                    "rejected_code"=>503,
                    "key"=> base64_encode($consumerName),
                    "policy"=> "redis",
                    "redis_host"=> "redis",
                    "redis_password"=> env('REDIS_PASSWORD'),
                    "redis_port" => (int)env('REDIS_PORT'),
                    "redis_timeout" => 1000,
                    "rejected_msg" =>"You have reached your token limit.",
                    "show_limit_quota_header" => true
                ]
            ]
        ]);
        // var_dump($response->status(), $response->headers(), $response->body());
        //var_dump($response->successful()); //return true or false
        if ($response->successful()) {
            //save it locally
            $tokens = Tokens::create([
                'TOTAL_TOKENS' => $tokens,
                'contract_id' => $cid,
            ]);
            return ['status'=>$response->successful() ,'body'=>$response->body()];
            // return response()->json(["message" => "Consumer created successfully.", "data" => $response->json()]);
        } else {
            //return response()->json(["error" => "Failed to create consumer.", "details" => $response->body()], $response->status());
            return ['status'=>false ,'body'=>''];
        }
    }

    private function apiContract($consumerName, $tokens, $cid)
    {
        $apiGateway = config('services.api_gateway.api_gateway_host').':'.
            config('services.api_gateway.api_gateway_port').'/'.
            config('services.api_gateway.api_gateway_admin').'/consumers';
        $response = Http::withHeaders([
            'X-API-KEY' => env('API_GATEWAY_APIKEY')
        ])->put($apiGateway, [
            "username" => $consumerName,
            "plugins" => [
                "jwt-auth" => [
                    "key" => base64_encode($consumerName),
                    "secret" => $consumerName,
                    "exp" => 172800
                ],
                "search-quota-redis" => [
                    "redis_host" => 'redis',
                    "redis_port" => 6379,
                    "redis_password" => 'password',
                    "default_max_queries" => $tokens
                ]
            ]
        ]);
        if ($response->successful()) {
                 $tokens = Tokens::create([
                     'TOTAL_TOKENS' => $tokens,
                     'contract_id' => $cid,
                 ]);
            return ['status'=>$response->successful() ,'body'=>$response->body()];
            // return response()->json(["message" => "Consumer created successfully.", "data" => $response->json()]);
        } else {
            //return response()->json(["error" => "Failed to create consumer.", "details" => $response->body()], $response->status());
            return ['status'=>false ,'body'=>''];
       }
    }


}
