<?php

namespace App\Http\Controllers\V1;


use App\Helper\ByteDance;
use App\Helper\UniPlatform\Bytedance\Payment as BytedancePayment;
use App\Helper\UniPlatform\Kuaishou\Payment as KuaishouPayment;
use App\Models\Pay;
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 = $data['status'] == 'SUCCESS';
                $pay->pay_dt = Carbon::now()->toDateTimeString();
                $pay->save();
                // 处理
                if ($pay->source == Pay::SOURCE_RECHARGE) {
                    $goods = $this->recharge($payId);
                } else if ($pay->source == Pay::SOURCE_BUY_VIP) {
                    $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
    {
        $app = new KuaishouPayment($this->getUniFactory(2));
        return $app->payNotify(function ($data, $fail) {
            //处理支付订单
            try {
                \DB::beginTransaction();
                $payId = $data['out_order_no'];
                $pay = Pay::find($payId);
                if (!$pay) { // 如果订单不存在
                    return true;
                }
                $payType = 11;
                if($data['channel'] == 'WECHAT'){
                    $payType = 1;
                }
                if($data['channel'] == 'ALIPAY'){
                    $payType = 2;
                }
                $pay->pay_type = $payType;
                $pay->serial_number = $data['trade_no'];
                $pay->status = $data['status'] == 'SUCCESS';
                $pay->pay_dt = Carbon::now()->toDateTimeString();
                $pay->save();
                // 处理
                if ($pay->source == Pay::SOURCE_RECHARGE) {
                    $this->recharge($payId);
                } else if ($pay->source == Pay::SOURCE_BUY_VIP) {
                    $this->buyVip($payId);
                }

                \DB::commit();
                // 成为分销商
                (new User())->beComeShare($pay->user_id);
            } catch (\Exception $e) {
                \DB::rollBack();
                \Log::error('快手支付回调错误==>'.$e->getMessage());
                return $fail('通信失败，请稍后再通知我');
            }
            return true;
        });
    }

    /**
     * @return Response
     * @throws \EasyWeChat\Kernel\Exceptions\Exception
     */
    public function wechat(): Response
    {
        $factory = $this->getUniFactory(3)->payment();
        return $factory->handlePaidNotify(function ($message, $fail){
            \Log::info('微信支付回调==>'.json_encode($message,JSON_UNESCAPED_SLASHES));
            //处理支付订单
            try {
                \DB::beginTransaction();
                $payId = $message['out_trade_no'];
                $pay = Pay::find($payId);
                if (!$pay) { // 如果订单不存在
                    return true;
                }
                if ($message['return_code'] === 'SUCCESS') {
                    if ($message['result_code'] === 'SUCCESS') {
                        $pay->status = 1;
                        $pay->serial_number = $message['transaction_id'];
                    }elseif ($message['result_code'] === 'FAIL') {
                        $pay->status = -1;
                    }
                } else {
                    return $fail('通信失败，请稍后再通知我');
                }
                $pay->pay_dt = Carbon::now()->toDateTimeString(); // 更新支付时间为当前时间
                $pay->save();
                // 处理
                if ($pay->source == Pay::SOURCE_RECHARGE) {
                    $this->recharge($payId);
                } else if ($pay->source == Pay::SOURCE_BUY_VIP) {
                    $this->buyVip($payId);
                }

                \DB::commit();
                // 成为分销商
                (new User())->beComeShare($pay->user_id);
            } catch (\Exception $e) {
                \DB::rollBack();
                \Log::error('微信支付回调错误==>'.$e->getMessage());
                return $fail('通信失败，请稍后再通知我');
            }
            return true;
        });
    }


    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
     * @param $type
     * @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($config->share_type == 1){ // 百分比
                $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();
        }
    }
}

