<?php

namespace App\Services\Deed;

use App\Events\EachLike;
use App\Events\UnEachLike;
use App\Models\Deed\EachLikeModel;
use App\Models\Deed\FriendsLogModel;
use App\Models\Deed\FriendsModel;
use App\Models\Deed\InvitationCardModel;
use App\Models\Fpdx\PairModel;
use App\Models\Fpdx\RoomModel as PairRoomModel;
use App\Models\Goodnight\RoomMemberModel as goodnightMemberModel;
use App\Models\Goodnight\RoomModel as goodnightRoomModel;
use App\Models\Gteam\RoomMemberModel as gameMemberModel;
use App\Models\Gteam\RoomModel as gameRoomModel;
use App\Models\Log\ClickUserHomeLogModel;
use App\Models\NoticeModel;
use App\Models\PraiseModel;
use App\Models\User\LikeInviteQuestionModel;
use App\Models\User\UserModel;
use App\Services\Service;
use Illuminate\Support\Facades\DB;

class FriendService extends Service
{
    public function overview(int $uid)
    {
        /** @var UserModel $user */
        $user = UserModel::findOrFail($uid);
        $friendCnt = FriendsModel::where([['uid', $uid], ['is_hide', 0]])->count();
        $clickMeCount = ClickUserHomeLogModel::where([
                ['home_uid', $uid],
                ['created_at', '>', time() - 86400 * 7],
            ])->count() + 3;
        $likeMeCount = 0;
        if ($user->partner_id > 0) {
            $likeMeCount = DB::table('kdgx_partner_charge_praise as praise')
                ->join('kdgx_partner_charge_partner as partner', 'praise.uid', '=', 'partner.uid')
                ->where(array(['praise.partner_id', $user->partner_id], ['praise.type', 1]))
                ->count();
        }
        $myLikeCount = DB::table('kdgx_partner_charge_praise as praise')
            ->join('kdgx_partner_charge_partner as partner', 'praise.partner_id', '=', 'partner.id')
            ->where([['praise.uid', $uid], ['type', 1], ['is_sell', 1]])->count();

        return array(
            'clickme' => $clickMeCount,
            'friend' => $friendCnt,
            'likeme' => $likeMeCount,
            'ilike' => $myLikeCount,
        );
    }

    /**
     * 好友列表数字 全部：未读 | 相互喜欢：未读 | 收到邀请：未读 | 发出邀请：未读
     * @param  int  $uid
     * @return array
     */
    public function getListCnt(int $uid)
    {
        $user = UserModel::findOrFail($uid);
        $like_me = PraiseModel::where([['read', 0], ['partner_id', $user->partner_id], ['type', 1]])->count();
        $eachlike = EachLikeModel::where([['tuid', $uid], ['read_at', 0], ['state', 1]])->count();
        $invite_me = InvitationCardModel::where([
            ['read', 0],
            ['state', 0],
            ['invite_uid', $uid],
            ['expired_at', '>', time()],
        ])->count();
        $send_invite = InvitationCardModel::where([['send_read', 0], ['uid', $uid]])->count();
        $sys_notice = NoticeModel::where([['uid', $uid], ['is_read', 0]])->count();

        return array(
            'all' => $eachlike + $invite_me + $send_invite,
            'each_like' => $eachlike,
            'invite_me' => $invite_me,
            'send_invite' => $send_invite,
            'like_me' => $like_me,
            'sys_notice' => $sys_notice,
        );
    }

    /**
     * 全部好友列表
     * @param  int  $uid
     * @param  array  $pages
     * @return array
     */
    public function getAllList(int $uid, array $pages)
    {
        $total = FriendsModel::where([['uid', $uid], ['is_hide', 0]])->count();
        $datas = FriendsModel::where([['uid', $uid], ['is_hide', 0]])->orderBy(
            'last_at',
            'desc'
        )->skip(($pages['page'] - 1) * $pages['limit'])->take($pages['limit'])->get();

        foreach ($datas as &$data) {
            $data->read_at = 1;
            /** @var FriendsModel $data */
            try {
                $data->friend = UserModel::find($data->friend_uid, [
                    'uid',
                    'headimgurl',
                    'nickname',
                    'sex',
                    'weixin',
                    'qq',
                    'identity_auth',
                    'wx_auth',
                    'be_vip_at',
                    'supvip_endat',
                ]);
                switch ($data->friend_type) {
                    case 0: // 相互喜欢
                        $each = EachLikeModel::find($data->friend_type_data);
                        if (collect($each)->isNotEmpty() && $uid == $each->tuid) {
                            $data->read_at = $each->read_at;
                        } else {
                            $data->read_at = 1;
                        }
                        break;
                    case 1: // 心动邀请
                    case 6: // 被心动邀请
                        $invite = InvitationCardModel::find($data->friend_type_data);
                        if (collect($invite)->isNotEmpty() && $uid == $invite->uid) {
                            $data->read_at = $invite->send_read;
                        } else {
                            $data->read_at = $invite->read;
                        }
                        break;
                    case 8: // 被取消心动
                        $data->read_at = $data->unread_cnt > 0 ? 0 : 2;
                        break;
                    case 2: // 活动72h匹配
                    case 3: // 晚安匹配
                    case 4: // 开黑匹配
                    case 5: // 开黑wz匹配
                    case 7: // 取消心动
                    default:
                        $data->read_at = 1;
                        break;
                }
            } catch (\Exception $exception) {
            }
        }

        return array(
            'total' => $total,
            'page' => $pages['page'],
            'limit' => $pages['limit'],
            'list' => $datas,
        );
    }

    /**
     * 相互喜欢列表
     * @param  int  $uid
     * @param  array  $pages
     * @return array
     */
    public function getEachLikeList(int $uid, array $pages)
    {
        $total = EachLikeModel::where([['uid', $uid], ['state', 1]])->orWhere([['tuid', $uid], ['state', 1]])->count();
        $datas = EachLikeModel::where([['uid', $uid], ['state', 1]])->orWhere([
            ['tuid', $uid],
            ['state', 1],
        ])->orderBy('id', 'desc')->skip(($pages['page'] - 1) * $pages['limit'])->take($pages['limit'])->get();

        foreach ($datas as &$data) {
            try {
                $tuid = $data->tuid;
                if ($data->tuid == $uid) {
                    $tuid = $data->uid;
                } else {
                    $data->read_at = 1;
                }
                $data->friend = UserModel::findOrFail($tuid, [
                    'uid',
                    'headimgurl',
                    'nickname',
                    'sex',
                    'weixin',
                    'identity_auth',
                    'wx_auth',
                    'be_vip_at',
                    'supvip_endat',
                ]);
            } catch (\Exception $exception) {
                app('sentry')->captureException($exception);
                $data->friend = null;
            }
        }

        return array(
            'total' => $total,
            'page' => $pages['page'],
            'limit' => $pages['limit'],
            'list' => $datas,
        );
    }

    /**
     * 星标好友列表
     * @param  int  $uid
     * @param  array  $pages
     * @return array
     */
    public function getStarList(int $uid, array $pages)
    {
        $total = FriendsModel::where([['uid', $uid], ['star_at', '>', 0], ['is_hide', 0]])->count();
        $datas = FriendsModel::where([['uid', $uid], ['star_at', '>', 0], ['is_hide', 0]])->orderBy(
            'last_at',
            'desc'
        )->skip(($pages['page'] - 1) * $pages['limit'])->take($pages['limit'])->get();

        foreach ($datas as &$data) {
            $data->read_at = 1;
            /** @var FriendsModel $data */
            try {
                $data->friend = UserModel::findOrFail($data->friend_uid, [
                    'uid',
                    'headimgurl',
                    'nickname',
                    'sex',
                    'weixin',
                    'identity_auth',
                    'wx_auth',
                    'be_vip_at',
                    'supvip_endat',
                ]);
                switch ($data->friend_type) {
                    case 0: // 相互喜欢
                        $each = EachLikeModel::find($data->friend_type_data);
                        if ($each->isNotEmpty() && $uid == $each->tuid) {
                            $data->read_at = $each->read_at;
                        } else {
                            $data->read_at = 1;
                        }
                        break;
                    case 1: // 心动邀请
                    case 6: // 被心动邀请
                        $invite = InvitationCardModel::findOrFail($data->friend_type_data);
                        if ($uid == $invite->uid) {
                            $data->read_at = $invite->send_read;
                        } else {
                            $data->read_at = $invite->read;
                        }
                        break;
                    case 8:
                        $data->read_at = $data->unread_cnt > 0 ? 0 : 2;
                        break;
                    case 7:
                    case 2: // 活动72h匹配
                    case 3: // 晚安匹配
                    case 4: // 开黑匹配
                    case 5: // 开黑wz匹配
                    default:
                        $data->read_at = 1;
                        break;
                }
            } catch (\Exception $exception) {
                $data->friend = null;
            }
        }

        return array(
            'total' => $total,
            'page' => $pages['page'],
            'limit' => $pages['limit'],
            'list' => $datas,
        );
    }

    /**
     * 标记相互喜欢
     * @param  int  $uid
     * @param  int  $partner_id
     * @param  int  $thumb
     * @return UserModel|bool
     */
    public function eachlike(int $uid, int $partner_id, int $thumb)
    {
        /** @var UserModel $user */
        $user = UserModel::findOrFail($uid);
        /** @var UserModel $puser */
        $puser = UserModel::where('partner_id', $partner_id)->firstOrFail([
            'uid',
            'nickname',
            'headimgurl',
            'sex',
            'weixin',
            'qq',
            'identity_auth',
            'wx_auth',
            'be_vip_at',
            'supvip_endat',
        ]);
        $eachlike = EachLikeModel::where(array(['uid', $user->uid], ['tuid', $puser->uid]))
            ->orWhere(array(['uid', $puser->uid], ['tuid', $user->uid]))->first();
        if (collect($eachlike)->isEmpty()) {
            if (0 == $thumb) {
                return false;
            }
            if (PraiseModel::where([['uid', $puser->uid], ['partner_id', $user->partner_id], ['type', 1]])->exists()) {
                EachLikeModel::firstOrCreate(
                    ['uid' => $user->uid, 'tuid' => $puser->uid],
                    [
                        'created_at' => time(),
                        'updated_at' => time(),
                        'read_at' => 0,
                        'state' => 1,
                        'tuid' => $puser->uid,
                    ]
                );
                // log=你和xxx相互心动
                event(new EachLike($uid, $puser->uid));
                $ns = new NoticeService();
                $ns->eachLike($puser->uid, $uid);

                return $puser;
            }
        } else {
            if (0 == $thumb && 1 == $eachlike->state) {
                $eachlike->state = 0;
                $eachlike->read_at = 0;
                $eachlike->updated_at = time();
                $eachlike->save();
                // log=xxx取消了对你的心动
                event(new UnEachLike($uid, $puser->uid));

                return false;
            }
            if (PraiseModel::where([['uid', $puser->uid], ['partner_id', $user->partner_id], ['type', 1]])->exists()) {
                $eachlike->state = 1;
                $eachlike->read_at = 0;
                $eachlike->updated_at = time();
                $eachlike->save();
                // log=你和xxx相互心动
                event(new EachLike($uid, $puser->uid));
                $ns = new NoticeService();
                $ns->eachLike($puser->uid, $uid);

                return $puser;
            }
        }

        return false;
    }

    /**
     * 好友关系维护-取消心动
     * @param  int  $uid
     * @param  int  $friend_uid
     */
    public function unEachLike(int $uid, int $friend_uid)
    {
        if ($uid == $friend_uid) {
            return;
        }
        FriendsModel::where([['uid', $uid], ['friend_uid', $friend_uid]])->update([
            'friend_type' => 7,
            'last_at' => time(),
        ]);
        FriendsModel::where([['uid', $friend_uid], ['friend_uid', $uid]])->update([
            'friend_type' => 8,
            'last_at' => time(),
            'unread_cnt' => 1,
        ]);
        // 邀请
        $blInvite = InvitationCardModel::where([['uid', $uid], ['invite_uid', $friend_uid], ['state', 1]])
            ->orWhere([['uid', $friend_uid], ['invite_uid', $uid], ['state', 1]])->exists();
        // 开黑
        $blGteam = !empty((new gameMemberModel())->friendRooms($uid, $friend_uid));
        // 晚安
        $blGoodnight = !empty((new goodnightMemberModel())->friendRooms($uid, $friend_uid));
        // 72h
        $blPair = PairRoomModel::where('type', 1)->where('member', "{$uid},{$friend_uid}")->orWhere(
            'member',
            "{$friend_uid},{$uid}"
        )->exists();

        if (!($blInvite || $blGteam || $blGoodnight || $blPair)) {
            FriendsModel::where([['uid', $uid], ['friend_uid', $friend_uid]])->update(['is_friend' => 0]);
            FriendsModel::where([['uid', $friend_uid], ['friend_uid', $uid]])->update(['is_friend' => 0]);
        }

        return;
    }

    /**
     * 成为好友
     * @param  int  $uid
     * @param  int  $friend_uid
     * @param  int  $friend_type
     * @param $friend_type_data
     * @return bool
     */
    public function befriend(int $uid, int $friend_uid, int $friend_type, $friend_type_data)
    {
        if ($uid == $friend_uid) {
            return false;
        }

        $type1 = $type2 = $friend_type;

        if ($friend_type == 1) {
            $type2 = 6;
        }

        if ($friend_type == 6) {
            $type2 = 1;
        }

        FriendsModel::updateOrCreate([
            'uid' => $uid,
            'friend_uid' => $friend_uid,
        ], [
            'created_at' => time(),
            'uid' => $uid,
            'friend_uid' => $friend_uid,
            'last_at' => time(),
            'friend_type' => $type1,
            'friend_type_data' => $friend_type_data,
        ]);
        FriendsModel::updateOrCreate([
            'uid' => $friend_uid,
            'friend_uid' => $uid,
        ], [
            'created_at' => time(),
            'uid' => $friend_uid,
            'friend_uid' => $uid,
            'last_at' => time(),
            'friend_type' => $type2,
            'friend_type_data' => $friend_type_data,
        ]);

        $user = UserModel::findOrFail($uid);
        $friend = UserModel::findOrFail($friend_uid);
        PraiseModel::where([['uid', $user->uid], ['partner_id', $friend->partner_id]])->update(['lock' => 100]);
        PraiseModel::where([['uid', $friend->uid], ['partner_id', $user->partner_id]])->update(['lock' => 100]);

        return true;
    }

    /**
     * 获取好友交互历史
     * @param  int  $uid
     * @param  int  $friend_uid
     * @return \Illuminate\Support\Collection
     */
    public function history(int $uid, int $friend_uid)
    {
        if ($uid == $friend_uid) {
            return collect();
        }
        FriendsModel::where('uid', $uid)->update(['unread_cnt' => 0]);

        $my_invites = InvitationCardModel::where([['uid', $uid], ['invite_uid', $friend_uid]])
            ->select(
                'id',
                'created_at',
                'state',
                'expired_at',
                'receive_at',
                'read',
                'question_id',
                'question_type',
                'question_answer',
                'say_hello',
                'kk',
                'paint_id',
                'request_content',
                'response_content'
            )
            ->get()->map(function ($value) use ($uid) {
                /** @var InvitationCardModel $value */
                if ($value->state == 1 && $value->send_read == 0) {
                    $value->send_read = 1;
                    $value->save();
                }
                $question = LikeInviteQuestionModel::withTrashed()->find($value->question_id);
                $value->question_uid = $question ? $question->uid : 1;
                $value->voice_src = $question ? $question->voice_src : '';
                $value->thumbs = $question ? $question->thumbs : 0;
                $value->question = $question ? json_decode($question->question, true) : null;

                switch ($value->question_type) {
                    case '4':
                    case '3':
                        break;
                }

                return collect($value)->put('origin', 'my_invite');
            });

        $friend_invites = InvitationCardModel::where([['uid', $friend_uid], ['invite_uid', $uid]])
            ->where('state', '>=', 0)
            ->select(
                'id',
                'created_at',
                'state',
                'expired_at',
                'receive_at',
                'read',
                'question_id',
                'question_type',
                'question_answer',
                'say_hello',
                'kk',
                'paint_id',
                'request_content',
                'response_content'
            )
            ->get()->map(function ($value) use ($uid) {
                /** @var InvitationCardModel $value */
                if ($value->state == 0 && $value->read == 0) {
                    $value->read = 1;
                    $value->save();
                }
                $question = LikeInviteQuestionModel::withTrashed()->find($value->question_id);
                $value->question_uid = $question ? $question->uid : 1;
                $value->voice_src = $question ? $question->voice_src : '';
                $value->thumbs = $question ? $question->thumbs : 0;
                $value->question = $question ? json_decode($question->question, true) : null;


                switch ($value->question_type) {
                    case '4':
                    case '3':
                        break;
                }


                return collect($value)->put('origin', 'friend_invite');
            });

        $game_rooms = gameRoomModel::find(
            (new gameMemberModel())->friendRooms($uid, $friend_uid),
            ['id', 'created_at', 'type']
        )
            ->map(function ($room) {
                if (in_array($room->type, ['cj_wx', 'cj_qq'])) {
                    return collect($room)->put('origin', 'game_cj');
                } else {
                    return collect($room)->put('origin', 'game_wz');
                }
            });
        $night_rooms = goodnightRoomModel::find(
            (new goodnightMemberModel())->friendRooms($uid, $friend_uid),
            ['id', 'created_at']
        )
            ->map(function ($room) {
                return collect($room)->put('origin', 'goodnight');
            });

        $pair_rooms = PairRoomModel::select(['created_at', 'room_id as id', 'stage_id'])->where(
            'type',
            1
        )->where('member', "{$uid},{$friend_uid}")->orWhere('member', "{$friend_uid},{$uid}")->get()
            ->map(function ($room) {
                /** @var PairRoomModel $room */
                if (PairModel::where(['room_id' => $room->id])->value('activity_type') == 'qbj') {
                    return collect($room)->put('origin', 'qbj');
                } else {
                    return collect($room)->put('origin', 'pair');
                }
            });

        EachLikeModel::where([['uid', $friend_uid], ['tuid', $uid], ['read_at', 0]])->update(['read_at' => time()]);
        $each_likes = FriendsLogModel::select([
            'id',
            'created_at',
            'uid',
            'tuid',
            'do',
            'log',
            'read_at',
        ])->where([['uid', $uid], ['tuid', $friend_uid]])
            ->orWhere(array(['uid', $friend_uid], ['tuid', $uid]))->get()->map(function ($value) use ($uid) {
                /** @var FriendsLogModel $value */
                if ($uid == $value->tuid && $value->read_at == 0) {
                    $value->read_at = time();
                    $value->save();
                }

                return collect($value)->put('origin', 'eachlike');
            });

        return collect()->merge($my_invites)->merge($friend_invites)->merge($game_rooms)->merge($night_rooms)
            ->merge($pair_rooms)
            ->merge($each_likes)
            ->sortByDesc('created_at')
            ->values()->all();
    }
}
