<?php

namespace App\Http\Middleware;

use App\ConsumerAPIRequests;
use App\JWTAccess;
use App\Logs;
use App\Slack;
use Closure;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\VendorApiCredentials;
use Hashids\Hashids;
use App\ConsumerApplicationElement;


class JwtEMICheckoutMiddleware extends JWTAccess
{
    protected $errorCode = [
        'Wrong number of segments' => 401,
        'Signature verification failed' => 402,
        'Expired token' => 408
    ];

    private $jwt_path = ['consumer/get-payments','api/get-agreement', 'api/run-auto-decision', 'api/sign-agreement', 'api/electricity-bill-details', 'api/employment-verification', 'api/ckyc/fetch', 'api/get-account-aggregator-link', 'consumer/check-loan-eligibility', 'consumer/pay-now', 'consumer/generate-otp', 'consumer/verify-otp'];
    private $basic_path = ['consumer/get-payments', 'api/get-agreement', 'api/run-auto-decision', 'api/sign-agreement', 'api/electricity-bill-details', 'api/employment-verification', 'api/ckyc/fetch', 'api/get-account-aggregator-link', 'consumer/check-loan-eligibility', 'consumer/pay-now', 'consumer/generate-otp', 'consumer/verify-otp'];

    private $error = [
        'MissingToken' => ['error' => ['code' => 'CF10034', 'message' => 'Unauthorized access'], 'httpCode' => 401],
        'InvalidRequest' => ['error' => ['code' => 'CF10035', 'message' => 'Unauthorized access'], 'httpCode' => 401],
        'InvalidToken' => ['error' => ['code' => 'CF10036', 'message' => 'Unauthorized access'], 'httpCode' => 401]
    ];
    /**
     * @var Request
     */
    private $request;

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {

        try {
            if (in_array($request->route()->uri(), $this->jwt_path) and in_array($request->route()->uri(), $this->basic_path))
            {
                if (!$request->hasHeader('Authorization') and !$request->hasHeader('X-Client-Id') and !$request->hasHeader('X-Client-Secret')){
                    return response()->json(['status' => "FAIL", 'error' => $this->error['MissingToken']['error']], $this->error['MissingToken']['httpCode']);
                }
                if ($request->hasHeader('Authorization')) {
                    // $this->secret = _env('JWT_EMI_CHECKOUT_KEY');
                    $requestBody = $request->get('application_id');
                    $app_id = isset($requestBody) ? $requestBody : $request->query('application_id');
                    $hashids = new Hashids('Creditfair by CS', 20);
                    $application_id = $hashids->decode($app_id);
                    if($application_id && !$request->header('X-CF-CUSTOMER-APP')) {
                        $consumerAppEle = ConsumerApplicationElement::where('application_id', $application_id)->first(['vendor_id']);
                        $vendorAPI = VendorAPICredentials::where('vendor_id', $consumerAppEle->vendor_id)->first(['key']);
                        $this->secret = $vendorAPI->key;
                    }else{
                        $this->secret = _env('CUSTOMER_APP_SALT');
                    }

                    if($this->verifyAccessTokenV1($request)) {
                        $this->request = $request;
                        $this->request->request->add(['user' => $this->user, 'secret' => $this->secret]);
                        return $next($this->request);
                    }
                    else{
                        return response()->json(['status' => "FAIL", 'error' => $this->error['MissingToken']['error'], "statusCode" => "CF401"], $this->error['MissingToken']['httpCode']);
                    }
                }
                if ($request->hasHeader('X-Client-Id') and $request->hasHeader('X-Client-Secret')) {
                        $requestIP = request()->ip();
                        $vendor = VendorAPICredentials::where('key', $request->header('x-client-id'))->where('secret', $request->header('x-client-secret'))->first();
                        $ipList = explode(",", $vendor->ips);
                        array_push($ipList, $requestIP);
                        if (isset($vendor) and (in_array($requestIP, $ipList))) {
                            return $next($request);
                        }
                        else{
                            return response()->json(['status' => "FAIL", 'error' => $this->error['InvalidRequest']['error']], $this->error['InvalidRequest']['httpCode']);
                        }
                }
                else {
                    return response()->json(['status' => "FAIL", 'error' => $this->error['InvalidRequest']['error']], $this->error['MissingToken']['httpCode']);
                }
            }

        } catch (Exception $e) {
            // return $this->initErrors(['message' => $e->getMessage(), 'code' => $this->errorCode[$e->getMessage()], 'type' => 'CF_EXCEPTION','cf_error_code' => $e->getLine()]);
            return response()->json(['status' => "FAIL", "statusCode" => "CF401", 'error' => $this->error['InvalidToken']['error'], "error_message" => $e->getMessage()], $this->error['MissingToken']['httpCode']);
        }
    }
}