<?php

namespace App\Http\Controllers\Api;

use App\Http\logic\api\SupefinaSpeiLogic;
use App\Http\logic\api\SupefinaSpeiCashierLogic;
use App\Inter\PayMentInterFace;
use App\Notification\TelegramBot;
use App\Services\SupefinaSpei;
use App\Util;
use App\Utility\SetNXLock;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;

class SupefinaSpeiController implements PayMentInterFace
{
    private $retryTimes = 0;

    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method = '')
    {
        $logic = new SupefinaSpeiLogic();
        try {
            $res = $logic->pay_order($userId, $payAmt, $userPhone, $userEmail, $userName, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
        } catch (\Exception $exception) {
            Redis::set('PayErro_SupefinaSpei', 1);
            Redis::expire('PayErro_SupefinaSpei', 600);
            Util::WriteLog('SupefinaSpei_error', $exception->getMessage() . json_encode($logic->result ?? []));
            TelegramBot::getDefault()->sendProgramNotify('SupefinaSpei Except ', $exception->getMessage(), $exception);
            return apiReturnFail($logic->getError());
        }

        if (!empty($res) && isset($res['code']) && (string)$res['code'] === '200' && !empty($res['data'])) {
            $data = $res['data'];
            $content = $data['url'] ?? '';
            if (empty($content) && !empty($data['identifier'])) {
                $content = 'CLABE:' . $data['identifier'];
            }
            return apiReturnSuc([
                'content' => $content,
                'money'   => $payAmt,
                'prdOrdNo' => $data['merOrderNo'] ?? '',
                'identifier' => $data['identifier'] ?? '',
            ]);
        }

        if ($res === false) {
            return apiReturnFail($logic->getError());
        }

        if ($this->retryTimes > 0) {
            Redis::set('PayErro_SupefinaSpei', 1);
            Redis::expire('PayErro_SupefinaSpei', 600);
            TelegramBot::getDefault()->sendProgramNotify('SupefinaSpei ReturnFail ', $logic->getError() . ' | ' . json_encode($res));
            return apiReturnFail($logic->getError());
        }
        $this->retryTimes++;
        return $this->pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
    }

    /**
     * 统一回调入口：代收(01) + 代付(02)，验签后按 transactionType 分发
     */
    public function notify(Request $request)
    {
        $payload = $request->getContent();
        $post = json_decode($payload, true);
        if (!is_array($post)) {
            $post = $request->all();
        }

        Util::WriteLog('SupefinaSpei', "raw notify\n" . $payload);

        $transactionType = $post['transactionType'] ?? '';
        $orderId = $post['merOrderId'] ?? $post['merOrderNo'] ?? '';

        $configKey = $transactionType === '02' ? 'SupefinaSpeiOut' : 'SupefinaSpei';
        $service = new SupefinaSpei($configKey);
        if (!$service->verify($post)) {
            Util::WriteLog('SupefinaSpei_error', 'notify sign invalid');
            return 'fail';
        }

        $lockKey = '';
        if ($orderId) {
            $lockKey = 'pay_notify_SupefinaSpei_' . $transactionType . '_' . $orderId;
            if (!SetNXLock::getExclusiveLock($lockKey, 60)) {
                Util::WriteLog('SupefinaSpei', 'notify concurrent, ignore: ' . $orderId);
                return 'SUCCESS';
            }
        }

        try {
            if ($transactionType === '01') {
                $logic = new SupefinaSpeiLogic();
                $ret = $logic->notify($post);
            } elseif ($transactionType === '02') {
                $logic = new SupefinaSpeiCashierLogic();
                $ret = $logic->notify($post);
            } else {
                Util::WriteLog('SupefinaSpei', 'ignore transactionType: ' . $transactionType);
                $ret = 'SUCCESS';
            }
        } finally {
            if ($lockKey !== '') {
                SetNXLock::release($lockKey);
            }
        }

        return $ret;
    }

    /**
     * 代付回调（保留兼容，建议统一用 notify）
     */
    public function cash_notify(Request $request)
    {
        $payload = $request->getContent();
        $post = json_decode($payload, true);
        if (!is_array($post)) {
            $post = $request->all();
        }

        Util::WriteLog('SupefinaSpei', "raw payout notify\n" . $payload);

        $orderId = $post['merOrderId'] ?? $post['merOrderNo'] ?? '';
        $lockKey = '';
        if ($orderId) {
            $lockKey = 'pay_notify_SupefinaSpei_02_' . $orderId;
            if (!SetNXLock::getExclusiveLock($lockKey, 60)) {
                Util::WriteLog('SupefinaSpei', 'payout notify concurrent, ignore: ' . $orderId);
                return 'SUCCESS';
            }
        }

        try {
            $logic = new SupefinaSpeiCashierLogic();
            $ret = $logic->notify($post);
        } finally {
            if ($lockKey !== '') {
                SetNXLock::release($lockKey);
            }
        }

        return $ret;
    }
}
