<?php

namespace App\Services\Deed;

use App\Exceptions\AlertException;
use App\Exceptions\DBException;
use App\Models\Deed\DeedCommentModel;
use App\Models\Deed\DeedModel;
use App\Models\Deed\InvitationCardModel;
use App\Models\Fpdx\ActivityModel;
use App\Models\Fpdx\PairModel;
use App\Models\Goodnight\RoomMemberModel as GoodnightRoomMemberModel;
use App\Models\Gteam\EnterModel;
use App\Models\Gteam\RoomMemberModel as GameRoomMemberModel;
use App\Models\User\UserModel;
use App\Services\Goodnight\EnterService;
use App\Services\Service;

class DeedService extends Service
{
    /**
     * 签订同意契约
     * @param  int  $uid
     * @param  string  $sign
     * @param  int  $deed_id
     * @return mixed
     * @throws AlertException
     * @throws DBException
     */
    public function signDeed(int $uid, string $sign, int $deed_id)
    {
        $deed = DeedModel::findOrFail($deed_id);
        if ($deed->state != 1) {
            throw new AlertException("契约已失效", 103);
        }
        \DB::beginTransaction();
        try {
            \DB::table('kdgx_fpdx_deed')->where('id', $deed_id)->update(['number' => date('YmdHis', time()) . uniqid()]);
            $tdeed_id = \DB::table('kdgx_fpdx_deed')->insertGetId([
                'type' => $deed->type,
                'uid' => $uid,
                'sign' => $sign,
                'ack' => $deed->ack,
                'number' => $deed->number,
                'state' => 1,
            ]);
            \DB::commit();

            return $tdeed_id;
        } catch (\Exception $e) {
            \DB::rollBack();
            throw new DBException($e->getMessage(), 501);
        }
    }

    /**
     * 创建契约
     * @param  int  $uid  签定契约的用户
     * @param  array  $signs  签名数组
     * @param  string  $type  活动类型 0:交换微信|1:72小时|2:开黑王者|3:开黑吃鸡
     * @param  string|null  $ack  活动处理标识,用于定位某人报名某期某活动
     * @param  int  $way  参加活动的方式 0:报名|1:邀请
     * @param  int  $way_id  方式关联字段 way为报名时=报名id|way为邀请时=邀请id
     * @return mixed
     * @throws AlertException
     */
    public function createDeed(int $uid, array $signs, string $type, $ack, int $way, int $way_id)
    {
        if (!in_array($way, [0, 1])) {
            throw new AlertException("参加活动的方式参数异常", 501);
        }
        $dm = new DeedModel();
        $deed = $dm->where([
            ['uid', $uid],
            ['way', $way],
            ['way_id', $way_id],
        ])->first();
        if (collect($deed)->isEmpty()) {
            $data = array(
                'created_at' => time(),
                'updated_at' => time(),
                'uid' => $uid,
                'type' => $type,
                'ack' => $ack,
                'sign' => $signs['sign'],
                'sign_content' => $signs['sign_content'],
                'state' => 1,
                'way' => $way,
                'way_id' => $way_id,
            );

            if ($way == 1) {
                $data['sign_at'] = time();
                $data['publish_at'] = time() + 86400;
                $data['confirm_at'] = time() + 86400;
                $data['end_at'] = time() + 86400;
            } else {
                switch ($type) {
                    case 0:
                        $data['sign_at'] = time();
                        $data['publish_at'] = time() + 86400;
                        $data['confirm_at'] = time() + 86400;
                        $data['end_at'] = time() + 86400;
                        break;
                    case 1:
                        $pair = PairModel::findOrFail($ack);
                        $activity = ActivityModel::findOrFail($pair->stage_id);
                        $data['sign_at'] = time();
                        $data['publish_at'] = $activity->open_time;
                        $data['confirm_at'] = $activity->rematched_at;
                        $data['end_at'] = $activity->close_time;
                        break;
                    case 2:
                    case 3:
                        $enter = EnterModel::findOrFail($ack);
                        $acty = $enter->activity;
                        $data['sign_at'] = time();
                        $data['publish_at'] = $acty->match_end_at;
                        $data['confirm_at'] = $acty->match_end_at;
                        $data['end_at'] = $acty->match_end_at + 3 * 3600;
                        break;
                    case 4:
                        $es = new EnterService();
                        $acty = $es->getActivity("报名");
                        $data['sign_at'] = time();
                        $data['publish_at'] = $acty->showed_at;
                        $data['confirm_at'] = $acty->showed_at;
                        $data['end_at'] = $acty->end_at;
                        break;
                }
            }
            $deed_id = \DB::table("kdgx_fpdx_deed")->insertGetId($data);

            return $deed_id;
        }

        return $deed->id;
    }

    /**
     * 生成契约编号
     * @param  int  $type
     * @param  int  $ack
     * @param  int  $isack
     * @return string
     * @throws AlertException
     * @throws DBException
     */
    public function signTwoDeed(int $type, $ack, $isack)
    {
        $deed = DeedModel::where([['type', $type], ['ack', $ack]])->first();
        $isdeed = DeedModel::where([['type', $type], ['ack', $isack]])->first();
        if (collect($deed)->isEmpty() || collect($isdeed)->isEmpty()) {
            throw new AlertException("不存在的契约", 404);
        }
        if ($deed->type != $isdeed->type) {
            throw new AlertException("契约类型不同", 101);
        }

        if (!in_array($deed->state, [1, 2]) || !in_array($isdeed->state, [1, 2])) {
            throw new AlertException("契约已失效", 103);
        }
        $number = bin2hex(\openssl_random_pseudo_bytes(3)) . rand(1, 9);
        $deed->number = $number;
        $deed->state = 3;
        $isdeed->number = $number;
        $isdeed->state = 3;
        if ($deed->save() && $isdeed->save()) {
            return $number;
        }
        throw new DBException("数据库异常", 501);
    }

    /**
     * 生成契约编号
     * @param  int  $deed_id
     * @param  int  $isdeed_id
     * @return string
     * @throws AlertException
     * @throws DBException
     */
    public function signTwoDeedByid(int $deed_id, int $isdeed_id)
    {
        $deed = DeedModel::findOrFail($deed_id);
        $isdeed = DeedModel::findOrFail($isdeed_id);
        if ($deed->type != $isdeed->type) {
            throw new AlertException("契约类型不同", 101);
        }

        if (!in_array($deed->state, [1, 2]) || !in_array($isdeed->state, [1, 2])) {
            throw new AlertException("契约已失效", 103);
        }

        switch ($deed->type) {
            case 0:
                $deed->end_at = time() + 86400;
                $isdeed->end_at = time() + 86400;
                break;
        }
        $number = bin2hex(\openssl_random_pseudo_bytes(3)) . rand(1, 9);
        $deed->number = $number;
        $deed->state = 3;
        $isdeed->number = $number;
        $isdeed->state = 3;
        if ($deed->save() && $isdeed->save()) {
            return $number;
        }
        throw new DBException("数据库异常", 501);
    }

    /**
     * 获取契约信息
     * @param  int  $deed_id
     * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model
     */
    public function get(int $deed_id)
    {
        $deed = DeedModel::findOrFail($deed_id);
        if (!empty($deed->number)) {
            $other = DeedModel::where([['number', $deed->number], ['id', '!=', $deed_id]])->first();
            $ouser = UserModel::findOrFail(
                $other->uid,
                ['nickname', 'headimgurl', 'qq', 'weixin', 'partner_id', 'wx_auth', 'age', 'work_state']
            );
            $ouser->deed_cnt = DeedModel::where([
                ['uid', $other->uid],
                ['end_at', '<', time()],
            ])->whereNotNull('number')->count();
            $other->user = $ouser;
            $deed->other = $other;
            $deed->comment = DeedCommentModel::where([
                    ['number', $deed->number],
                    ['comment_uid', $other->uid],
                ])->first(['speed', 'level']) ?? null;
        }

        return $deed;
    }

    public function getByTUA(int $type, int $uid, $ack)
    {
        if (is_null($ack)) {
            throw new AlertException("没有找到契约", 401);
        }
        /** @var DeedModel|null $deed */
        $deed = DeedModel::where([
            ['type', $type],
            ['uid', $uid],
            ['ack', $ack],
        ])->first();
        if (collect($deed)->isEmpty()) {
            throw new AlertException("没有找到契约", 404);
        }
        if (!empty($deed->number)) {
            $other = DeedModel::where([['number', $deed->number], ['id', '!=', $deed->id]])->first();
            if (collect($other)->isEmpty()) {
                $other = null;
            } else {
                $ouser = UserModel::findOrFail($other->uid, ['nickname', 'headimgurl', 'qq', 'weixin', 'partner_id']);
                $ouser->deed_cnt = DeedModel::where('uid', $other->uid)->count();
                $other->user = $ouser;
                $deed->comment = DeedCommentModel::where([
                        ['number', $deed->number],
                        ['comment_uid', $other->uid],
                    ])->first(['speed', 'level']) ?? null;
            }
            $deed->other = $other;
        }

        return $deed;
    }

    public function getByTUW(int $type, int $uid, $way, $way_id)
    {
        $deed = DeedModel::where([
            ['type', $type],
            ['uid', $uid],
            ['way', $way],
            ['way_id', $way_id],
        ])->first();
        if (collect($deed)->isEmpty()) {
            throw new AlertException("没有找到契约", 404);
        }
        if (!empty($deed->number)) {
            $other = DeedModel::where([['number', $deed->number], ['id', '!=', $deed->id]])->first();
            if (collect($other)->isEmpty()) {
                $other = null;
            } else {
                $ouser = UserModel::findOrFail($other->uid, ['nickname', 'headimgurl', 'qq', 'weixin', 'partner_id']);
                $ouser->deed_cnt = DeedModel::where('uid', $other->uid)->count();
                $other->user = $ouser;
                $deed->comment = DeedCommentModel::where([
                        ['number', $deed->number],
                        ['comment_uid', $other->uid],
                    ])->first(['speed', 'level']) ?? null;
            }
            $deed->other = $other;
        }

        return $deed;
    }

    /**
     * 进行中的契约
     * @param  int  $uid
     * @param  array  $pages
     * @return array
     */
    public function ings(int $uid, array $pages)
    {
        $total = DeedModel::where([['uid', $uid], ['end_at', '>', time()]])->whereIn('state', [0, 1, 2, 3])->count();
        $deeds = DeedModel::where([['uid', $uid], ['end_at', '>', time()]])->whereIn('state', [0, 1, 2, 3])->get();
        foreach ($deeds as &$deed) {
            try {
                switch ($deed->type) {
                    case 0:
                        $invita = InvitationCardModel::findOrFail($deed->way_id);
                        if ($invita->uid == $uid) {
                            $duid = $invita->invite_uid;
                        } else {
                            $duid = $invita->uid;
                        }
                        $user = UserModel::findOrFail(
                            $duid,
                            ['uid', 'headimgurl', 'nickname', 'sex', 'qq', 'weixin', 'partner_id']
                        );
                        $user->deed_cnt = DeedModel::where('uid', $user->uid)->count();
                        $deed->user = $user;
                        break;
                    case 1:
                        $user = array(
                            'headimgurl' => "https://oss.pocketuniversity.cn/media/2018-12-03/5c04a96d88148.png",
                        );
                        $pair = PairModel::findOrFail($deed->ack);
                        if (!empty($pair->assoc_id)) {
                            $assoc = PairModel::findOrFail($pair->assoc_id);
                            $user = UserModel::findOrFail(
                                $assoc->uid,
                                ['uid', 'headimgurl', 'nickname', 'sex', 'qq', 'weixin', 'partner_id']
                            );
                            $user->deed_cnt = DeedModel::where('uid', $user->uid)->count();
                        }
                        $deed->user = $user;
                        break;
                    case 2:
                    case 3:
                        $duid = 0;
                        if (!empty($deed->number)) {
                            $enter = EnterModel::findOrFail($deed->ack);
                            $member = GameRoomMemberModel::where([
                                ['room_id', $enter->room_id],
                                ['uid', '!=', $uid],
                            ])->firstOrFail();
                            $duid = $member->uid;
                        } else {
                            if ($deed->way == 1) {
                                $invita = InvitationCardModel::findOrFail($deed->way_id);
                                if ($invita->uid == $uid) {
                                    $duid = $invita->invite_uid;
                                } else {
                                    $duid = $invita->uid;
                                }
                            }
                        }
                        if ($duid == 0) {
                            if ($deed->type == 2) {
                                $user = array(
                                    'headimgurl' => "https://oss.pocketuniversity.cn/media/2018-12-10/5c0e5153b3cbe.png",
                                );
                            } else {
                                $user = array(
                                    'headimgurl' => "https://oss.pocketuniversity.cn/media/2018-12-10/5c0e515249448.png",
                                );
                            }
                        } else {
                            $user = UserModel::findOrFail(
                                $duid,
                                ['uid', 'headimgurl', 'nickname', 'sex', 'qq', 'weixin']
                            );
                            $user->deed_cnt = DeedModel::where('uid', $user->uid)->count();
                        }
                        $deed->user = $user;
                        break;
                    case 4:
                        $duid = 0;
                        if (!empty($deed->number)) {
                            $enter = \App\Models\Goodnight\EnterModel::findOrFail($deed->ack);
                            $member = GoodnightRoomMemberModel::where([
                                ['room_id', $enter->room_id],
                                ['uid', '!=', $uid],
                            ])->firstOrFail();
                            $duid = $member->uid;
                        } else {
                            if ($deed->way == 1) {
                                $invita = InvitationCardModel::findOrFail($deed->way_id);
                                if ($invita->uid == $uid) {
                                    $duid = $invita->invite_uid;
                                } else {
                                    $duid = $invita->uid;
                                }
                            }
                        }
                        if ($duid == 0) {
                            $user = array(
                                'headimgurl' => "https://oss.pocketuniversity.cn/media/2018-12-03/5c04a96d8b26b.png",
                            );
                        } else {
                            $user = UserModel::findOrFail(
                                $duid,
                                ['uid', 'headimgurl', 'nickname', 'sex', 'qq', 'weixin']
                            );
                            $user->deed_cnt = DeedModel::where('uid', $user->uid)->count();
                        }
                        $deed->user = $user;
                        break;
                }
            } catch (\Exception $e) {
                app('sentry')->captureException($e);
                continue;
            }
        }

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

    /**
     * 已完成的契约
     * @param  int  $uid
     * @param  array  $pages
     * @return array
     */
    public function succs(int $uid, array $pages)
    {
        $total = DeedModel::where('uid', $uid)->where(function ($query) {
            $query->whereIn('state', [-1, 4, 5])->orWhere('end_at', '<', time());
            $query->whereIn('state', [-1, 4, 5])->orWhere('end_at', '<', time());
            $query->whereIn('state', [-1, 4, 5])->orWhere('end_at', '<', time());
        })->count();
        $deeds = DeedModel::where('uid', $uid)->where(function ($query) {
            $query->whereIn('state', [-1, 4, 5])->orWhere('end_at', '<', time());
        })->skip(($pages['page'] - 1) * $pages['limit'])->take($pages['limit'])->get();
        foreach ($deeds as &$deed) {
            /** @var DeedModel $deed */
            if (!empty($deed->number)) {
                $other = DeedModel::where([
                    ['number', $deed->number],
                    ['id', '!=', $deed->id],
                ])->first();
                /** @var UserModel $ouser */
                $ouser = UserModel::findOrFail(
                    $other->uid,
                    ['uid', 'nickname', 'headimgurl', 'qq', 'weixin', 'partner_id']
                );
                $ouser->deed_cnt = DeedModel::where('uid', $other->uid)->count();
                $deed->user = $ouser;
                $deed->comment = DeedCommentModel::where([
                        ['number', $deed->number],
                        ['comment_uid', $ouser->uid],
                    ])->first(['speed', 'level']) ?? null;
            }
            switch ($deed->type) {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                    break;
            }
        }

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