<?php
/*
 * description：
 * author：wh
 * email：
 * createTime：{2024/6/3} {15:56} 
 */

namespace app\index\controller;


use app\common\model\TabConf;
use think\Db;
use think\Exception;
use wanghua\general_utility_tools_php\Mmodel;
use wanghua\general_utility_tools_php\SundryConfig;
use wanghua\general_utility_tools_php\tool\Tools;

/**
 * 离线奖励计算任务
 *
 * Class Offlineprizetimer
 * @package app\index\controller
 */
class Offlineprizetimer
{

    /**
     * desc：定时计算任务，每小时执行一次
     * author：wh
     */
    function count()
    {
        $this->countOfflinePrize();
        $this->recoveryPower();
        $this->recoveryPowerTimes();
    }

    /**
     * desc：计算离线奖励并写入离线奖励表
     *
     * 每1小时执行一次
     *
     * index/Offlineprizetimer/count
     *
     * author：wh
     */
    private function countOfflinePrize(){

        Tools::log_to_write_txt(['开始计算离线奖励']);
        return Mmodel::catchJson(function (){
            //一定时间内可领取的离线奖励次数
            $time_inner_get_prize_times = SundryConfig::val('time_inner_get_prize_times');
            $exp_arr = explode('-',$time_inner_get_prize_times);
            $max_hours = $exp_arr[0];
            $limit_time = time()-$max_hours * 3600;//n小时以内的离线用户

            //$can_get_times = $exp_arr[1];//可领取次数

            //所有离线时间大于 $max_hours 的用户
            $all_users = Db::table(TabConf::$fa_users)
                ->where('offline_time','egt',date('Y-m-d H:i:s',$limit_time))//规定离线时间内
                ->where('clientid','')//已离线
                ->select();
            //每离线N小时可获得奖励
            $offline_n_hour_gift_can_prize = SundryConfig::val('offline_n_hour_gift_can_prize');
            //计算奖励
            foreach ($all_users as &$user){
                if(empty($user['offline_time'])){
                    //刚注册，未离线
                    continue;
                }
                if($user['clientid']){
                    //在线
                    continue;
                }
                /** 下方是已离线用户↓ **/

                //查询最近计算奖励的时间
                $last_prize_time = Db::table(TabConf::$fa_user_offline_prize)
                    ->where('openid',$user['openid'])
                    ->order('id desc')
                    ->find();
                $offline_time = '';
                if($last_prize_time){
                    //如果最近领取了奖励则以最近领取时间为准
                    $offline_time = $last_prize_time['create_time'];
                }else{
                    //取离线时间
                    $offline_time = $user['offline_time'];
                }
                //离线时间超过3小时才能计算奖励
                if(time() - strtotime($offline_time) < 3*3600 ){
                    //上次计算奖励的时间到现在还没到3小时
                    continue;
                }

                if(time()-$max_hours*3600 < strtotime($offline_time)){//在72小时以内
                    //减去领奖时间
                    $offline_time_hours = (time() - strtotime($offline_time)) / 3600;//得到小时数
                    $prize_num = floor($offline_time_hours / $offline_n_hour_gift_can_prize);//得到本次可领取的奖品数量
                }else{//在72小时以外按72小时计算
                    $prize_num = floor($max_hours / $offline_n_hour_gift_can_prize);//得到本次可领取的奖品数量
                }
                if($prize_num<=0){
                    //离线时间不足，不计算奖励
                    continue;
                }

                //离线奖励获得数值
                $offline_prize_got_num_value = SundryConfig::val('offline_prize_got_num_value');
                //随机一个奖品
                $prop_id = $this->random_prop('id');
                //离线奖励可被偷取的百分比
                $lose_percent = SundryConfig::val('offline_prize_can_lose_percent');

                $prize_all_num = $prize_num * $offline_prize_got_num_value;
                $can_lose_num = floor($prize_all_num * $lose_percent);
                $self_got_num = $prize_all_num - $can_lose_num;
                //计算奖品数值
                $gameprop_arr = [
                    'openid'=>$user['openid'],
                    //奖品
                    'gameprop_id'=>$prop_id,
                    //奖品总数量
                    'prize_all_num'=>$prize_all_num,
                    //可被偷取的数量
                    'can_lose_num'=>$can_lose_num,//被偷取时，该值减少
                    //自己保底所得数量
                    'self_got_num'=>$self_got_num?:0,
                ];

                Db::table(TabConf::$fa_user_offline_prize)
                    ->insert($gameprop_arr);
            }
            Tools::log_to_write_txt(['结束计算离线奖励']);
            return Tools::set_ok('ok');
        });
    }
    private function random_prop($key=''){
        $count = Db::table(TabConf::$fa_gameprop)
            ->count('id');
        $id = mt_rand(1,$count);

        $p = Db::table(TabConf::$fa_gameprop)->where('id',$id)->find();
        if(empty($p)){
            $id = mt_rand(1,$count);
            $p = Db::table(TabConf::$fa_gameprop)->where('id',$id)->find();
        }
        if(empty($p)){
            throw new Exception('道具获取失败');
        }
        return $key?$p[$key]:$p;
    }

    /**
     * desc：每小时恢复一点体力，上限5点
     * author：wh
     */
    private function recoveryPower(){
        return Mmodel::catchJson(function (){
            $users = Db::table(TabConf::$fa_users)
                ->where('power','<',5)
                ->select();
            foreach ($users as $user){
                try {
                    Db::table(TabConf::$fa_users)
                        ->where('id',$user['id'])
                        ->setInc('power',1);
                }catch (\Exception $e){
                    continue;
                }
            }
        });
    }

    /**
     * 每日凌晨恢复看广告增加体力次数和消耗金币增加体力次数
     */
    private function recoveryPowerTimes(){
        return Mmodel::catchJson(function (){
            //判断当前时间是否是零点
            $now_time = date('H');
            if($now_time !== '00'){
                return '';
            }

            $per_day_coin_add_power_times = SundryConfig::val('per_day_coin_add_power_times');
            $per_day_look_ad_add_power_times = SundryConfig::val('per_day_look_ad_add_power_times');
            $users = Db::table(TabConf::$fa_users)->select();
            foreach ($users as $user){
                try {
                    Db::table(TabConf::$fa_users)
                        ->where('id',$user['id'])
                        ->data([
                            'coin_power_times'=>$per_day_coin_add_power_times,
                            'ad_power_times'=>$per_day_look_ad_add_power_times,
                        ]);
                }catch (\Exception $e){
                    continue;
                }
            }
        });
    }
}