<?php

namespace App\Jobs\Orders;

use App\Consts\SysConsts;
use App\Modules\Order\Services\OrderService;
use App\Modules\Trade\Models\Order;
use App\Modules\User\Models\User;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\DB;
use Redis;

/**
 * 增加订单统计金额
 */
class AddOrderAmount implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $key;
    private $date;
    private $order_no;
    private $channel_id;
    private $send_order_id;
    private $uid;
    private $amount;
    private $pay_time;

    /**
     * Create a new job instance.
     * @param string $order_no 订单号
     * @param float $amount 支付金额
     * @param string $paid_time 支付成功事件
     * @return void
     */
    public function __construct(string $order_no)
    {
        $this->order_no = $order_no;
        $order = $this->findOrder($order_no);
        $this->channel_id = $order->distribution_channel_id;
        $this->send_order_id = $order->send_order_id;
        $this->amount = $order->price;
        $this->pay_time = $order->created_at;
        $this->date = date('Y-m-d', strtotime($order->created_at));
        $this->key = 'increase_order_amount:' . $this->date;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $service = new OrderService;
        try {
            if (!Redis::exists($this->key)) {
                Redis::hSet($this->key, $this->order_no, 1);
                Redis::expire($this->key, SysConsts::ONE_DAY_SECONDS * 2);
            } else if (Redis::hExists($this->key, $this->order_no)) {
                return;
            } else {
                Redis::hSet($this->key, $this->order_no, 1);
            }
            DB::beginTransaction();
            $service->increaseChannelAmount($this->date, $this->channel_id, $this->amount);
            $service->increaseSendOrderAmount($this->date, $this->channel_id, $this->send_order_id, $this->amount, $this->pay_time);
            $user = User::where('id', $this->uid)->select('send_order_id')->first();
            if ($user) {
                $user_send_order = $user->send_order_id;
                $service->increaseUserSendOrderAmount($this->date, $this->channel_id, $user_send_order, $this->amount, $this->pay_time);
            }
            DB::commit();
        } catch (Exception $e) {
            DB::rollback();
            Redis::hDel($this->key, $this->order_no);
            myLog('increase_order_amount')->error($this->order_no);
            myLog('increase_order_amount')->error($e->getMessage());
        }
    }

    private function findOrder(string $order_no)
    {
        return Order::where('order_no', $order_no)
            ->select('send_order_id', 'distribution_channel_id', 'pay_end_at', 'uid', 'price')
            ->first();
    }
}
