<?php


namespace app\common\model;

use app\common\core\BaseModel;
use think\Db;

class MemberSignModel extends BaseModel
{
    protected $settings=[
        'open'=>0
    ];
    public function __construct($data = [])
    {
        parent::__construct($data);

        //初始化配置
        $settings = getSettings(false,true);
        if(!empty($settings['sign'])){
            foreach($settings['sign'] as $k=>$v){
                $key = $k;
                if(strpos($k,'sign_')===0)$key = substr($k,5);
                $this->settings[$key]=$v;
            }
            if(!empty($this->settings['keep_award'])){
                usort($this->settings['keep_award'],function ($prev, $next){
                    if($prev['day'] == $next['day'])return 0;
                    return $prev['day'] > $next['day']?1:-1;
                });
            }
        }
    }

    protected function format_time($time)
    {
        if(is_null($time)){
            return time();
        }
        if(!is_numeric($time)){
            $time = strtotime($time);
        }
        return intval($time);
    }

    public function getSigns($member_id, $time = NULL)
    {
        $model = Db::name('signLog')->where('member_id',$member_id);
        if(is_array($time)){
            $start=$this->format_time($time[0]);
            if(isset($time[1])){
                $end=$this->format_time($time[1]);
                $model->whereBetween('signdate',[date('Y-m-d',$start),date('Y-m-d',$end)]);
            }else{
                $model->where('signdate','>=', date('Y-m-d',$start));
            }
        }else{
            $time = $this->format_time($time);
            $month = date('Y-m',$time);
            $model->whereRaw(' INSTR(signdate, \''.$month.'\') = 1 ');
        }
        $list = $model->order('signdate ASC')->select();
        return array_column($list, NULL, 'signdate');
    }

    public function getSignRank($time, $num = 10)
    {
        $time = $this->format_time($time);
        $model = Db::view('signLog','*')
        ->view('member','username,nickname,level_id,avatar,gender,status,delete_time','member.id = signLog.member_id','LEFT')
        ->where('signdate',date('Y-m-d',$time));

        $list = $model->order('ranking_day ASC')->limit($num)->select();
        return $list;
    }

    public function getLastSign($member_id)
    {
        return Db::name('signLog')->where('member_id',$member_id)->order('signdate DESC')->find();
    }

    public function sign($member_id, $mood='', $time=NULL, $is_sup=false)
    {
        if($this->settings['open']==0){
            $this->error='签到功能未开启';
            return false;
        }
        $time = $this->format_time($time);
        if($time>=strtotime('today +1 day')){
            $this->error='还没到签到时间哦~';
            return false;
        }
        if($time<strtotime('today')){
            $is_sup=true;
        }
        $date = date('Y-m-d',$time);
        if($is_sup){
            $today = Db::name('signLog')->where('member_id',$member_id)->where('signdate',date('Y-m-d'))->find();
            if(empty($today)){
                $this->error='今天还没签到哦~';
                return false;
            }
        }

        $exists=Db::name('signLog')->where('member_id',$member_id)->where('signdate',$date)->find();
        if(!empty($exists)){
            if($date == date('Y-m-d')){
                $this->error='今天已经签过到了';
            }else{
                $this->error=$date.' 已经签过到了';
            }
            return false;
        }
        if($is_sup){
            if(!$this->settings['sup_sign_open']){
                $this->error='系统未开启补签';
                return false;
            }
            if(empty($this->settings['sup_sign_rule']['times'])){
                $this->error='本月补签次数已用完';
                return false;
            }
            $supcount = Db::name('signLog')->where('member_id',$member_id)
                ->where('is_sup',1)
                ->where('signdate','>=',date('Y-m-01'))->count();
            if($supcount>=$this->settings['sup_sign_rule']['times']){
                $this->error='本月补签次数已用完';
                return false;
            }
        }
        $count = Db::name('signLog')->where('signdate',$date)->count();

        $keep_days=1;
        if(date('d') != '01' || $this->settings['cycle']!='month'){
            $lastdate = date('Y-m-d',strtotime($date.' -1 day'));
            $lastsign = Db::name('signLog')->where('member_id',$member_id)->where('signdate',$lastdate)->find();
            if(!empty($lastsign )){
                $keep_days = $lastsign['keep_days']+1;
            }
        }
        $insertid = Db::name('signLog')->insert([
            'member_id'=>$member_id,
            'is_sup'=>$is_sup,
            'ranking_day' =>$count+1,
            'keep_days' =>$keep_days,
            'signdate' =>$date,
            'signtime' =>time(),
            'mood' =>$mood,
            'remark' =>'',
        ],false,true);
        if($insertid){
            $returnmsg='签到成功';
            $awarded=false;
            if($is_sup){
                $credit = empty($this->settings['sup_sign_rule']['credit'])?0 :intval($this->settings['sup_sign_rule']['credit']);
                money_log($member_id,-$credit*100,'补签扣除'.lang('Credit'),'sign',0,'credit');
                
                $today=strtotime('today');
                $nextday = strtotime($date.' +1 day');
                while($nextday<=$today){
                    $signed = Db::name('signLog')->where('member_id',$member_id)->where('signdate',date('Y-m-d',$nextday))->find();
                    if(empty($signed)){
                        break;
                    }
                    $nextday = strtotime(date('Y-m-d',$nextday).' +1 day');
                }
                Db::name('signLog')->where('member_id',$member_id)->where('signdate','>',$date)
                    ->where('signdate','<',date('Y-m-d',$nextday))->update(['keep_days'=>['INC',1]]);
            }elseif(!empty($this->settings['keep_award'])) {
                //是否有连接签到奖励
                $days = array_column($this->settings['keep_award'],'day');
                $maxday = max($days);
                $cdays=$keep_days%$maxday;
                $rkey=-1;
                foreach ($days as $key=>$day){
                    if($cdays < $day)break;
                    if($cdays == $day)$rkey = $key;
                }
                if($rkey > -1){
                    $credit = floatval($this->settings['keep_award'][$rkey]['value']);
                    if($credit>0) {
                        $awarded=true;
                        $returnmsg = '连续签到' . $days[$rkey] . '天奖励'.$credit.lang('Credit');
                        money_log($member_id, $credit*100, '连续签到' . $days[$rkey] . '天奖励', 'sign', 0, 'credit');
                    }
                }
            }
            
            if(!$awarded){
                $credit = empty($this->settings['award']['first'])?0:floatval($this->settings['award']['first']);
                if(!empty($credit) && !$is_sup){
                    $isfirst = 0;
                    if($keep_days==1){
                        if( $this->settings['cycle']=='month'){
                            $isfirst = Db::name('signLog')->where('member_id',$member_id)
                                ->where('signdate','>=',date('Y-m-01',time()))->count();
                        }else{
                            $isfirst = Db::name('signLog')->where('member_id',$member_id)->count();
                        }
                    }
                    if($isfirst==1){
                        $awarded=true;
                        $returnmsg = '首次签到奖励'.$credit.lang('Credit');
                        money_log($member_id, $credit*100, '首次签到奖励', 'sign', 0, 'credit');
                    }
                }
    
                $credit = empty($this->settings['award']['normal'])?0:floatval($this->settings['award']['normal']);
                if(!$awarded && !empty($credit)){
                    $returnmsg = '签到成功,奖励'.$credit.lang('Credit');
                    money_log($member_id, $credit*100, '日常签到奖励', 'sign', 0, 'credit');
                }
            }
            
            $this->setError($returnmsg,0);
        }
        return $insertid;
    }
}