<?php

namespace App\Services\User;

use App\Exceptions\AlertException;
use App\Http\Controllers\Core\User;
use App\Http\Controllers\Wechat\Kfaccount;
use App\Jobs\NoticeJob;
use App\Models\Common\TokenModel;
use App\Models\Deed\EachLikeModel;
use App\Models\Deed\InvitationCardModel;
use App\Models\NoticeLogModel;
use App\Models\NoticeModel;
use App\Models\PraiseModel;
use App\Models\User\SuperLikeModel;
use App\Models\User\UserModel;
use App\Services\Log\NoticeLogService;
use App\Services\Service;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Redis;
use PocketBE\MsyPush\Jobs\RegistEventJob;

/**
 * Class NoticeService
 * @package App\Services\User
 */
class NoticeService extends Service
{
    /**
     * 心动通知延迟
     */
    public function thumbMeDelay()
    {
        $json = Redis::lpop("{fpdx:thumbme:notice:dely}");
        while (!empty($json)) {
            try {
                $data = json_decode($json, true);
                $this->thumbMe($data['uid'], $data['partner_id'], true);
                $json = Redis::lpop("{fpdx:thumbme:notice:dely}");
            } catch (\Exception $exception) {
            }
        }
    }

    /**
     * 喜欢我的卡片时通知
     * @param  int  $uid  触发者
     * @param  int  $partner_id  通知者卡片
     * @param  bool  $is_callback  是否作为回调函数
     * @return bool
     */
    public function thumbMe(int $uid, int $partner_id, bool $is_callback = true)
    {
        if (time() < mktime(8, 0, 0) || time() > mktime(23, 0, 0)) {
            // 延迟发送
            Redis::rpush("{fpdx:thumbme:notice:dely}", [json_encode(['uid' => $uid, 'partner_id' => $partner_id])]);

            return true;
        }

        /** @var UserModel $to_user */
        $to_user = UserModel::where('partner_id', $partner_id)->firstOrFail();
        $from_user = UserModel::find($uid);
        $to_uid = $to_user->uid;
        // 三天内的点赞次数
        $praise_count = PraiseModel::where([
            ['partner_id', $to_user->partner_id],
            ['created_at', '>', strtotime("-3 day")],
        ])->count();

        $invite_count = InvitationCardModel::where([
            ['invite_uid', $to_user->uid],
            ['created_at', '>', $to_user->login_at],
        ])->count();

        $description = "";
        if ($from_user->partner_id) {
            $from_user_praise = PraiseModel::where([
                ['partner_id', $from_user->partner_id],
            ])->count();

            if ($from_user_praise > 10) {
                switch ($from_user->sex) {
                    case "1":
                        $gender = "他";
                        $appellation = "小姐姐";
                        break;
                    case "2":
                        $gender = "她";
                        $appellation = "小哥哥";
                        break;
                    default:
                        $gender = "ta";
                        $appellation = "人";
                        break;
                }
                $description = "{$gender}被{$from_user_praise}个{$appellation}心动过！";
            }
        }

        // 通知队列
        $payload = [
            'to_user' => $to_user->getAuth(),
            'user' => $to_user->toArray(),
            'from_user' => $from_user->toArray(),
            'meta' => [
                'praise_count' => $praise_count ? $praise_count - 1 : 0,
                'invite_count' => $invite_count ? $invite_count - 1 : 0,
                'date' => date('Y-m-d'),
                'datetime' => date('Y-m-d H:i'),
                'description' => $description,
            ],
        ];

        if ($is_callback) {
            dispatch(new RegistEventJob(100012, $payload))->onQueue("{push}");
            NoticeJob::dispatch($to_uid, array(new self(), __FUNCTION__), array($uid, $partner_id));

            return true;
        }

        dispatch(new RegistEventJob(100005, $payload))->onQueue("{push}");

        return true;
    }

    /**
     * 获取全局通知的数量
     * @param  int  $uid
     * @return array
     */
    public function noticeCnt(int $uid): array
    {
        $user = UserModel::findOrFail($uid);
        // 心动我的通知
        $like_me = PraiseModel::where([['read', 0], ['partner_id', $user->partner_id], ['type', 1]])->count();
        // 系统消息
        if (in_array(Config::get("platform"), ['ios', 'android'])) {
            // APP通知
            if (Config::get("version") < "2.17.6") {
                $shield = [20, 13, 14];
            } else {
                $shield = [20];
            }
        } else {
            // 小程序通知
            $shield = [5];
        }
        $system = NoticeModel::where([['uid', $uid], ['is_read', 0]])->whereIn('type', $shield)->count();
        // 我发出的邀请
        $send_invite = InvitationCardModel::where([['send_read', 0], ['uid', $uid]])->count();
        // 邀请我的
        $invite_me = InvitationCardModel::where([['read', 0], ['state', 0], ['invite_uid', $uid]])->count();
        // 邀请我的用户信息
        $invite_user = null;
        try {
            if ($invite_me > 0) {
                $invitation = InvitationCardModel::where([
                    ['read', 0],
                    ['state', 0],
                    ['invite_uid', $uid],
                ])->OrderBy('id', 'desc')->first();
                $invite_user = UserModel::findOrFail($invitation->uid, ['uid', 'headimgurl', 'nickname']);
            }
        } catch (\Exception $exception) {
            $invite_user = null;
        }

        return array(
            'like_me' => $like_me,
            'system' => $system,
            'send_invite' => $send_invite,
            'invite_me' => $invite_me,
            'invite_user' => $invite_user ?? null,
        );
    }

    /**
     * 会员加入通知
     * @param  int  $to_uid
     * @return bool
     */
    public function vip(int $to_uid)
    {
        $title = '会员加入通知';
        $uuid = uuid();
        $noticeLog = new NoticeLogService();
        try {
            $user = \App\Models\User\UserModel::findOrFail($to_uid);
            $public_id = config('wechat.fpdx.public_id');
            $openid = \DB::table('kddx_user_openid')->where('public_id', $public_id)->where(
                'uid',
                $to_uid
            )->value('openid');
            // 客服消息
            // 限流
            if (
                time() > mktime(18, 0, 0) && NoticeLogModel::where([
                    ['uid', $to_uid],
                    ['title', $title],
                    ['created_at', '>', mktime(18, 0, 0)],
                    ['notice_type', '公众号客服消息'],
                ])->count() >= 3
            ) {
                $noticeLog->record($to_uid, $title, "发送频繁", $uuid);

                return false;
            } elseif (
                time() <= mktime(18, 0, 0) && NoticeLogModel::where([
                    ['uid', $to_uid],
                    ['title', $title],
                    ['created_at', '>', mktime(18, 0, 0) - 86400],
                    ['notice_type', '公众号客服消息'],
                ])->count() >= 3
            ) {
                $noticeLog->record($to_uid, $title, "发送频繁", $uuid);

                return false;
            }
            $kfcontent = "欢迎{$user->nickname}（ID:{$user->uid}）成为我们的会员。【<a href='https://m.fenpeiduixiang.com/fpdx-attend/index.html#/vip/index'>点此查看</a>】会员特权";
            $result = Kfaccount::text([
                'touser' => $openid,
                'content' => $kfcontent,
                'kf_account' => 'notice@admin',
            ]);
            if ($result['code'] == 0) {
                $noticeLog->record($to_uid, $title, "公众号客服消息", $uuid, 1, $kfcontent);

                return true;
            }

            // 模板消息
            // 限流
            if (
                time() > mktime(18, 0, 0) && NoticeLogModel::where([
                    ['uid', $to_uid],
                    ['created_at', '>', mktime(18, 0, 0)],
                    ['notice_type', '公众号模板消息'],
                ])->count() >= 1
            ) {
                $noticeLog->record($to_uid, $title, "发送频繁", $uuid);

                return false;
            } elseif (
                time() <= mktime(18, 0, 0) && NoticeLogModel::where([
                    ['uid', $to_uid],
                    ['created_at', '>', mktime(18, 0, 0) - 86400],
                    ['notice_type', '公众号模板消息'],
                ])->count() >= 1
            ) {
                $noticeLog->record($to_uid, $title, "发送频繁", $uuid);

                return false;
            }
            $template_id = "alWufNQA9zhVec2RynEUqEUIl2l7TJZjvI6K0YZLzJM";
            $data = [
                'first' => [
                    'value' => "欢迎{$user->nickname}成为我们的会员\n",
                ],
                'keyword1' => [
                    'value' => $user->uid,
                ],
                'keyword2' => [
                    'value' => date('Y-m-d'),
                ],
                'remark' => [
                    'value' => "\n点击查看，会员特权",
                    'color' => "#ff7e98",
                ],
            ];
            $access_token = TokenModel::getToken($public_id);
            $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$access_token}";
            $response = \Curl::to($url)->withData([
                'touser' => $openid,
                'template_id' => $template_id,
                "url" => "https://m.fenpeiduixiang.com/fpdx-attend/index.html#/vip/index",
                "data" => $data,
            ])->asJson()->post();
            if (isset($response->errcode) && !$response->errcode) {
                $noticeLog->record($to_uid, $title, "公众号模板消息", $uuid, 1, $data);

                return true;
            }
        } catch (\Exception $e) {
            app('sentry')->captureException($e);
        }
        $noticeLog->record($to_uid, $title, "发送失败", $uuid);

        return false;
    }

    public function bevip(int $to_uid)
    {
        $nm = new NoticeModel();
        $notice = $nm->fill([
            'uid' => $to_uid,
            'title' => '成功激活VIP普通会员特权',
            'content' => "亲爱的VIP用户，恭喜你，接下来你将享受会员相关特权：1.解锁\"心动我的\"专属进度加成。2.专属活动匹配成功率加成。3.每日专属小fa红包。4.及时的心动消息通知。",
            'type' => 5,
            'type_id' => 0,
            'create_at' => time(),
            'update_at' => time(),
            'tab_content' => '了解详情',
            'tab_url' => '/pages/vip/vip?type=normal',
        ]);
        $notice->save();


        $openidData = User::getOpenidByUid($to_uid);
        $openid = $openidData['openid'];

        $data = [
            'touser' => $openid,
            'content' => "恭喜你！成功激活VIP普通会员资格。从现在开始：你将拥有以下专属特权！\n\n
1.解锁“心动我的”卡片时，可获取VIP专属进度加成。\n\n
2.免费提升在72小时恋爱活动中匹配\"恋爱对象\"以及组CP开黑中匹配\"玩伴\"时的10-20%匹配成功率。\n\n
3.天天领额外小fa红包，每天向分配对象公众号回复关键词：\"红包\"即可获得会员专属随机小fa红包1个！\n\n
点击【<a href='weixin://bizmsgmenu?msgmenucontent=红包&msgmenuid=234234'>这里</a>】领取一个\n\n
4.\"超即时\"心动通知,从现在开始你可以通过分配对象公众号以最及时的方式获取到你关心的通知。让你不错过每一次心动。",
            'kf_account' => 'notice@admin',
        ];
        Kfaccount::text($data);

        $data = [
            'touser' => $openid,
            'content' => "你的会员号是：{$to_uid}。升级「超级会员」，你将拥有更多特权！<a href='https://m.fenpeiduixiang.com/fpdx-attend/index.html#/vip/index'>点击查看</a>",
            'kf_account' => 'notice@admin',
        ];
        Kfaccount::text($data);
    }

    /**
     * 退出会员系统通知
     * @param  int  $to_uid
     */
    public function outvip(int $to_uid)
    {
        $nm = new NoticeModel();
        $notice = $nm->fill([
            'uid' => $to_uid,
            'title' => '会籍取消通知',
            'content' => "很抱歉，因为你已取关了官方公众号「分配对象」，我们不得不取消你的会籍。从现在，你将不能享受会员相关特权：1.专属成功率。2.每日专属小fa红包。3.每日精选日报。4.及时的心动消息通知。重新关注即可立即恢复会籍。",
            'type' => 5,
            'type_id' => 0,
            'create_at' => time(),
            'update_at' => time(),
            'tab_content' => '去激活',
            'tab_url' => '/pages/vip/vip?type=normal',
        ]);
        $notice->save();
    }

    /**
     * 阅读超级心动消息
     * @param  int  $uid
     * @param  int  $like_uid
     * @return bool
     */
    public function readSuperlike(int $uid, int $like_uid)
    {
        $user = UserModel::findOrFail($uid);
        SuperLikeModel::where([
            ['uid', $like_uid],
            ['partner_id', $user->partner_id],
            ['read_at', 0],
        ])->update(['read_at' => time()]);

        return true;
    }

    /**
     * 阅读相互心动消息
     * @param  int  $uid
     * @param  int  $id
     * @return bool
     * @throws AlertException
     */
    public function readEachLikeList(int $uid, int $id)
    {
        $eachlike = EachLikeModel::findOrFail($id);
        if ($uid != $eachlike->tuid) {
            throw new AlertException("无权限", 101);
        }
        if ($eachlike->read_at == 0) {
            $eachlike->read_at = time();
        }
        $eachlike->save();

        return true;
    }

    /**
     * 阅读相互心动消息
     * @param  int  $uid
     * @param  int  $id
     * @return bool
     * @throws AlertException
     */
    public function readSystemList(int $uid, int $id)
    {
        $notice = NoticeModel::findOrFail($id);
        if ($uid != $notice->uid) {
            throw new AlertException("无权限", 101);
        }
        if ($notice->read_at == 0) {
            $notice->read_at = time();
            $notice->save();
        }

        return true;
    }

    /**
     * 超级会员-过期通知
     * @param  int  $to_uid
     */
    public function supvipExpire(int $to_uid)
    {
        $user = UserModel::find($to_uid);
        $payload = [
            'to_user' => $user->getAuth(),
            'user' => $user->toArray(),
        ];
        dispatch(new RegistEventJob(10701, $payload))->onQueue("{push}");

        // 系统消息
        NoticeModel::create([
            'uid' => $to_uid,
            'title' => '超级会员特权即将失效',
            'content' => "你的超级会员特权即将失效，1天后到期。立即续订超级会员，系统将额外赠送最多31天会员时长（过期重新开通不享受赠送）",
            'type' => 5,
            'type_id' => 0,
            'create_at' => time(),
            'update_at' => time(),
            'tab_content' => '查看详情',
            'tab_url' => '/pages/vip/vip?type=super',
        ]);
    }

    /**
     * 超级会员-过期系统通知
     * @param  int  $to_uid
     */
    private function supvipExpireOfsys(int $to_uid)
    {
        $nm = new NoticeModel();
        $notice = $nm->fill([
            'uid' => $to_uid,
            'title' => '超级会员特权即将失效',
            'content' => "你的超级会员特权即将失效，1天后到期。立即续订超级会员，系统将额外赠送最多31天会员时长（过期重新开通不享受赠送）",
            'type' => 5,
            'type_id' => 0,
            'create_at' => time(),
            'update_at' => time(),
            'tab_content' => '查看详情',
            'tab_url' => '/pages/vip/vip?type=super',
        ]);
        $notice->save();
    }
}
