<?php

namespace App\Managers;

use App\Jobs\MockThumbJob;
use App\Models\Deed\FriendsModel;
use App\Models\Deed\InvitationCardModel;
use App\Models\Log\AppSignModel;
use App\Models\Log\FeedLogModel;
use App\Models\PraiseModel;
use App\Models\User\FeedType4RemindModel;
use App\Models\User\InviteConfigModel;
use App\Models\User\LocklikemeModel;
use App\Models\User\SuperLikeModel;
use App\Models\User\UserSysTagModel;
use App\Services\Goodnight\UserService;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use App\Models\User\UserModel;
use App\Models\PartnerModel;
use App\Models\User\Openid;
use App\Models\BlackListModel;
use App\Models\TagModel;

class UserManager
{
    public function fpdxProfile(int $uid)
    {
        $userModel = new UserModel();
        $userModel->initUser($uid);

        $user = UserModel::findOrFail($uid);
        /** @var UserModel $user */
        $user->login_at = time();
        if (in_array(Config::get('platform'), ['ios', 'android'])) {
            $user->login_app_platform = Config::get("platform");
        }
        $user->save();
        if ($inviteConf = InviteConfigModel::find($uid)) {
            $user->task_photo = $inviteConf->task_photo;
            $user->task_question = $inviteConf->task_question;
            $user->task_sing = $inviteConf->task_sing;
            $user->task_question_data = $inviteConf->task_question_data ? true : false;
        } else {
            $user->task_photo = false;
            $user->task_question = false;
            $user->task_sing = false;
        }
        // 普通会员

        // 超级VIP相关
        $superVip = [
            'supvip_endat' => 0,
        ];
        if ($user->supvip_endat > time()) {
            // 累计开通supvip天数
            $systag = UserSysTagModel::where('uid', $uid)->first();
            $superVip['supvip_days'] = $systag ? $systag->supvip_days : 0;
            // 每天心动我的解锁次数
            $superVip['locklikeme_cnt'] = 5 - LocklikemeModel::where([
                    ['uid', $user->uid],
                    ['created_at', '>', mktime(0, 0, 0)],
                    ['origin', 'supvip']
                ])->count();
            // 到期时间
            $superVip['supvip_endat'] = $user->supvip_endat;
        }
        $user->supvip = $superVip;

        // 标签处理
        $tagModel = new TagModel();
        $user->tags = $tagModel->getAllTagByUser($user);
        // 是否关注fpdx
        $user->bind_fpdxfwh = (int)Openid::where([
            ['uid', $uid],
            ['subscribe', 1],
            ['public_id', 'gh_b598cb7474d8']
        ])->exists();
        // 黑名单
        $black = BlackListModel::where('uid', $uid)
            ->where('end_at', '>', time())
            ->whereIn('type', ['msy', 'all'])
            ->first();

        // 卡片和解锁卡统计
        $banner = [
            'is_praises' => 0,
            'charm' => 0,
            'count' => PartnerModel::where([['uid', $uid], ['is_hide', 0]])->count(),
            'black' => $black ? $black->end_at : 0,
        ];
        if ($user->partner_id > 0) {
            $partner = PartnerModel::findOrFail($user->partner_id, ['praises', 'charm']);
            $banner['is_praises'] = $partner->praises;
            $banner['charm'] = $partner->charm;
        }

        $user->lock_card = 0;

        $user->banner = $banner;
        // 黑名单
        $user->black = $user->black();

        // App签到
        $user->app_sign_at = AppSignModel::where('uid', $uid)->where('date', date('Y-m-d'))->first()
            ? mktime(0, 0, 0) + 86400
            : mktime(0, 0, 0);

        MockThumbJob::dispatch($uid)->delay(Carbon::now()->addHours(1));

        $user->course = Redis::getbit("app:course", $uid);
        return $user;
    }

    public function profile(int $uid, $app)
    {
        $userModel = new UserModel();
        $userModel->initUser($uid);

        switch ($app) {
            case "goodnight":
                $user = UserModel::findOrFail($uid, ['uid', 'headimgurl', 'nickname', 'phone', 'sex']);
                /** @var \App\Models\User\UserModel $user */
                $userService = new UserService();
                $userService->getUser($user);
                break;
            case "fpdx":
            default:
                $user = UserModel::findOrFail($uid);
                /** @var UserModel $user */
                $user->login_at = time();
                if (in_array(Config::get("platform"), ['ios', 'android'])) {
                    $user->login_app_platform = Config::get("platform");
                }
                $user->save();
                if ($inviteConf = InviteConfigModel::find($uid)) {
                    $user->setAttribute("task_photo", $inviteConf->task_photo);
                    $user->setAttribute("task_question", $inviteConf->task_question);
                    $user->setAttribute("task_sing", $inviteConf->task_sing);
                    $user->setAttribute("task_paint", $inviteConf->task_paint);
                    $user->setAttribute("task_question_data", $inviteConf->task_question_data ? true : false);
                } else {
                    $user->setAttribute("task_paint", false);
                    $user->setAttribute("task_photo", false);
                    $user->setAttribute("task_question", false);
                    $user->setAttribute("task_sing", false);
                }
                // 超级VIP相关
                $superVip = array('supvip_endat' => 0);
                if ($user->supvip_endat > time()) {
                    // 累计开通supvip天数
                    $systag = UserSysTagModel::where('uid', $uid)->first();
                    if (collect($systag)->isEmpty()) {
                        $superVip['supvip_days'] = 0;
                    } else {
                        $superVip['supvip_days'] = $systag->supvip_days;
                    }
                    // 每天心动我的解锁次数
                    $superVip['locklikeme_cnt'] = 5 - LocklikemeModel::where(array(
                            ['uid', $user->uid],
                            ['created_at', '>', mktime(0, 0, 0)],
                            ['origin', 'supvip']
                        ))->count();
                    // 到期时间
                    $superVip['supvip_endat'] = $user->supvip_endat;
                }
                $user->supvip = $superVip;

                // 标签处理
                $tagModel = new TagModel();
                $user->tags = $tagModel->getAllTagByUser($user);
                // 是否关注fpdx
                $user->bind_fpdxfwh = Openid::where([
                    'uid' => $uid,
                    'subscribe' => 1,
                    'public_id' => 'gh_b598cb7474d8'
                ])->exists() ? 1 : 0;

                // 卡片和解锁卡统计
                $banner = array(
                    'is_praises' => 0,
                    'charm' => 0
                );
                if ($user->partner_id > 0) {
                    $partner = PartnerModel::findOrFail($user->partner_id, ['praises', 'charm']);
                    $banner['is_praises'] = $partner->praises;
                    $banner['charm'] = $partner->charm;
                }

                $user->lock_card = 0;
                $banner['count'] = PartnerModel::where([['uid', $uid], ['is_hide', 0]])->count();
                // 黑名单
                $blacklistModel = new BlackListModel();
                $black = $blacklistModel->where([['uid', $uid], ['end_at', '>', time()]])
                    ->whereIn('type', ['msy', 'all'])->first();
                if (collect($black)->isEmpty()) {
                    $banner['black'] = 0;
                } else {
                    $banner['black'] = $black->end_at;
                }
                $user->banner = $banner;
                // 黑名单
                $user->black = $user->black();

                // App签到
                $user->app_sign_at = AppSignModel::where('uid', $uid)->where('date', date('Y-m-d'))->first()
                    ? mktime(0, 0, 0) + 86400
                    : mktime(0, 0, 0);

                MockThumbJob::dispatch($uid)->delay(Carbon::now()->addHours(1));
                break;
        }
        $user->course = Redis::getbit("app:course", $uid);
        return $user;
    }


    /**
     * 获取心动我的列表（分页）
     * @param  int  $uid
     * @param  int  $page
     * @param  int  $limit
     * @return array
     */
    public function getLikeMeList(int $uid, $page, $limit = 20): array
    {
        $user = UserModel::findOrFail($uid);
        $datas = collect(array());
        $total = 0;
        if ($user->partner_id > 0) {
            $total = 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],
                    ['partner.is_sell', 1],
                    ['praise.type', 1],
                ))->count();
            $datas = DB::table('kdgx_partner_charge_praise as praise')
                ->join('kdgx_partner_charge_partner as partner', 'praise.uid', '=', 'partner.uid')
                ->selectRaw("praise.lock, praise.read, praise.id as praise_id, partner.id, partner.uid, partner.photo_src, partner.check_photo, 
                partner.voice, partner.voice_check, partner.photo_1, partner.photo_1_check, partner.photo_2, partner.photo_2_check, partner.photo_3, partner.photo_3_check, partner.photo_4, partner.photo_4_check,
                partner.black_at,partner.is_sell,partner.praises, praise.updated_at")
                ->where(array(
                    ['praise.partner_id', $user->partner_id],
                    ['partner.is_sell', 1],
                    ['praise.type', 1],
                ))->skip(($page - 1) * $limit)
                ->take($limit)
                ->orderBy('praise.updated_at', 'desc')
                ->get();
        }

        $lookmeuid = array();
        if (!$datas->isEmpty() && $page * $limit >= $total) {
            if (PraiseModel::where([['uid', $uid], ['partner_id', 1], ['type', 1]])->exists()) {
                $partner = PartnerModel::findOrFail(
                    1,
                    ['id', 'uid', 'photo_src', 'voice', 'photo_1', 'photo_2', 'photo_3', 'photo_4']
                );
                $datas->push($partner);
            }
            if (PraiseModel::where([['uid', $uid], ['partner_id', 2], ['type', 1]])->exists()) {
                $partner = PartnerModel::findOrFail(
                    2,
                    ['id', 'uid', 'photo_src', 'voice', 'photo_1', 'photo_2', 'photo_3', 'photo_4']
                );
                $datas->push($partner);
            }
        }
        foreach ($datas as &$data) {
            $data->photo_src = empty($data->photo_src) ? null : "https://oss.pocketuniversity.cn{$data->photo_src}";
            $data->photo_1 = empty($data->photo_1) ? null : "https://oss.pocketuniversity.cn{$data->photo_1}";
            $data->photo_2 = empty($data->photo_2) ? null : "https://oss.pocketuniversity.cn{$data->photo_2}";
            $data->photo_3 = empty($data->photo_3) ? null : "https://oss.pocketuniversity.cn{$data->photo_3}";
            $data->photo_4 = empty($data->photo_4) ? null : "https://oss.pocketuniversity.cn{$data->photo_4}";
            if (1 != $data->check_photo) {
                unset($data->photo_src);
            }
            if (1 != $data->photo_1_check) {
                unset($data->photo_1);
            }
            if (1 != $data->photo_2_check) {
                unset($data->photo_2);
            }
            if (1 != $data->photo_3_check) {
                unset($data->photo_3);
            }
            if (1 != $data->photo_4_check) {
                unset($data->photo_4);
            }
            if (1 != $data->voice_check) {
                unset($data->voice);
            }
            unset($data->check_photo);
            unset($data->photo_1_check);
            unset($data->photo_2_check);
            unset($data->photo_3_check);
            unset($data->photo_4_check);
            unset($data->voice_check);
            $data->user = UserModel::find($data->uid, [
                'uid',
                'nickname',
                'headimgurl',
                'sex',
                'be_vip_at',
                'supvip_endat',
                'identity_auth',
                'wx_auth',
                'login_at'
            ]);
            if (FriendsModel::where([['uid', $data->uid], ['friend_uid', $uid]])->exists()) {
                $data->lock = 100;
            }
            $data->remind = FeedType4RemindModel::where([
                'uid' => $uid,
                'is_remind_uid' => $data->uid,
                'type' => 3
            ])->exists() ? true : false;
            $data->superlike = SuperLikeModel::where([
                ['uid', $data->uid],
                ['partner_id', $user->partner_id]
            ])->exists() ? true : false;
            array_push($lookmeuid, $data->uid);
        }
        $unreads = DB::table('kdgx_partner_charge_praise as praise')
            ->join('kdgx_partner_charge_partner as partner', 'praise.uid', '=', 'partner.uid')
            ->selectRaw("partner.id")
            ->where(array(['praise.partner_id', $user->partner_id], ['praise.type', 1], ['read', 0]))
            ->get()
            ->pluck('id');

        PraiseModel::where('partner_id', $user->partner_id)->update(['read' => 1]);

        return array(
            'pages' => array(
                'page' => $page,
                'limit' => $limit,
                'total' => $total + 1
            ),
            'tag_count' => count($unreads),
            'list' => $datas,
            'unread_list' => $unreads
        );
    }


    /**
     * 获取我喜欢的列表
     * @param  int  $uid
     * @param  int  $page
     * @param  int  $limit
     * @return array
     */
    public function getMyLikeList(int $uid, $page, $limit = 20): array
    {
        $total = 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();
        $datas = DB::table('kdgx_partner_charge_praise as praise')
            ->join('kdgx_partner_charge_partner as partner', 'praise.partner_id', '=', 'partner.id')
            ->select(DB::raw("partner.id, praise.type, praise.id as praise_id, partner.uid, partner.school, partner.sex, 
                partner.age, partner.star, partner.photo_src, partner.check_photo, partner.voice, partner.voice_check,
                partner.photo_1, partner.photo_1_check, partner.photo_2, partner.photo_2_check, partner.photo_3, partner.photo_3_check,
                partner.photo_4, partner.photo_4_check, partner.is_sell, partner.black_at, partner.praises, praise.updated_at"))->where([
                ['praise.uid', $uid],
                ['type', 1],
                ['is_sell', 1],
                ['is_hide', 0]
            ])
            ->skip(($page - 1) * $limit)
            ->take($limit)
            ->orderBy('praise.updated_at', 'desc')
            ->get();

        foreach ($datas as &$data) {
            $data->photo_src = "https://oss.pocketuniversity.cn{$data->photo_src}";
            $data->photo_1 = "https://oss.pocketuniversity.cn{$data->photo_1}";
            $data->photo_4 = "https://oss.pocketuniversity.cn{$data->photo_4}";
            $data->photo_2 = "https://oss.pocketuniversity.cn{$data->photo_2}";
            $data->photo_3 = "https://oss.pocketuniversity.cn{$data->photo_3}";
            if (1 != $data->check_photo) {
                unset($data->photo_src);
            }
            if (1 != $data->photo_1_check) {
                unset($data->photo_1);
            }
            if (1 != $data->photo_2_check) {
                unset($data->photo_2);
            }
            if (1 != $data->photo_3_check) {
                unset($data->photo_3);
            }
            if (1 != $data->photo_4_check) {
                unset($data->photo_4);
            }
            if (1 != $data->voice_check) {
                unset($data->voice);
            }
            unset($data->check_photo);
            unset($data->photo_1_check);
            unset($data->photo_2_check);
            unset($data->photo_3_check);
            unset($data->photo_4_check);
            unset($data->voice_check);
            try {
                $data->user = UserModel::findOrFail($data->uid, [
                    'uid',
                    'headimgurl',
                    'nickname',
                    'login_at',
                    'age',
                    'star',
                    'introduce',
                    'expect',
                    'height',
                    'sex',
                    'school',
                    'address',
                    'home',
                    'tag_1',
                    'tag_2',
                    'tag_3',
                    'tag_4',
                    'be_vip_at',
                    'supvip_endat',
                    'identity_auth',
                    'wx_auth'
                ]);
                $data->user->invite_cnt = InvitationCardModel::where('invite_uid', $data->uid)->count();
            } catch (\Exception $e) {
                $data->user = null;
            }
            $data->is_self = ($uid == $data->uid) ? 1 : 0;
            $data->remind = FeedType4RemindModel::where([
                'uid' => $uid,
                'is_remind_uid' => $data->uid,
                'type' => 2
            ])->exists() ? true : false;
        }
        return array(
            'pages' => array(
                'page' => $page,
                'limit' => $limit,
                'total' => $total
            ),
            'list' => $datas
        );
    }


    /**
     * 获取访客列表
     * @param  int  $uid
     * @param $page
     * @param  int  $limit
     * @return array
     */
    public function getVisitorList(int $uid, $page, $limit = 20): array
    {
        $user = UserModel::findOrFail($uid);
        $uids = PraiseModel::where('partner_id', $user->partner_id)->get()->pluck('uid')->toArray();
        $total = FeedLogModel::whereHas('uidPartner', function (/** @var Builder $query */ $query) {
            $query->where('is_sell', 1);
        })
            ->whereNotIn('uid', $uids)
            ->where('partner_id', $user->partner_id)
            ->distinct()
            ->count();
        $innerDB = FeedLogModel::whereHas('uidPartner', function (/** @var Builder $query */ $query) {
            $query->where('is_sell', 1);
        })
            ->whereNotIn('uid', $uids)
            ->where('partner_id', $user->partner_id)
            ->orderBy('id');
        $innerSql = $innerDB->toSql();
        $innerBind = $innerDB->getBindings();
        $offset = ($page - 1) * $limit;
        $sql = "SELECT tab.uid, tab.created_at, count(*) as count FROM($innerSql) as tab group by `uid` ORDER BY `created_at` DESC limit {$limit} offset $offset";
        $feeds = Collection::make(DB::select($sql, $innerBind));

        $users = UserModel::whereIn('uid', $feeds->pluck('uid'))
            ->get(['uid', 'nickname', 'headimgurl', 'sex'])
            ->toArray();
        $users = array_combine(array_column($users, 'uid'), $users);

        $feeds->map(function ($value) use ($users) {
            $value->users = $users[$value->uid];
        });

        return [
            'total' => $total,
            'page' => $page,
            'limit' => $limit,
            'list' => $feeds
        ];
    }

    /**
     * 通过IMAccount获取uid
     * @param string $IMAccount im账号
     * @return int 用户uid；0=未绑定的im账号
     */
    public function getUidByIMAccount(string $IMAccount): int
    {
        $user = UserModel::where('im_account', $IMAccount)->first();
        if ($user) {
            return $user->uid;
        } else {
            return 0;
        }
    }
}
