<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use DateTime;
use DateTimeZone;
use App\Models\EasypaisaUser;
use App\Models\CustomerSavingsMaster;
use App\Models\InvestmentLedgerSaving;
use App\Models\DailyReturn;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Cache;
use App\Services\CryptoService;
use App\Services\EasypaisaCryptoService;
use App\Models\KiborRate;
use Carbon\Carbon;
use App\Models\Slab;



class EasypaisaController extends Controller
{
    private string $clientId;
    private string $apiKey;
    private string $baseUrl;
    private string $appId;
    private string $merchantId;
    private string $accessToken;
    private $privateKey;
    private $publicKey;

    public function __construct()
    {
        $this->clientId     = config('easypaisa.client_id');
        $this->apiKey       = config('easypaisa.api_key');
        $this->baseUrl      = config('easypaisa.base_url');
        $this->appId        = config('easypaisa.app_id');
        $this->merchantId   = config('easypaisa.merchant_id');
        $this->accessToken  = config('easypaisa.access_token');
        $this->privateKey   = openssl_pkey_get_private(config('easypaisa.private_key'));

        if (!$this->privateKey) {
            Log::error("EasypaisaController: Invalid private key loaded.");
        }
    }


    private function generateSignature($data)
    {
        $privateKey = openssl_pkey_get_private($this->privateKey);
        if (!$privateKey) {
            Log::error("Error loading private key.");
            return response()->json(['error' => 'Invalid private key'], 500);
        }

        openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA256);
        openssl_free_key($privateKey);

        return urlencode(base64_encode($signature));
    }

    private function sendRequest($endpoint, $headers, $data)
    {

          // Log the request data
        $url = $this->baseUrl . $endpoint;

        $response = Http::withHeaders([
            "Request-Time"  => $headers['Request-Time'],
            "Client-Id"     => $headers['Client-Id'],
            "Signature"     => $headers['Signature'],
            "Access-Token"  => $headers['Access-Token'],
            "Content-Type"  => "application/json"
        ])->post($url, $data);

        return $response->json();
    }

 


        private function sendRequesAuthCode($endpoint, $headers, $data)
    {
        $url = $this->baseUrl . $endpoint;
    
        $response = Http::withHeaders([
            "Content-Type"  => "application/json",
            "Client-Id"     => $headers['Client-Id'],
            "Request-Time"  => $headers['Request-Time'],
            "Access-Token"  => $headers['Access-Token'],
            "Signature"     => $headers['Signature']
        ])->post($url, $data);
    
        \Log::info('Response Body:', $response->json());
        \Log::info('Response Headers:', $response->headers());
    
        return [
            'body'    => $response->json(),
            'headers' => $response->headers(),
            'status'  => $response->status(),
        ];
    }



    public function getAuthCode(Request $request, CryptoService $crypto)
{
    $date = new DateTime('now', new DateTimeZone('Asia/Karachi'));
    $requestTime = $date->format("Y-m-d\TH:i:s.vP");

    $request->validate([
        'authCode' => 'required|string',
    ]);

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

    $params = [
        'Request-Time' => $requestTime,
        'Client-Id'    => $this->clientId,
        'Access-Token' => $this->accessToken
    ];

    $data = [
        'authCode' => $authCode
    ];

    $signatureString = "POST /v1/users/inquireUserInfo\n" .
        "{$params['Client-Id']}.{$params['Request-Time']}.{$this->accessToken}." . json_encode($data);

    $signature = $this->generateSignature($signatureString);
    $params['Signature'] = "algorithm=RSA2048, keyVersion=1, signature=$signature";

    try {
       $responseData = $this->sendRequesAuthCode('/v1/users/inquireUserInfo', $params, $data);

     \Log::info('EasypaisaController: Response Body', ['response_body' => $responseData['body']]);
            
            $response = $responseData['body']; // ✅ Fixed variable name
            $headers  = $responseData['headers'];
            $status   = $responseData['status'];
            
            $encryptedCnic = $response['userInfo']['userCnic'] ?? null;
            $decryptedCnic = null;
        
            if (!empty($headers['encrypt'][0]) && $encryptedCnic) {
                $encryptHeader = $headers['encrypt'][0];
        
                $cryptoService = new EasypaisaCryptoService();
                $decryptedCnic = $cryptoService->decryptCnic($encryptHeader, $encryptedCnic);
        
                if ($decryptedCnic) {
                    Log::info('EasypaisaController: CNIC decrypted successfully.', [
                        'decrypted_cnic_preview' => substr($decryptedCnic, 0, 5) . '******'
                    ]);
                } else {
                    Log::error('EasypaisaController: Failed to decrypt CNIC.');
                }
            } else {
                Log::warning('EasypaisaController: Missing "encrypt" header or encrypted CNIC is empty.', [
                    'encrypt_header_present' => !empty($headers['encrypt'][0]),
                    'encryptedCnic_present'  => !empty($encryptedCnic)
                ]);
            }



    
        //return $decryptedCnic;
        $fullName = $response['userInfo']['userName'] ?? '';
        $nameParts = explode(' ', trim($fullName), 2);
        $firstName = $nameParts[0] ?? null;
        $lastName  = $nameParts[1] ?? null;
        $lastDigit = $decryptedCnic ? substr($decryptedCnic, -1) : null;
        $gender    = ($lastDigit % 2 === 0) ? 'Male' : 'Female';
        
        \Log::info('Test Response:', ['CNIC' => $decryptedCnic]);

        if (isset($response['userInfo']) && isset($response['result'])) {
            EasypaisaUser::updateOrCreate(
                ['open_id' => $response['userInfo']['openId']],
                [
                    'union_id'        => $response['userInfo']['unionId'],
                    'user_msisdn'     => $response['userInfo']['userMsisdn'],
                    'result_code'     => $response['result']['resultCode'],
                    'result_status'   => $response['result']['resultStatus'],
                    'result_message'  => $response['result']['resultMessage'],
                    'first_name'      => $firstName,
                    'last_name'       => $lastName,
                    'date_of_birth'   => !empty($response['userInfo']['birthDate']) ? $response['userInfo']['birthDate'] : now()->toDateString(),
                    'cnic'            => $decryptedCnic, // ðŸ‘ˆ Save decrypted CNIC here
                    'gender'          => $gender,
                    'email_address'   => $response['userInfo']['userMsisdn'] ? $response['userInfo']['userMsisdn'] . '@easypaisa.com' : null,
                    'address'         => 'Easypaisa Mini App',
                    'province'        => 'Punjab',
                    'city'            => 'Islamabad',
                    'occupation'      => 'Q17'
                ]
            );

            return response()->json([
                'status' => 200,
                'message' => 'UserInfo Successfully Saved',
                'data' => $response
            ], 200);
        }

        return response()->json([
            'status' => 400,
            'message' => 'Invalid response received',
            'data' => $response
        ], 400);

    } catch (\Illuminate\Validation\ValidationException $e) {
        return response()->json(['error' => $e->getMessage()], 422);
    } catch (\Exception $e) {
        \Log::info('error:', ['error' => $e]);
        return response()->json(['error' => $e], 500);
    }
}


    private function getAccessToken()
    {
        return '92ef0af596107b199c70944b5e8110361be3a17b'; // Yahan actual token retrieval logic add karein
    }













}
