<?php

namespace App\Http\Controllers\Api;

use App\Http\logic\api\WiwiPayLogic;
use App\Http\logic\api\WiwiPayCashierLogic;
use App\Inter\PayMentInterFace;
use App\Notification\TelegramBot;
use App\Services\WiwiPay;
use App\Services\PayConfig;
use App\Services\PayUtils;
use App\Util;
use App\Utility\SetNXLock;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class WiwiPayController implements PayMentInterFace
{
    private $retryTimes = 0;

    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method = '')
    {
        $logic = new WiwiPayLogic();
        try {
            $res = $logic->pay_order($userId, $payAmt, $userPhone, $userEmail, $userName, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
        } catch (\Exception $exception) {
            Redis::set("PayErro_WiwiPay", 1);
            Redis::expire("PayErro_WiwiPay", 600);
            Util::WriteLog('WiwiPay_error', $exception->getMessage() . json_encode($logic->result ?? []));

            TelegramBot::getDefault()->sendProgramNotify("WiwiPay Except ", $exception->getMessage(), $exception);
            return apiReturnFail($logic->getError());
        }

        if (!empty($res) && isset($res['code']) && $res['code'] == 0) {
            $data = [
                'content' => $res['data']['cashierUrl'],
                'money' => $payAmt,
                'prdOrdNo' => $res['data']['mchOrderNo'],
            ];
            return apiReturnSuc($data);
        } else if ($res == false) {
            return apiReturnFail($logic->getError());
        } else {
            if ($this->retryTimes > 0) {
                Redis::set("PayErro_WiwiPay", 1);
                Redis::expire("PayErro_WiwiPay", 600);
                TelegramBot::getDefault()->sendProgramNotify("WiwiPay RetrunFail ", $logic->getError() . " | " . json_encode($res));
                return apiReturnFail($logic->getError());
            } else {
                $this->retryTimes++;
                return $this->pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
            }
        }
    }

    // 支付异步回调
    public function notify(Request $request)
    {
        $post = $request->all();
        $payload = json_encode($post);

        Util::WriteLog('WiwiPay', "WiwiPay回调订单\n" . $payload);



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

        if (!$verify) {
            Util::WriteLog('WiwiPay', '签名错误');
            return 'fail';
        }

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

        // 代收回调加锁，防止并发重复处理
        $lockKey = 'pay_notify_WiwiPay_' . $order_sn;
        if (!SetNXLock::getExclusiveLock($lockKey, 60)) {
            Util::WriteLog('WiwiPay', '代收回调并发，订单已处理或处理中: ' . $order_sn);
            return 'success';
        }

        $logic = new WiwiPayLogic();
        try {
            $redis = Redis::connection();
            $ret = $logic->notify($post);
            if ($ret == 'success') $redis->set($order_sn, $order_sn, 3600 * 24);
            return $ret;
        } catch (\Exception $exception) {
            Redis::set("PayErro_WiwiPay", 1);
            Redis::expire("PayErro_WiwiPay", 600);
            TelegramBot::getDefault()->sendProgramNotify("WiwiPay 订单回调执行 异常 ", json_encode($post), $exception);
            Util::WriteLog("WiwiPay_error", $post);
            return '{"success":false,"message":"商户自定义出错信息"}';
        } finally {
            SetNXLock::release($lockKey);
        }
    }

    public function sync_notify(Request $request)
    {
        Log::info('WiwiPay同步回调');
        echo 'WiwiPay同步回调';
    }

    // 提现异步回调
    public function cash_notify(Request $request)
    {
        $post = $request->all();
        $payload = json_encode($post);

        Util::WriteLog('WiwiPay', "WiwiPay cash 异步回调\n" . $payload);

        // ✅ 使用 WiwiPayOut 配置进行验签
        $payConfigService = new PayConfig();
        $config = $payConfigService->getConfig('WiwiPayOut');
        $apiKey = $config['key'];
        
        try {
            $verify = PayUtils::verifySign($post, $apiKey);
        } catch (\Exception $e) {
            Util::WriteLog('WiwiPay cash', '验签失败：' . $e->getMessage());
            return 'fail';
        }

        if (!$verify) {
            Util::WriteLog('WiwiPay cash', '签名错误');
            return 'fail';
        }

        $logic = new WiwiPayCashierLogic();
        try {
            return $logic->notify($post);
        } catch (\Exception $exception) {
            TelegramBot::getDefault()->sendProgramNotify("WiwiPay 提现异步回调执行 异常 ", json_encode($post), $exception);
            Util::WriteLog("WiwiPay_error", $post);
            return '{"success":false,"message":"商户自定义出错信息"}';
        }
    }
}
