<?php

namespace App\Jobs;

use App\Models\Deed\InvitationCardModel;
use App\Models\PartnerModel;
use App\Models\PraiseModel;
use App\Models\User\SuperLikeModel;
use App\Models\User\UserModel;
use App\Models\User\UserSysTagModel;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

/**
 * Class NoticeJob
 * @package App\Jobs
 */
class NoticeJob implements ShouldQueue
{
    use Dispatchable;
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;

    private $dlt = 0.0003;
    private $t2limit = 80;
    private $basescore = 60;
    private $minscore = 89;
    private $less60m_prescore = 3;

    // 累计超级心动分数
    private $total_superlike_prescore = 2;
    // 累计心动邀请分数
    private $total_invite_prescore = 4;
    // 累计心动分数
    private $total_thumb_prescore = 1;

    // 当前超级心动分数
    private $superlike_prescore = 20;
    // 当前心动邀请分数
    private $invite_prescore = 40;
    // 当前心动分数
    private $thumb_prescore = 5;

    private $uid;

    private $callback;

    private $args;


    /**
     * Create a new job instance.
     *
     * @param  int  $uid  通知用户
     * @param $callback
     * @param $args
     */
    public function __construct(int $uid, $callback, $args)
    {
        $this->uid = $uid;
        $this->callback = $callback;
        $this->args = $args;
        array_push($this->args, false);
    }

    /**
     * Execute the job.
     *
     * @return bool
     */
    public function handle()
    {
        sleep(3);

        /** @var UserSysTagModel $systag */
        $systag = UserSysTagModel::firstOrCreate(['uid' => $this->uid], [
            'supvip_days' => 0,
            'last_be_supvip_at' => 0,
            'supvip_endat' => 0,
            'last_send_notice_at' => 0,
            'after_notice_less_h_into_cnt' => 0,
            'notice_send_cnt' => 0
        ]);

        $last_send_notice_at = $systag->last_send_notice_at;
        0 == $systag->last_send_notice_at && $systag->last_send_notice_at = time() - 18 * 3600;
        $user = UserModel::findOrFail($this->uid);
        $partner = PartnerModel::findOrFail($user->partner_id);

        if ($user->login_at < $last_send_notice_at && time() < $last_send_notice_at + 86400) {
            return true;
        }

        // 当前超级心动分数
        $superlike_cnt = SuperLikeModel::where([
            ['partner_id', $user->partner_id],
            ['created_at', '>', $user->login_at]
        ])->count();
        $superlike_score = $superlike_cnt * $this->superlike_prescore;
        // 当前心动邀请分数
        $invite_cnt = InvitationCardModel::where([
            ['invite_uid', $user->uid],
            ['created_at', '>', $user->login_at]
        ])->count();
        $invite_score = $invite_cnt * $this->invite_prescore;
        // 当前心动分数
        $thumb_cnt = PraiseModel::where([
            ['partner_id', $user->partner_id],
            ['create_at', '>', $user->login_at]
        ])->count();
        $thumb_score = $thumb_cnt * $this->thumb_prescore;

        $total_at = $last_send_notice_at;
        0 == $total_at && $total_at = $user->login_at;
        // 累计超级心动分数
        $total_superlike_cnt = SuperLikeModel::where([
            ['partner_id', $user->partner_id],
            ['created_at', '<', $total_at]
        ])->count();
        $total_superlike_score = $total_superlike_cnt * $this->total_superlike_prescore;
        // 累计心动邀请分数
        $total_invite_cnt = InvitationCardModel::where([
            ['invite_uid', $user->uid],
            ['created_at', '<', $total_at]
        ])->count();
        $total_invite_score = $total_invite_cnt * $this->total_invite_prescore;
        // 累计心动分数
        $total_thumb_cnt = max($partner->praises - PraiseModel::where([
                ['partner_id', $user->partner_id],
                ['create_at', '>', $total_at]
            ])->count(), 0);
        $total_thumb_score = $total_thumb_cnt * $this->total_thumb_prescore;

        $sbf = ceil(min(
            $this->minscore,
            exp(-1 * $this->dlt * (time() - $partner->created_at) / 3600) * ($this->basescore + $total_superlike_score + $total_invite_score + $total_thumb_score - $systag->after_notice_less_h_into_cnt * $this->less60m_prescore)
        ));
        $now = ceil($superlike_score + $invite_score + $thumb_score + min(
            ceil((time() - $systag->last_send_notice_at) / 3600),
            24
        ) * ($this->t2limit / 24));

        if ($now >= $sbf) {
            // 发送
            if (call_user_func_array($this->callback, $this->args)) {
                UserSysTagModel::where('uid', $user->uid)->update([
                    'last_send_notice_at' => time(),
                    'notice_send_cnt' => $systag->notice_send_cnt + 1
                ]);
            }
            return true;
        } else {
            return true;
        }
    }
}
