<?php

namespace App\Http\Controllers\Api;

use App\Http\logic\api\BotImPayLogic;
use App\Http\logic\api\BotImPayCashierLogic;
use App\Inter\PayMentInterFace;
use App\Notification\TelegramBot;
use App\Services\BotImPayService;
use App\Util;
use App\Utility\SetNXLock;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;

class BotImPayController implements PayMentInterFace
{
    /**
     * 代收下单
     */
    public function pay_order(
        $userId, $payAmt, $userName, $userEmail, $userPhone,
        $GiftsID, $buyIP, $AdId, $eventType, $pay_method = ''
    ) {
        $logic = new BotImPayLogic();
        try {
            $res = $logic->pay_order($userId, $payAmt, $userPhone, $userEmail, $userName, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
        } catch (\Exception $exception) {
            Redis::set("PayErro_BotImPay", 1);
            Redis::expire("PayErro_BotImPay", 600);
            Util::WriteLog('BotImPay_error', $exception->getMessage() . json_encode($logic->result ?? []));
            TelegramBot::getDefault()->sendProgramNotify("BotImPay Except ", $exception->getMessage(), $exception);
            return apiReturnFail($logic->getError());
        }

        if (!empty($res) && isset($res['code']) && $res['code'] == 200) {
            $data = [
                'content'  => $res['data']['order_data'] ?? '',
                'money'    => $payAmt,
                'prdOrdNo' => $res['data']['order_no'] ?? '',
            ];
            return apiReturnSuc($data);
        }

        if ($res == false) {
            return apiReturnFail($logic->getError() ?: 'Payment failed');
        }

        Redis::set("PayErro_BotImPay", 1);
        Redis::expire("PayErro_BotImPay", 600);
        $errMsg = $res['message'] ?? 'Unknown error';
        TelegramBot::getDefault()->sendProgramNotify("BotImPay ReturnFail ", $errMsg . " | " . json_encode($res));
        return apiReturnFail(['web.payment.paytype_error', $errMsg]);
    }

    /**
     * 代收异步回调通知
     */
    public function notify(Request $request)
    {
        $post = $request->all();
        Util::WriteLog('BotImPay', "BotImPay回调订单\n" . json_encode($post));

        $service = new BotImPayService('BotImPay');
        try {
            $verify = $service->verifySign($post);
        } catch (\Exception $e) {
            Util::WriteLog('BotImPay', '验签失败：' . $e->getMessage());
            return 'fail';
        }
        if (!$verify) {
            Util::WriteLog('BotImPay', '签名错误');
            return 'fail';
        }

        $order_sn = $post['order_no'] ?? '';
        if (empty($order_sn)) {
            Util::WriteLog('BotImPay', '缺少订单号');
            return 'fail';
        }

        $lockKey = 'pay_notify_BotImPay_' . $order_sn;
        if (!SetNXLock::getExclusiveLock($lockKey, 60)) {
            Util::WriteLog('BotImPay', '代收回调并发，订单已处理或处理中: ' . $order_sn);
            return 'ok';
        }

        $logic = new BotImPayLogic();
        try {
            $ret = $logic->notify($post);
            return $ret;
        } catch (\Exception $exception) {
            Redis::set("PayErro_BotImPay", 1);
            Redis::expire("PayErro_BotImPay", 600);
            TelegramBot::getDefault()->sendProgramNotify("BotImPay 订单回调执行异常 ", json_encode($post), $exception);
            Util::WriteLog("BotImPay_error", $post);
            return 'fail';
        } finally {
            SetNXLock::release($lockKey);
        }
    }

    /**
     * 代付异步回调通知
     */
    public function cash_notify(Request $request)
    {
        $post = $request->all();
        Util::WriteLog('BotImPay', "BotImPay 提现回调\n" . json_encode($post));

        $service = new BotImPayService('BotImPayOut');
        try {
            $verify = $service->verifySign($post);
        } catch (\Exception $e) {
            Util::WriteLog('BotImPay', '提现回调验签失败：' . $e->getMessage());
            return 'FAIL';
        }
        if (!$verify) {
            Util::WriteLog('BotImPay', '提现回调签名错误');
            return 'FAIL';
        }

        $logic = new BotImPayCashierLogic();
        try {
            return $logic->notify($post);
        } catch (\Exception $exception) {
            TelegramBot::getDefault()->sendProgramNotify("BotImPay 提现异步回调执行异常 ", json_encode($post), $exception);
            Util::WriteLog("BotImPay_error", $post);
            return 'SUCCESS';
        }
    }
}
