<?php
namespace App\Http\Controllers\WX;

use App\Http\Controllers\Controller;
use App\Models\WxSignModel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Throwable;
use Exception;
use Carbon\Carbon;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Redis;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
use App\Models\WxBindRole;
use App\Models\UserExtra;
use App\Models\WxSign;
use App\Models\User;
use App\Models\WxAldGift;
use App\Services\AldGmService;
use App\Services\UtilService;

class SignController extends Controller
{
    private $time;

    public function __construct()
    {
        $this->time = Carbon::now()->format('Y-m-d H:i:s');
    }

    /**
     * 登录后首页
     * @date 2021/05/26
     * @author live
     */
    public function getLoginHome(Request $request)
    {
        $uid = $request->session()->get("uid");
        $isLogin = 1;
        $serverName = '';
        $roleName = '';
        $isBandOrange = 0;
        $bindOrangeUrl = route("aldCode");
        $isBindRole = 0;

        $user = User::where('uid',$uid)->select('uid','account')->first();
        $userName = $user->account ?? '';
        $userExtra = UserExtra::find($uid);
        if (!empty($userExtra->aldzn_info)) $isBandOrange = 1;
        $bind = WxBindRole::where('uid',$uid)->select('uid','role_name','server_name')->first();
        if($bind){
            $isBindRole = 1;
            $serverName = $bind->server_name;
            $roleName = $bind->role_name;
        }
        $sign = WxSign::where('uid',$uid)->select('id','sign_data')->first();
        if($sign){
            $signData = json_decode($sign->sign_data,true);
            $data['signDay'] = count($signData);
        }else{
            $signData = [];
            $data['signDay'] = 0;
        }
        $giftArr = [];
        $gifts = WxAldGift::where('uid',$uid)->where('type',2)->select('id','gift_id')->get();
        foreach($gifts as $gift) $giftArr[] = $gift->gift_id;

        $startTime = strtotime(config('sign.date'));
        $endTime = $startTime + 15 * 86400 - 1;
        $num = intval((strtotime(date('Y-m-d')) - strtotime(date('Y-m-d',$startTime))) / 86400) + 1 ;
        $allSignDate = [];
        for($i=0;$i<15;$i++){
            $tem = $startTime + $i * 86400;
            if($tem < $endTime) $allSignDate[$i+1] = date('Ymd',$tem);
        }

        $data['startTime'] = date('Y',$startTime).'年'.date('m',$startTime).'月'.date('d',$startTime).'日';
        $data['endTime'] = date('Y',$endTime).'年'.date('m',$endTime).'月'.date('d',$endTime).'日';
        $data['giftArr'] = $giftArr;
        $data['num'] = $num;
        $data['allSignDate'] = $allSignDate;
        $data['signGift'] = config('sign.sign');
        $data['continueSign'] = config('sign.continueSign');
        $data['signData'] = $signData;
        $data['isLogin'] = $isLogin;
        $data['userName'] = $userName;
        $data['serverName'] = $serverName;
        $data['roleName'] = $roleName;
        $data['isBandOrange'] = $isBandOrange;
        $data['bindOrangeUrl'] = $bindOrangeUrl;
        $data['isBindRole'] = $isBindRole;
        $data['loginUrl'] = route("login");
        $data['loginOutUrl'] = route("logout");
        $data['isWx'] =  UtilService::getIsWx($_SERVER['HTTP_USER_AGENT']);
        return view("wx.sign", $data);
    }

    /**
     * 绑定阿拉德码
     * @date 2021/05/26
     * @author live
     */
    public function getBindAldCode(Request $request)
    {
        $uid = $request->session()->get("uid");
        $limitErrorTimesPerDay = 3;
        $errTimesKey = "bind_code_errtimes:" . date("Ymd") . ":" . $uid;
        $errTimes = Cache::get($errTimesKey, 0);
        $data['bind_total_num'] = $limitErrorTimesPerDay;
        $data['bind_left_num'] = $limitErrorTimesPerDay - $errTimes;
        $data['isWx'] =  UtilService::getIsWx($_SERVER['HTTP_USER_AGENT']);
        return view("wx.bindCode", $data);
    }

    /**
     * 绑定签到角色
     * @date 2021/05/26
     * @author live
     */
    public function getBindSignAldRole(Request $request)
    {
        $uid = $request->session()->get("uid");
        if (empty($uid)) return $this->jsonReturn(1019, "登陆失效或未登陆，请重新登陆");

        $userExtra = UserExtra::find($uid);
        if (empty($userExtra->aldzn_info)) return $this->jsonReturn(4003, "请您先绑定Orange识别码后再来绑定角色哦~");

        $aldznInfo = json_decode($userExtra->aldzn_info,true);
        $channel = $aldznInfo['channel'] ?? 0;
        if($channel == '') return $this->jsonReturn(10008, "很抱歉，非指定平台用户无法参与本次签到活动");
        if (!in_array($channel, config('sign.channel'))) return $this->jsonReturn(10008, "很抱歉，非指定平台用户无法参与本次签到活动");

        $verityBind = WxBindRole::where('uid',$uid)->first();
        if($verityBind) return $this->jsonReturn(10001, "您已经绑定角色，请勿重复绑定");

        $roleId = $request->input("roleId");
        $serverId = $request->input("serverId");
        $serverName = $request->input("serverName");
        if (empty($roleId) || empty($serverId) || empty($serverName)) return $this->jsonReturn(7002, "参数错误");

        $targetRole = [];
        $roleIdsKey = "user_roleIds:" . $uid;
        $roleList = json_decode(Redis::get($roleIdsKey), true);

        if (!isset($roleList[$serverId])) return $this->jsonReturn(7003, "请选择正确的服务器");
        foreach ($roleList[$serverId]['list'] as $role) {
            if ($role['roleId'] == $roleId) {
                $targetRole = $role;
                break;
            }
        }
        if (empty($targetRole)) return $this->jsonReturn(7004, "请刷新重新选择角色");

        $bindRole = new WxBindRole();
        $bindRole->uid = $uid;
        $bindRole->role_id = $targetRole['roleId'];
        $bindRole->role_name = $targetRole['roleName'];;
        $bindRole->user_id = $targetRole['userId'];
        $bindRole->user_name = '';
        $bindRole->channel = $targetRole['channel'];
        $bindRole->vip_level = $targetRole['vipLevel'];
        $bindRole->server_id = $serverId;
        $bindRole->server_name = $serverName;
        if($bindRole->save())  return $this->jsonReturn(0, "绑定角色成功");
        return $this->jsonReturn(10002, "绑定角色失败");
    }

    /**
     * 用户签到
     * @date 2021/05/26
     * @author live
     */
    public function getSign(Request $request)
    {
        $uid = $request->session()->get("uid");
        if(empty($uid)) return $this->jsonReturn(1019, "登陆失效或未登陆，请重新登陆");

        $userExtra = UserExtra::find($uid);
        if(empty($userExtra->aldzn_info)) return $this->jsonReturn(4003, "请您先绑定Orange识别码后再绑定角色签到领取礼包哦~");

        $verityBind = WxBindRole::where('uid',$uid)->first();
        if(!$verityBind) return $this->jsonReturn(10004, "请您绑定角色后再来签到领取礼包");

        $startTime = strtotime(config('sign.date'));
        $endTime = $startTime + 15 * 86400 -1;
        $now = strtotime(date('Y-m-d H:i:s'));
        if($now < $startTime || $now > $endTime) return $this->jsonReturn(10009, "签到活动只在".date('Y-m-d H:i:s',$startTime).'--'.date('Y-m-d H:i:s',$endTime).'时间段开放');

        if(Cache::has($uid.':sign:click')){
            return $this->jsonReturn(10022, "请勿重复签到");
        }else{
            Cache::put($uid.':sign:click',1,60);
            $ym = date('Ym');
            $tableName = 'wx_sign_log_'.$ym;
            $this->getCheckSignLogTable($tableName);
            $ymd = date('ymd');
            $verity = $this->getVeritySign($uid,$ymd,$tableName);
            if(!$verity) return $this->jsonReturn(10005, "您今天已签到，请勿重复签到");
            $startTime = config('sign.date');
            $num = intval((strtotime(date('Y-m-d')) - strtotime(date('Y-m-d',strtotime($startTime)))) / 86400) + 1 ;
            DB::connection('wx_mysql')->beginTransaction();
            try{
                $this->getInsertLog($uid,$tableName,$ymd);
                $this->getUpUserSign($uid);
                $this->getAddAldSignGift($uid,$num,1);
            }catch (\Exception $e) {
                DB::connection('wx_mysql')->rollBack();
                return $this->jsonReturn(10006, "签到失败");
            }
            //$this->getSendGift($verityBind,$num);
            DB::connection('wx_mysql')->commit();
            return $this->jsonReturn(0, "签到成功，签到礼包发送中，稍后请去绑定角色的邮箱查收");
        }
    }

    /**
     * 记录签到礼包
     * @return bool
     * @date 2021/04/28
     * @author live
     */
    public function getAddAldSignGift($uid,$num,$type)
    {
        $verity = WxAldGift::where('uid',$uid)->where('gift_id',$num)->where('type',$type)->first();
        if(!$verity){
            $giftArr = [];
            if($type == 1) $giftArr = config('sign.sign');
            if($type == 2) $giftArr = config('sign.continueSign');
            $gift = $giftArr[$num] ?? [];
            $row = new WxAldGift();
            $row->uid = $uid;
            $row->gift_id = $num;
            $row->gift_num = $gift['itemNum'] ?? 1;
            $row->type = $type;
            $row->status = 0;
            $row->remark = json_encode($gift);
            $row->save();
        }
       return true;
    }

    /**
     * 更新用户签到表
     * @return bool
     * @date 2021/04/28
     * @author live
     */
    public function getUpUserSign($id)
    {
        $sign = WxSign::where('uid',$id)->select('id','sign_data')->first();
        $ymd = date('Ymd');
        if($sign){
            $array = array_unique(json_decode($sign->sign_data,true));
            if(!in_array($ymd,$array)){
                $array[] = date('Ymd');
                $sign->sign_data = json_encode(array_unique(array_values($array)));
                $sign->save();
            }else{
                $sign->sign_data = json_encode(array_values($array));
                $sign->save();
            }
            return $sign;
        }else{
            $row = new WxSign();
            $row->uid = $id;
            $row->sign_data = json_encode([$ymd]);
            return $row->save();
        }
    }

    /**
     * 插入签到日志
     * @return bool
     * @date 2021/05/26
     * @author live
     */
    public function getInsertLog($id,$tableName,$ymd)
    {
        $verity = $this->getVeritySign($id,$ymd,$tableName);
        if($verity){
            $time = date('Y-m-d H:i:s');
            $array = ['ymd'=>$ymd,'uid'=>$id,'created_at'=>$time,'updated_at'=>$time];
            return DB::connection('wx_mysql')->table($tableName)->insert($array);
        }
       return true;
    }

    /**
     * 校验当天是否签到过
     * @return bool
     * @date 2021/05/26
     * @author live
     */
    public function getVeritySign($id,$ymd,$tableName)
    {
        $log = DB::connection('wx_mysql')->table($tableName)->where('ymd',$ymd)->where('uid',$id)->select('id')->first();
        if($log) return false;
        return true;
    }

    /**
     * 检查签到日志表
     * @return bool
     * @date 2021/05/26
     * @author live
     */
    public function getCheckSignLogTable($table)
    {
        if ( ! Schema::connection('wx_mysql')->hasTable($table)) {
            Schema::connection('wx_mysql')->create($table, function (Blueprint $table) {
                $table->bigIncrements('id')->comment('自增主键');
                $table->integer('ymd')->default(0)->comment('年月日');
                $table->integer('uid')->default(0)->comment('用户id');
                $table->timestamps();
                $table->index(['Ymd','uid']);
                $table->engine = 'InnoDB';
            });
        }
        return true;
    }

    /**
     * 发放连续签到礼包
     * @return bool
     * @date 2021/05/26
     * @author live
     */
    public function getSendGift(WxBindRole $role,$num)
    {
        $array = ['code'=>200,'num'=>1];
        $giftArr = config('sign.sign');
        //$startTime = config('sign.date');
        //$num = intval((strtotime(date('Y-m-d')) - strtotime(date('Y-m-d',strtotime($startTime)))) / 86400) + 1 ;
        $gift = $giftArr[$num] ?? [];
        if($num < 1 || $num > 15 || empty($gift)){
            $array['code'] = 400;
            return $array;
        }

        $itemId = $gift['itemId'];
        $itemNum = $gift['itemNum'];
        $subject = config('sign.signEmailTitle');
        $content = config('sign.signEmailContent');
        $reason = config('sign.signEmailReason');
        $gmService = new AldGmService();
        $result = $gmService->getSendSignRoleGift($role->server_id,$role->role_id,$role->channel,$itemId,$itemNum,$subject,$content,$reason);
        if($result){
            $array['num'] = $num;
        }else{
            $array['code'] = 400;
        }
        return $array;
    }


    /**
     * 发放连续签到礼包
     * @return bool
     * @date 2021/05/26
     * @author live
     */
    public function geSendSignGift(Request $request)
    {
        $uid = $request->session()->get("uid");
        if(empty($uid)) return $this->jsonReturn(1019, "登陆失效或未登陆，请重新登陆");
        $role = WxBindRole::where('uid',$uid)->first();
        if(!$role) return $this->jsonReturn(10004, "请您绑定角色后再来签到领取礼包");

        $type = $request->input("type");
        if(!in_array($type, [3,7,12])) return $this->jsonReturn(7002, "参数错误");

        $sign = WxSign::where('uid',$uid)->select('id','sign_data')->first();
        if(!$sign) return $this->jsonReturn(10010, "对不起，您不够领取礼包资格，请记得每天来签到");

        $signDay = json_decode($sign->sign_data,true);
        if(count($signDay) < $type) return $this->jsonReturn(10010, "对不起，您不够领取礼包资格，请记得每天来签到");

        if(Cache::has('send:gift:wx:'.$uid)){
            return $this->jsonReturn(10022, "请勿重复点击领取");
        }else{
            $verity = WxAldGift::where('uid',$uid)->where('gift_id',$type)->where('type',2)->first();
            if($verity) return $this->jsonReturn(10011, "您已经领取礼包，请勿重复领取");
            Cache::put('send:gift:wx:'.$uid,$uid,60);
            $this->getAddAldSignGift($uid,$type,2);
            return $this->jsonReturn(0, "签到礼包发送中，稍后请去绑定角色的邮箱查收");
        }




    }
}