<?php

namespace App\Http\Controllers\V1;

use App\Helper\UniPlatform\Bytedance\Payment as BytedancePayment;
use App\Helper\UniPlatform\Kuaishou\Payment as KuaishouPayment;
use App\Models\Config;
use App\Models\Giveaway;
use App\Models\Order;
use App\Models\Pay;
use App\Models\Share;
use App\libs\helpers\Helper;
use App\Models\PaymentConfig;
use App\Models\ShareConfig;
use App\Models\User;
use App\Models\UserConsumeRecord;
use App\Models\UserInfo;
use App\Models\UserRechargeRecord;
use App\Models\UserShare;
use App\Models\UserVipRecord;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;

class PayNoticeController extends Controller
{
    public function bytedance(): JsonResponse
    {
        $factory = $this->getUniFactory();
        $app     = new BytedancePayment($factory);

        return $app->payNotify(function ($data, $fail) use ($factory) {
            // 处理支付订单
            try {
                \DB::beginTransaction();
                $payId = $data['cp_orderno'];
                $pay   = Pay::find($payId);
                if (!$pay) { // 如果订单不存在
                    return true;
                }
                $pay->pay_type      = $data['way'];
                $pay->serial_number = $data['channel_no'];
                $pay->status        = 'SUCCESS' == $data['status'];
                $pay->pay_dt        = Carbon::now()->toDateTimeString();
                $pay->save();
                // 处理
                if (Pay::SOURCE_RECHARGE == $pay->source) {
                    $goods = $this->recharge($payId);
                } elseif (Pay::SOURCE_BUY_VIP == $pay->source) {
                    $goods = $this->buyVip($payId);
                }

                if (isset($goods)) {
                    /* @var Pay $payInfo */
                    $payInfo = Pay::with(['user'])->where('pay_id', $payId)->first();
                    $factory->pushOrder($payInfo->user->open_id, $payId, $goods, '已支付');
                }
                \DB::commit();
                // 成为分销商
                (new User())->beComeShare($pay->user_id);
            } catch (\Exception $e) {
                \DB::rollBack();
                \Log::error('抖音支付回调错误==>' . $e->getMessage());

                return $fail('通信失败，请稍后再通知我');
            }

            return true;
        });
    }

    public function kuaishou(): JsonResponse
    {
        $factory = $this->getUniFactory(2);
        $app     = new KuaishouPayment($factory);

        return $app->payNotify(function ($data, $fail) use ($factory) {
            // 处理支付订单
            try {
                \DB::beginTransaction();
                $payId = $data['out_order_no'];
                $pay   = Pay::find($payId);
                if (!$pay) { // 如果订单不存在
                    return true;
                }
                $payType = 11;
                if ('WECHAT' == $data['channel']) {
                    $payType = 1;
                }
                if ('ALIPAY' == $data['channel']) {
                    $payType = 2;
                }
                $pay->pay_type      = $payType;
                $pay->serial_number = $data['trade_no'];
                $pay->status        = 'SUCCESS' == $data['status'];
                $pay->pay_dt        = Carbon::now()->toDateTimeString();
                $pay->save();
                // 处理
                if (Pay::SOURCE_RECHARGE == $pay->source) {
                    $goods = $this->recharge($payId);
                } elseif (Pay::SOURCE_BUY_VIP == $pay->source) {
                    $goods = $this->buyVip($payId);
                }

                if (isset($goods)) {
                    /* @var Pay $payInfo */
                    $payInfo = Pay::with(['user'])->where('pay_id', $payId)->first();
                    $factory->pushOrder($payInfo->user->open_id, $payId, $payInfo->created_at);
                }

                \DB::commit();
                // 成为分销商
                (new User())->beComeShare($pay->user_id);
            } catch (\Exception $e) {
                \DB::rollBack();
                \Log::error('快手支付回调错误==>' . $e->getMessage());

                return $fail('通信失败，请稍后再通知我');
            }

            return true;
        });
    }

    public function kuaishouSettle()
    {
        $app = new KuaishouPayment($this->getUniFactory(2));

        return $app->payNotify(function ($data, $fail) {
            return true;
        });
    }

    /**
     * @throws \EasyWeChat\Kernel\Exceptions\Exception
     */
    public function wechat()
    {
        $param  = file_get_contents('php://input');
        $params = Helper::xmlToArray($param);

        Log::info('微信支付回调==>' . json_encode($params, JSON_UNESCAPED_SLASHES));

        // 处理支付订单
        try {
            $payId = $params['out_trade_no'];
            $pay   = Order::query()->where('order', $payId)->where('state',0)->first();
            if (!$pay) { // 如果订单不存在
                return true;
            }
            if ('SUCCESS' === $params['return_code']) {
                if ('SUCCESS' === $params['result_code']) {
                    $pay->state    = 1;
                    $pay->wx_order = $params['transaction_id'];
                    $pay->amount = $params['total_fee'];
                    User::query()->where('id', $pay->user_id)->increment('diamond', $pay->diamond);
                    $user = User::query()->find($pay->user_id);
                    if (!empty($user->share_pid)){
                        $userShare = User::query()->find($user->share_pid);
                        $payConfig = PaymentConfig::query()->where('id',$pay->config_id)->first();
                        (float)$commission = Config::query()->where('key','commission')->value('value');
                        if ($userShare->is_share){
                            $number = $pay->amount * ($commission / 100);
                            if ($number < 0.01){
                                $number = 0.01;
                            }
                            $income = $number * 100;
                            User::query()->where('id', $user->share_pid)->increment('income', $income);
                            Giveaway::query()->create([
                                'user_id'       => $user->share_pid,
                                'purchaser_user_id' => $pay->user_id,
                                'amount' => $income,
                                'title'         => "购买了{$payConfig->amount}的{$payConfig->title}，您获得了佣金{$number}元",
                                'order_id'      => $pay->id
                            ]);
                        }else{
                            if ($payConfig->award_count > 0){
                                 Share::query()->create([
                                    'user_id' => $user->share_pid,
                                    'pid'     => $user->id,
                                    'diamond' => $payConfig->award_count,
                                    'desc'      => '通过购买套餐'.$payConfig->amount.'的'.$payConfig->title.'获得'.$payConfig->award_count.'次数',
                                ]);
                                User::query()->where('id', $user->share_pid)->increment('diamond', $payConfig->award_count);
                            }
                        }
                    }
                } elseif ('FAIL' === $params['result_code']) {
                    $pay->state = 2;
                }
            } else {
                return '通信失败，请稍后再通知我';
            }
            $pay->pay_at = date('Y-m-d H:i:s'); // 更新支付时间为当前时间
            $pay->save();
        } catch (\Exception $e) {
            Log::error('微信支付回调错误==>' . $e->getMessage());

            return '通信失败，请稍后再通知我';
        }
    }

    private function recharge($payId)
    {
        /* @var UserRechargeRecord $record */
        $record = UserRechargeRecord::with(['combo'])->where('pay_id', $payId)->first();
        if (!$record) {
            return true;
        }
        $user = UserInfo::find($record->user_id);

        // 记录日志
        $gold = $record->gold + $record->gift;
        app(UserConsumeRecord::class)->record(
            $user->user_id,
            UserConsumeRecord::TYPE_RECHARGE,
            $gold,
            "购买金币,combo_id:{$record->combo_id}"
        );

        // 发放奖励
        $user->integral       = $user->integral       + $gold;
        $user->total_integral = $user->total_integral + $gold;
        $user->save();

        $record->status = 1;
        $record->save();

        // 分销
        $this->share($record, 2);

        return [
            'id'    => $record->combo_id,
            'title' => $record->combo->name,
            'price' => $record->combo->price,
            'img'   => '',
        ];
    }

    private function buyVip($payId)
    {
        /* @var UserVipRecord $record */
        $record = UserVipRecord::with(['combo'])->where('pay_id', $payId)->first();
        if (!$record) {
            return true;
        }
        $user = UserInfo::find($record->user_id);
        if (empty($user->is_vip)) {
            $user->is_vip   = 1;
            $user->start_at = Carbon::now()->toDateString();
            $user->end_at   = Carbon::now()->addDays($record->valid_day)->toDateString();
        } else {
            list($year, $month, $day) = explode('-', $user->end_at);
            $user->end_at             = Carbon::createFromDate($year, $month, $day)->addDays($record->valid_day)->toDateString();
        }
        $user->save();

        $record->status = 1;
        $record->save();

        // 分销
        $this->share($record, 1);

        return [
            'id'    => $record->combo_id,
            'title' => $record->combo->name,
            'price' => $record->combo->price,
            'img'   => '',
        ];
    }

    /**
     * @param UserVipRecord|UserRechargeRecord $record
     *
     * @return void
     */
    private function share($record, $type)
    {
        $user = User::find($record->user_id);
        // 一级分销
        if ($user->parent_id) {
            $config = ShareConfig::first();
            $pay    = Pay::find($record->pay_id);
            if (1 == $config->share_type) { // 百分比
                $income = $pay->order_fee * $config->share_number / 100;
            } else { // 固定
                $income = $config->share_number;
            }

            $share             = new UserShare();
            $share->user_id    = $user->parent_id;
            $share->child_id   = $user->id;
            $share->order_type = $type;
            $share->order_id   = $record->pay_id;
            $share->income     = $income;
            $share->save();

            $parent               = User::find($user->parent_id);
            $parent->income       = $user->income       + $income;
            $parent->total_income = $user->total_income + $income;
            $parent->save();
        }
    }
}
