<?php

namespace App\Http\Services\Deposit\Bank;

use App\Http\Services\Deposit\Bank\Util\ResponseBankUtilDepositServices;
use App\Models\PaymentMethod;
use App\Models\Setting;
use Illuminate\Support\Facades\URL;

/**
 * Laravel/Symfony Developer
 * Name: bukar mai 
 * Telegram: @Mamber001
 * Hire me via Telegram: @Mamber001
 */
class HeyPayBankDepositServices
{
    /**
     * Deposit Payment
     *
     * @param string $reference
     * @param string $currency
     * @param string $amount
     * @param string $method
     */
    public function deposit(
        string $reference,
        string $currency,
        string $amount,
        string $method
    ) {
        try {
            // Find Setting
            $setting = PaymentMethod::where(['tag' => 'heypay', 'status' => 'active'])->first();
            if (!$setting) throw new \Exception("Service not enabled at the moment");
            $setting = json_decode($setting->settings);

            // Request Body
            $requestBody = [
                "appid"      => $setting->appid->value,
                "amount"     => intval($amount) * 100, // 
                "order_no"   => $reference,
                "notify_url" => URL::route('ipn.heypay.payin'),
                "timestamp"  => time(),
                "jump_url"   => URL::route('recharge.history.preview'),
                'pay_method' => 'MA',
            ];

            // Sign Data
            $requestBody['sign'] = self::generateSignature($requestBody, $setting->app_key->value);

            // Send Curl Request
            $response = $this->curlRequest('POST', '/v1/payin/create', $requestBody);

            // Exception
            if ($response instanceof \Exception) throw new \Exception($response->getMessage());

            // Format Response
            return ResponseBankUtilDepositServices::response(
                200,
                2,
                true,
                $reference,
                $response['order_no'],
                $currency,
                $amount,
                $method,
                $response['pay_url'] ?? ''
            );

        } catch (\Exception $th) {
            return $th;
        }
    }

    /**
     * Curl Request
     *
     * @param string $method
     * @param string $endpoint
     * @param array $body
     */
    public function curlRequest(string $method, string $endpoint, array $body = [])
    {
        try {
            $curl = curl_init();
            curl_setopt_array($curl, [
                CURLOPT_URL => 'https://api.heypay.org' . $endpoint,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_ENCODING => '',
                CURLOPT_MAXREDIRS => 10,
                CURLOPT_TIMEOUT => 30,
                CURLOPT_FOLLOWLOCATION => true,
                CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                CURLOPT_CUSTOMREQUEST => $method,
                CURLOPT_POSTFIELDS => json_encode($body),
                CURLOPT_HTTPHEADER => [
                    'Content-Type: application/json'
                ],
            ]);

            $response = curl_exec($curl);
            $err = curl_error($curl);
            $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            curl_close($curl);

            if ($err) throw new \Exception('Curl returned error: ' . $err);

            $response_array = json_decode($response, true);
            if (!in_array($httpcode, [200])) throw new \Exception($response_array['msg'] ?? 'Unknown error');
            if (($response_array['code'] ?? 1) !== 0) throw new \Exception($response_array['msg'] ?? 'Unknown error');

            return $response_array['data'] ?? [];

        } catch (\Exception $th) {
            return $th;
        }
    }

    /**
     * Generate HMAC-SHA1 Signature
     *
     * @param array $data
     * @param string $key
     * @return string
     */
    public static function generateSignature(array $data, string $key): string
    {
        // Remove empty and sign field
        $filteredData = array_filter($data, function ($v, $k) {
            return $v !== '' && $k !== 'sign';
        }, ARRAY_FILTER_USE_BOTH);

        // Sort by key ASCII
        ksort($filteredData);

        // Build string
        $str = '';
        foreach ($filteredData as $k => $val) {
            $str .= $k . '=' . $val . '&';
        }
        $str = rtrim($str, '&');

        // HMAC-SHA1 and base64 encode
        return base64_encode(hash_hmac("sha1", $str, $key, true));
    }
}
