<?php

namespace App\Http\Services\V1_1;

use App\Generated\V1_1\DTOs\UidImAccountDTO;
use App\Generated\V1_1\Messages\User\UidTranslationImAccountMessage;
use App\Generated\V1_1\DTOs\ProfileUserDTO;
use App\Generated\V1_1\Messages\User\RefreshMessage;
use App\Generated\V1_1\DTOs\BannerDTO;
use App\Generated\V1_1\DTOs\BlackDTO;
use App\Generated\V1_1\DTOs\FpdxProfileDTO;
use App\Generated\V1_1\DTOs\SupvipDTO;
use App\Generated\V1_1\Messages\User\ProfileMessage;
use App\Jobs\MockThumbJob;
use App\Managers\UserManager;
use App\Models\BlackListModel;
use App\Models\Interlocution\AnswerModel;
use App\Models\Interlocution\QuestionModel;
use App\Models\Log\AppSignModel;
use App\Models\PartnerModel;
use App\Models\TagModel;
use App\Models\User\InviteConfigModel;
use App\Models\User\LocklikemeModel;
use App\Models\User\Openid;
use App\Models\User\UserModel;
use App\Models\User\UserSysTagModel;
use App\Utils\ImUtil;
use Config;
use App\Http\Controllers\Core\Auth;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Redis;
use App\Generated\V1_1\Messages\User\ToggleTagMessage;
use App\Generated\V1_1\Messages\User\UpdateProfileMessage;
use App\Exceptions\AlertException;
use App\Jobs\StoreSelfPartnerJob;
use App\Models\NoticeModel;
use App\Services\Goodnight\UserService as GoodNightUserService;
use App\Services\User\ProfileService;
use Exception;
use App\Generated\V1_1\Messages\User\StoreSelfPartnerMessage;
use App\Generated\V1_1\Messages\User\GetFpdxProfileMessage;
use App\Generated\V1_1\Messages\User\CreateAnswerMessage;
use App\Generated\V1_1\Messages\User\GetQuestionInfoMessage;
use App\Generated\V1_1\Messages\User\GetQuestionAnswerListMessage;
use App\Generated\V1_1\Messages\User\GetQuestionListMessage;
use App\Generated\V1_1\Messages\User\DeletePhotosMessage;
use App\Generated\V1_1\Messages\User\SelectCoverMessage;

class UserService
{
    protected $userManager;
    public function __construct(UserManager $userManager)
    {
        $this->userManager = $userManager;
    }
    public function refresh(RefreshMessage $message)
    {
        $uid = Auth::auth();
        $imUtil = new ImUtil();
        $user = UserModel::findOrFail($uid);
        if ($user->im_account) {
            $imSig = $imUtil->registerUser($user->im_account, $user->nickname, $user->headimgurl, $user->sex, 0);
            $user->im_sig = $imSig;
        } else {
            $user->im_account = md5(config('app.env') . $user->uid);
            $imSig = $imUtil->registerUser($user->im_account, $user->nickname, $user->headimgurl, $user->sex, 0);
            $user->im_sig = $imSig;
        }
        $user->save();
        $message->setResponse($user->uid, $user->im_account, $user->im_sig);
    }
    public function profile(ProfileMessage $message)
    {
        $model = $message->getModel() ?: 'fpdx';
        $uid = Auth::auth();
        $user = $this->userManager->profile($uid, $model);
        $message->setResponse(ProfileUserDTO::initFromEloquent($user));
    }
    public function getFpdxProfile(GetFpdxProfileMessage $message)
    {
        $uid = Auth::auth();
        $userModel = new UserModel();
        $userModel->initUser($uid);
        $user = UserModel::findOrFail($uid);
        /** @var UserModel $user */
        $user->login_at = time();
        $platform = Config::get('platform');
        if (in_array($platform, ['ios', 'android'])) {
            $user->login_app_platform = $platform;
        }
        $user->save();
        $inviteConf = InviteConfigModel::find($uid);
        $user->task_photo = $inviteConf->task_photo ?? false;
        $user->task_question = $inviteConf->task_question ?? false;
        $user->task_sing = $inviteConf->task_sing ?? false;
        $user->task_question_data = (bool) $inviteConf->task_question_data;
        // 普通会员
        // 超级VIP相关
        $supvip = ['supvip_endat' => 0];
        if ($user->supvip_endat > time()) {
            // 累计开通supvip天数
            $systag = UserSysTagModel::where('uid', $uid)->first();
            $supvip['supvip_days'] = $systag ? $systag->supvip_days : 0;
            // 每天心动我的解锁次数
            $supvip['locklikeme_cnt'] = 5 - LocklikemeModel::where([['uid', $user->uid], ['created_at', '>', mktime(0, 0, 0)], ['origin', 'supvip']])->count();
            // 到期时间
            $supvip['supvip_endat'] = $user->supvip_endat;
        }
        // 标签处理
        $tagModel = new TagModel();
        $tags = $tagModel->getAllTagByUser($user);
        // 是否关注fpdx
        $bindFpdxfwh = (int) Openid::where([['uid', $uid], ['subscribe', 1], ['public_id', 'gh_b598cb7474d8']])->exists();
        // 卡片和解锁卡统计
        /** @var PartnerModel $partner */
        $partner = PartnerModel::findOrFail($user->partner_id, ['praises', 'charm']);
        $banner = [
            'is_praises' => $partner->praises ?? 0,
            'charm' => $partner->charm ?? 0,
            'count' => PartnerModel::where([['uid', $uid], ['is_hide', 0]])->count(),
            // 黑名单
            'black' => BlackListModel::where('uid', $uid)->where('end_at', '>', time())->whereIn('type', ['msy', 'all'])->first()->end_at ?? 0,
        ];
        $lockCard = 0;
        // 黑名单
        $black = $user->black();
        // App签到
        $appSignAt = 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));
        $course = Redis::getbit("app:course", $uid);
        $message->setResponse(FpdxProfileDTO::initFromEloquent($user), SupvipDTO::initFromEloquent($supvip), $bindFpdxfwh, $lockCard, BannerDTO::initFromEloquent($banner), BlackDTO::initFromEloquent($black), $appSignAt, $course, $tags);
    }
    public function toggleTag(ToggleTagMessage $message)
    {
        $tagId = $message->getTagId();
        $group = $message->getGroup();
        $uid = Auth::auth();
        $ps = new ProfileService();
        $ps->toggleTag($uid, $tagId, $group);
    }
    /**
     * @param  UpdateProfileMessage  $message
     * @throws AlertException
     * @throws \AlicFeng\IdentityCard\Exception\BirthdayException
     */
    public function updateProfile(UpdateProfileMessage $message)
    {
        $request = $message->getRequest();
        $uid = Auth::auth();
        /** @var UserModel $user */
        $user = UserModel::findOrFail($uid);
        // 更新基础数据
        $basedata = $request->only(['nickname', 'headimgurl', 'sex']);
        if (!empty($basedata)) {
            $pService = new ProfileService();
            $pService->updateUser($user, $basedata);
        }
        $app = $request->get('model') ?? "fpdx";
        switch ($app) {
            case 'goodnight':
                # 互道晚安
                $data = $request->only(['cover', 'like_sex', 'like_tone_1', 'like_tone_2', 'like_tone_3', 'voice']);
                if (!empty($data)) {
                    $guService = new GoodNightUserService();
                    $guService->updateUser($user, $data);
                }
                break;
            case 'fpdx':
            # 72小时恋爱体验
            default:
                # 基础信息
                $pService = new ProfileService();
                $data = $request->except(array('gold_flower', 'red_flower', 'task_type', 'wx_auth', 'identity_auth', 'wxkf', 'login_at', 'created_at', 'phone', 'task_photo', 'task_question', 'task_sing'));
                $pService->updateUser($user, $data);
                break;
        }
        $message->setResponse($this->userManager->profile($uid, $app));
    }
    /**
     * @param  StoreSelfPartnerMessage  $message
     * @throws Exception
     */
    public function storeSelfPartner(StoreSelfPartnerMessage $message)
    {
        $uid = Auth::auth();
        try {
            $user = UserModel::findOrFail($uid);
            if ($user->partner_id > 0) {
                $message->setResponse($user);
            }
            $partnerModel = new PartnerModel();
            $data = $user->toArray();
            $data['media_id'] = $message->getMediaId() ?: '';
            $data['secret'] = bin2hex(openssl_random_pseudo_bytes(4));
            $partner = $partnerModel->fill($data);
            $partner->created_at = time();
            if (!empty($partner->qq) || !empty($partner->weixin)) {
                $partner->is_sell = 1;
            }
            if (!empty($partner->photo_src)) {
                $partner->check_photo = 0;
                $partner->is_commit_check = 1;
            }
            if (!empty($partner->voice)) {
                $partner->voice_check = 0;
                $partner->is_commit_check = 1;
            }
            if (!empty($partner->photo_1)) {
                $partner->photo_1_check = 0;
                $partner->is_commit_check = 1;
            }
            if (!empty($partner->photo_2)) {
                $partner->photo_2_check = 0;
                $partner->is_commit_check = 1;
            }
            if (!empty($partner->photo_3)) {
                $partner->photo_3_check = 0;
                $partner->is_commit_check = 1;
            }
            if (!empty($partner->photo_4)) {
                $partner->photo_4_check = 0;
                $partner->is_commit_check = 1;
            }
            if (Redis::exists("storeselfpartner:{$uid}")) {
                throw new AlertException("请求频繁", 104);
            }
            Redis::setex("storeselfpartner:{$uid}", 5, true);
            if ($partner->save()) {
                $user->partner_id = $partner->id;
                $user->save();
                // 系统通知
                $sex = 1 == $partner->sex ? "小姐姐" : "小哥哥";
                NoticeModel::create(['uid' => $uid, 'title' => '交友卡片上传完成', 'content' => "你的交友卡片已经完成啦！现在可以去交友大厅邀请你心动的{$sex}啦~ ", 'type' => 5, 'type_id' => 0, 'create_at' => time(), 'update_at' => time(), 'tab_content' => '进入大厅', 'tab_url' => '/pages/index/index']);
            }
            Redis::del(["storeselfpartner:{$uid}"]);
            StoreSelfPartnerJob::dispatch($uid);
        } catch (Exception $e) {
            if (Redis::exists("storeselfpartner:{$uid}")) {
                Redis::del(["storeselfpartner:{$uid}"]);
            }
            throw $e;
        }
        $message->setResponse($user);
    }
    /**
     * 获取所有问题列表
     * @param  GetQuestionListMessage  $message
     */
    public function getQuestionList(GetQuestionListMessage $message)
    {
        $questions = QuestionModel::get();
        $message->setResponse($questions);
    }
    /**
     * 获取问题详情
     * @param  GetQuestionInfoMessage  $message
     */
    public function getQuestionInfo(GetQuestionInfoMessage $message)
    {
        $uid = Auth::auth();
        $questionId = $message->getQuestionId();
        $question = QuestionModel::find($questionId);
        $answer = AnswerModel::where('uid', $uid)->where('question_id', $questionId)->first();
        $question->answer = $answer;
        $message->setResponse($question);
    }
    /**
     * 获取我回答的问题
     * @param  GetQuestionAnswerListMessage  $message
     */
    public function getQuestionAnswerList(GetQuestionAnswerListMessage $message)
    {
        if (!($uid = $message->getUid())) {
            $uid = Auth::auth();
        }
        $questionIdArray = AnswerModel::where('uid', $uid)->pluck('question_id');
        $questions = QuestionModel::whereIn('id', $questionIdArray)->get();
        foreach ($questions as $question) {
            $question->answer = AnswerModel::where('uid', $uid)->where('question_id', $question->id)->first();
        }
        $message->setResponse($questions);
    }
    public function createAnswer(CreateAnswerMessage $message)
    {
        $questionId = $message->getQuestionId();
        $content = $message->getContent();
        $uid = Auth::auth();
        $question = QuestionModel::find($questionId);
        $answer = AnswerModel::updateOrCreate(['uid' => $uid, 'question_id' => $questionId], ['content' => $content]);
        $question->answer = $answer;
        $message->setResponse($question);
    }
    /**
     * @param  DeletePhotosMessage  $message
     * @throws Exception
     */
    public function deletePhotos(DeletePhotosMessage $message)
    {
        $field = $message->getField();
        $uid = Auth::auth();
        $pfs = new ProfileService();
        $pfs->deletePhoto($uid, $field);
    }
    /**
     * @param  SelectCoverMessage  $message
     * @throws AlertException
     */
    public function selectCover(SelectCoverMessage $message)
    {
        $field = $message->getField();
        $uid = Auth::auth();
        $user = UserModel::findOrFail($uid);
        /** @var UserModel $user */
        if (empty($user->{$field})) {
            throw new AlertException("参数错误", 101);
        }
        $identity_auth = $user->identity_auth;
        if (!empty($identity_auth)) {
            $identity_auths = explode(",", $identity_auth);
            array_walk($identity_auths, function (&$value) use ($field) {
                if ($value == "photo_src") {
                    $value = $field;
                } elseif ($value == $field) {
                    $value = "photo_src";
                }
            });
            $identity_auth = implode(",", $identity_auths);
            $user->identity_auth = $identity_auth;
        }
        $tmp = $user->photo_src;
        $user->photo_src = $user->{$field};
        $user->{$field} = $tmp;
        $user->save();
        $ps = new \App\Services\User\PartnerService();
        $ps->selectCover($user->partner_id, $field);
    }
    public function uidTranslationImAccount(UidTranslationImAccountMessage $message)
    {
        $uid = $message->getReqUid() ?? 0;
        $imAccount = $message->getReqIMAccount() ?? null;
        if ($uid) {
            $user = UserModel::whereUid($uid)->first();
        } else {
            $user = UserModel::where('im_account', $imAccount)->first();
        }
        if ($user) {
            $message->setResponse($user->uid, $user->im_account);
        } else {
            throw new AlertException("参数错误");
        }
    }
}
