<?php

namespace App\Http\Controllers\Api;

use App\Http\logic\api\PayPlusCashierLogic;
use App\Http\logic\api\PayPlusLogic;
use App\Inter\PayMentInterFace;
use App\Notification\TelegramBot;
use App\Services\PayPlus;
use App\Util;
use App\Utility\SetNXLock;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class PayPlusController implements PayMentInterFace
{
    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method = '')
    {
        $logic = new PayPlusLogic();

        try {
            $res = $logic->pay_order($userId, $payAmt, $userPhone, $userEmail, $userName, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
        } catch (\Exception $exception) {
            Redis::set('PayErro_PayPlus', 1);
            Redis::expire('PayErro_PayPlus', 600);
            Util::WriteLog('PayPlus_error', $exception->getMessage());
            TelegramBot::getDefault()->sendProgramNotify('PayPlus Except ', $exception->getMessage(), $exception);

            return apiReturnFail($logic->getError() ?: 'Payment processing error');
        }

        if (!empty($res) && isset($res['code']) && (int) $res['code'] == 200 && !empty($res['decryptedComponentDelta']['link'])) {
            
            return apiReturnSuc([
                'content' => $res['decryptedComponentDelta']['link'],
                'money' => $payAmt,
                'prdOrdNo' => $res['decryptedComponentDelta']['order_id'] ?? '',
            ]);
        }

        return apiReturnFail($logic->getError() ?: 'Payment processing error');
    }

    public function notify(Request $request)
    {
        $post = $request->all();
        $content = (string) $request->getContent();
        $post = json_decode($content, true) ?: $post;
        Util::WriteLog('PayPlus', 'pay notify: ' . json_encode($post, JSON_UNESCAPED_UNICODE));
        Util::WriteLog('PayPlus', 'pay notify header: ' . json_encode($request->headers->all()));

        $orderSn = $post['data']['platform_order_id'] ?? '';
        if ($orderSn === '') {
            return 'success';
        }

        $lockKey = 'pay_notify_PayPlus_' . $orderSn;
        if (!SetNXLock::getExclusiveLock($lockKey, 60)) {
            return 'success';
        }

        try {
            return (new PayPlusLogic())->notify($post);
        } catch (\Exception $exception) {
            Redis::set('PayErro_PayPlus', 1);
            Redis::expire('PayErro_PayPlus', 600);
            TelegramBot::getDefault()->sendProgramNotify('PayPlus notify exception', json_encode($post), $exception);
            Util::WriteLog('PayPlus_error', $exception->getMessage());

            return 'success';
        } finally {
            SetNXLock::release($lockKey);
        }
    }

    public function sync_notify(Request $request)
    {
        Log::info('PayPlus sync notify');

        return 'PayPlus sync notify';
    }

    public function cash_notify(Request $request)
    {
        $post = $request->all();
        $content = (string) $request->getContent();
        $post = json_decode($content, true) ?: $post;
        Util::WriteLog('PayPlus', 'cash notify: ' . json_encode($post, JSON_UNESCAPED_UNICODE));
        Util::WriteLog('PayPlus', 'cash notify header: ' . json_encode($request->headers->all()));
        $signature = $request->header('Authorization', '');
        $service = (new PayPlus())->getPayoutService();
        if (!$service->verifyPayoutSignature($post, $signature)) {
            Util::WriteLog('PayPlus', 'cash notify verify failed');

            return 'success';
        }

        try {
            (new PayPlusCashierLogic($service))->notify($post);
        } catch (\Exception $exception) {
            TelegramBot::getDefault()->sendProgramNotify('PayPlus cash notify exception', json_encode($post), $exception);
            Util::WriteLog('PayPlus_error', $exception->getMessage());
        }

        return 'success';
    }
}
