<?php

namespace app\api\controller;

use app\common\controller\Api;
use think\Db;
/**
 * 售课
 */
class Lesson extends Api
{
    // 无需登录的接口,*表示全部
    protected $noNeedLogin = [];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = ['*'];

    //售课列表
    public function lists(){

        $list = Db::name('lesson')->where('is_show',1)->order('weigh desc')->autopage()->select();
        $list = list_domain_image($list,['image']);
        $list = $this->list_lang($list,['name','title','info','shiherenqun','pingjunrenshu','sirenkecheng','daoshi']);

        $this->success(1,$list);
    }

    //售课分类列表
    public function lesson_cate(){
        $list = Db::name('lesson_cate')->order('id asc')->select();
        $list = $this->list_lang($list,['name']);

        $this->success(1,$list);
    }

    //日历列表

    //教练列表
    public function coach_list(){
        $list = Db::name('coach')->field('id,nickname')->where('status',1)->order('nickname asc')->select();
        $this->success(1,$list);
    }

    //课时列表首页
    //根据年,月获取当月剩余日期,有课程的标记1
    public function slot_index(){

        $getdate = input('date',date('Y-m'));
        if(empty($getdate)){
            $getdate = date('Y-m');
        }
        $year = substr($getdate,0,4);
        $month = substr($getdate,-2,2);

        //今天是哪日
        if($year == date('Y') && $month == date('m')){
            //如果是今年今月,默认今天开始
            $startday = date('d');
        }else{
            //从1号开始
            $startday = '01';
        }

        //本月结束日
        $endday_arr = [
            '01' => 31,
            '02' => 28,
            '03' => 31,
            '04' => 30,
            '05' => 31,
            '06' => 30,
            '07' => 31,
            '08' => 31,
            '09' => 30,
            '10' => 31,
            '11' => 30,
            '12' => 31,
        ];
        if($year%4 == 0){
            $endday_arr['02'] = 29;
        }
        $endday = $endday_arr[$month];

        //拿数据
        $startdate = $getdate.'-'.$startday;
        $enddate   = $getdate.'-'.$endday;
        $where = [
            'starttime' => ['BETWEEN',[strtotime($startdate),strtotime($enddate)+86399]],
            'status'    => 0
        ];
        //dump($where);exit;
        $slots = Db::name('lesson_slot')->where($where)->field('id,starttime')->select();

        $date_arr = [];
        for($i=intval($startday);$i<=$endday;$i++){

            $j = $i;
            if($j < 10){
                $j = 0 . $j;
            }
            $idate = $year.'-'.$month.'-'.$j;

            $itime = strtotime($idate);
            $week = $this->lang == 'en' ? date('D',$itime) : '周'.date('w',$itime);

            $i_data = [
                'yeah' =>$year,
                'month'=>$month,
                'day'  => $j.'',
                'date' => $idate,
                'week' => $week,
                'is_today' => 0,
                'slot_num' => 0,
            ];

            foreach($slots as $slot){
                if(date('Y-m-d',$slot['starttime']) == $idate)
                {
                    $i_data['slot_num'] += 1;
                }
            }

            if($idate == date('Y-m-d')){
                $i_data['is_today'] = 1;
            }

            $date_arr[] = $i_data;
        }

        $this->success(1,$date_arr);
    }

    //某日课时列表
    public function slot_list(){

        $date = strtotime(input('date',date('Y-m-d')));
        $cate_id = input('cate_id',0);
        $coach_id = input('coach_id',0);

        $where = [
            'slot.starttime' => ['BETWEEN',[$date,$date+86399]],
            'slot.status' => 0
        ];
        if($cate_id){
            $where['lesson.lessoncate_id'] = $cate_id;
        }

        //课时
        $list = Db::name('lesson_slot')->alias('slot')
            ->field('slot.*,lesson.name,lesson.name_en,lesson.image,lesson.price')
            ->join('lesson','slot.lesson_id = lesson.id','LEFT')
            ->where($where);
        if($coach_id){
            $list->where('find_in_set(:coach_ids,coach_ids)', ['coach_ids' => $coach_id]);
        }
        $list = $list->order('slot.starttime asc')->select();
        if(empty($list)){
            $this->success(1,[]);
        }
        $list = list_domain_image($list,['image']);
        $list = $this->list_lang($list,['name']);

        //准备教练数据
        $coach_list = Db::name('coach')->column('id,nickname');

        foreach($list as $key => &$slot){
            //放入教练
            $coach_text = '';
            $coach_ids = explode(',',$slot['coach_ids']);
            foreach($coach_ids as $coach_id){
                $coach_text .= $coach_list[$coach_id].',';
            }
            $slot['coach_text'] = substr($coach_text,0,-1);

            //剩余空位数量
            $pay_number = Db::name('lesson_order')->where('slot_id',$slot['id'])->where('order_status',10)->sum('usernumber');
            $slot['num_remain'] = $slot['num_max'] - $pay_number;
            if($slot['num_remain'] < 0){
                $slot['num_remain'] = 0;
            }

            //预约按钮,1能预约,0不能
            $slot['button_status'] = $slot['status'] == 0 ? 1 : 0;

            if($slot['num_remain'] <= 0){
                $slot['button_status'] = 0;//没有空位了,强制改
            }

            //右上角备注
            if(time() >= $slot['starttime']){
                $slot['num_remark'] = __('报名已截止');
                $slot['button_status'] = 0;//报名截止了,强制改
            }else{
                $slot['num_remark'] = __('剩N个名额',['number'=>$slot['num_remain']]);
            }
        }

        $this->success(1,$list);
    }

    public function test(){
        echo __('剩N个名额',['number'=>8]);
    }

    //课时详情
    public function slot_info(){
        $slot_id = input('slot_id',0);
        $number  = input('number',1,'intval');

        //课时
        $info = Db::name('lesson_slot')->alias('slot')
            ->field('slot.*,lesson.name,lesson.name_en,lesson.image,lesson.price')
            ->join('lesson','slot.lesson_id = lesson.id','LEFT')
            ->where('slot.id',$slot_id)->find();
        if(empty($info)){
            $this->error('课程可能已取消,请刷新重试');
        }

        $info = info_domain_image($info,['image']);
        $info = $this->info_lang($info,['name']);

        //准备教练数据
        $coach_list = Db::name('coach')->where('id','IN',$info['coach_ids'])->column('nickname');
        $info['coach_text'] = implode(',',$coach_list);

        //剩余空位数量
        $pay_number = Db::name('lesson_order')->where('slot_id',$info['id'])->where('order_status',10)->sum('usernumber');
        $info['num_remain'] = $info['num_max'] - $pay_number;
        if($info['num_remain'] < 0){
            $info['num_remain'] = 0;
        }

        //时间
        $info['slot_time'] = date('m月d日',$info['starttime']).' (周'.date('w',$info['starttime']).')'.','.date('H:i',$info['starttime']).'-'.date('H:i',$info['endtime']);

        //是否有可买配套
        $wait_buy_package = Db::name('lesson_package')
            ->where('find_in_set(:lesson_ids,lesson_ids)', ['lesson_ids' => $info['lesson_id']])
            ->where('is_show',1)
            ->find();
        $info['wait_buy_package'] = !empty($wait_buy_package) ? 1 : 0;

        //预约按钮,1能预约,0不能
        /*$info['button_status'] = $info['status'] == 0 ? 1 : 0;
        if($info['num_remain'] <= 0){
            $info['button_status'] = 0;//没有空位了,强制改
        }*/

        //总价格乘出来
        $info['price'] = bcmul($info['price'],$number,2);

        //此课程是否还有未使用的套餐(多个包含赠送的)
        $map = [
            'o.user_id' =>$this->auth->id,

            'o.endtime' => ['gt',time()],
            'o.remain' => ['egt',$number], //不能只是大于0,还得大于等于报名人数
            'o.order_status' => 1,
        ];
        $package_list = Db::name('package_order')->alias('o')
            ->join('lesson_package p','o.package_id = p.id','LEFT')
            ->field('o.id,o.remain,o.starttime,o.endtime,o.is_gift,p.name,p.name_en')
            ->where($map)
            ->where('find_in_set(:lesson_ids,o.lesson_ids)', ['lesson_ids' => $info['lesson_id']])
            ->order('o.endtime asc')->select();
        $package_list = $this->list_lang($package_list,['name']);
        if(!empty($package_list)){
            foreach($package_list as $key => &$val){
                if($this->lang == 'zh-cn'){
                    $val['time_text'] = date('m月d,Y',$val['starttime']).'-'.date('m月d,Y',$val['starttime']);
                }else{
                    $val['time_text'] = date('M d,Y',$val['starttime']).'-'.date('M d,Y',$val['starttime']);
                }
            }
        }

        $info['package_list'] = $package_list;


        $this->success(1,$info);
    }

    //课时申请报名
    public function slot_apply(){
        $this->apiLimit();

        $slot_id = input('slot_id',0,'intval');
        $number  = input('number',1,'intval');
        $remark  = input('remark','','trim');
        $paytype = input('paytype',1,'intval');//支付类型:1=课程套餐,2=线上付款,3=购买套餐中
        $packageorder_id = input('packageorder_id',0,'intval');
        if($number <= 0){
            $this->error('预约人数错误');
        }
        if(!in_array($paytype,[1,2,3])){
            $this->error();
        }

        //课时
        $info = Db::name('lesson_slot')->alias('slot')
            ->field('slot.*,lesson.name,lesson.name_en,lesson.image,lesson.price')
            ->join('lesson','slot.lesson_id = lesson.id','LEFT')
            ->where('slot.id',$slot_id)->where('slot.status',0)->find();
        if(empty($info)){
            $this->error('课程可能已取消,请刷新重试');
        }
        if($info['endtime'] < time()){
            $this->error('课程已经结束了,不能再进行预约');
        }

        //报名人数不能超限
        $pay_number = Db::name('lesson_order')->where('slot_id',$slot_id)->where('order_status',10)->sum('usernumber');
        $num_remain = $info['num_max'] - $pay_number;
        if($num_remain < 0){
            $num_remain = 0;
        }
        if($num_remain < $number){
            $this->error(__('预约名额只剩N名',['number'=>$num_remain]));
        }

        $lesson_order = [
            'order_no' => createUniqueNo('S',$this->auth->id),
            'user_id' => $this->auth->id,
            'slot_id' => $slot_id,
            'lesson_id' => $info['lesson_id'],
            'order_amount' => bcmul($info['price'],$number,2),
            'order_status' => 0,
            'paytype' => $paytype, //支付类型:1=课程套餐,2=线上付款,3=购买套餐中
            'paytime' => 0,
            'createtime' => time(),
//            'updatetime' => ,
//            'finishtime' => ,
            'usernumber' => $number,
            'userremark' => $remark,
            'package_order_id' => 0,
            'package_remark' => '',//  比如:5/30,5-7/30
        ];

        //
        Db::startTrans();
        if($paytype == 1){
            //检查已选择套餐
            $map = [
                'user_id' =>$this->auth->id,

                'endtime' => ['gt',time()],
                'remain' => ['gt',0],
                'order_status' => 1,
                'id' => $packageorder_id,
            ];
            $package_order = Db::name('package_order')->where($map)->where('find_in_set(:lesson_ids,lesson_ids)', ['lesson_ids' => $info['lesson_id']])->lock(true)->find();
            if(!$package_order){
                Db::rollback();
                $this->error('套餐信息不正确,请刷新重试');
            }

            //课时不足支撑报名人数
            if($package_order['remain'] < $number){
                Db::rollback();
                $this->error('该套餐余额不足,可以使用其他支付方式');
            }

            //扣除一节
            $update = [
                'remain'     => $package_order['remain']-$number,
                'updatetime' => time(),
            ];
            $rs1 = Db::name('package_order')->where('id',$packageorder_id)->update($update);
            if($rs1 === false){
                Db::rollback();
                $this->error('扣除套餐余额失败');
            }

            //修改预约单数据
            $lesson_order['order_amount'] = 0;
            $lesson_order['order_status'] = 10;
            $lesson_order['paytime'] = time();
            $lesson_order['package_order_id'] = $packageorder_id;
            if($number > 1){
                $lesson_order['package_remark'] = ($package_order['sessions'] - $package_order['remain'] + 1) . '-' . ($package_order['sessions'] - $package_order['remain'] + $number) .'/'. $package_order['sessions'];
            }else{
                $lesson_order['package_remark'] = ($package_order['sessions'] - $package_order['remain'] + 1) .'/'. $package_order['sessions'];
            }

            //预约单写入
            $lesson_order_id = Db::name('lesson_order')->insertGetId($lesson_order);
            if(!$lesson_order_id){
                Db::rollback();
                $this->error('预约失败');
            }

            Db::commit();
            $this->success('预约成功',['returntype'=>1]);
        }
        elseif($paytype == 2)
        {
            //预约单写入
            $lesson_order_id = Db::name('lesson_order')->insertGetId($lesson_order);
            if(!$lesson_order_id){
                Db::rollback();
                $this->error('预约失败');
            }

            //支付订单下单
            $pay_order = [];
            $pay_order['user_id'] = $lesson_order['user_id'];
            $pay_order['out_trade_no'] = $lesson_order['order_no'];
            $pay_order['order_amount'] = $lesson_order['order_amount'];
            $pay_order['createtime'] = $lesson_order['createtime'];

            $pay_order['pay_type'] = 'hitpay';
            $pay_order['platform'] = 'app';
            $pay_order['order_status'] = 0;
            $pay_order['table_name'] = 'lesson_order';
            $pay_order['table_id'] = $lesson_order_id;
            $pay_order['args'] = '';

            //拉起支付
            $notify_url = config('notify_cdnurl');
            $hitpay_return = $this->hitpay_payment($pay_order['out_trade_no'],$pay_order['order_amount'],$notify_url);
            if($hitpay_return['status'] !== true){
                $this->error($hitpay_return['msg']);
            }
            //支付请求id
            $pay_order['payment_request_id'] = $hitpay_return['id'];

            $pay_order_id = Db::name('pay_order')->insertGetId($pay_order);
            if(!$pay_order_id){
                Db::rollback();
                $this->error('下单失败');
            }

            Db::commit();

            $return = [
                'url' => $hitpay_return['url'],
                'id'  => $hitpay_return['id'],
                'returntype' => 2,
            ];
            $this->success(1,$return);
        }
        elseif($paytype == 3)
        {
            //预约单写入
            $lesson_order['order_amount'] = 0;
            $lesson_order_id = Db::name('lesson_order')->insertGetId($lesson_order);
            if(!$lesson_order_id){
                Db::rollback();
                $this->error('预约失败');
            }

            Db::commit();

            //去购买套餐,参数代入过去
            $return = [
                'lesson_order_id' => $lesson_order_id,
                'returntype' => 3,
            ];
            $this->success(1,$return);
        }
    }

    //售课套餐列表
    public function package_list(){
        $lesson_id = input('lesson_id',0);

        //套餐列表
        $list = Db::name('lesson_package')
            ->where('find_in_set(:lesson_ids,lesson_ids)', ['lesson_ids' => $lesson_id])
            ->where('is_show',1)
            ->order('weigh desc')->select();
        $list = list_domain_image($list,['image']);
        $list = $this->list_lang($list,['name','validity','activeremark']);

        $this->success(1,$list);
    }

    //售课套餐详情
    public function package_info(){
        $package_id = input('package_id',0);

        //套餐详情
        $list = Db::name('lesson_package')
            ->where('id',$package_id)
            ->order('weigh desc')->find();
        $list = info_domain_image($list,['image']);
        $list = $this->info_lang($list,['name','validity','activeremark','content']);

        $this->success(1,$list);
    }

    //下单购买售课套餐
    public function package_buy(){
        $package_id = input('package_id',0);
        $lesson_order_id = input('lesson_order_id',0,'intval');//预约单id

        $package_info = Db::name('lesson_package')->where('id',$package_id)->find();

        //套餐订单
        $data = [
            'order_no'    => createUniqueNo('P',$this->auth->id),
            'user_id'     => $this->auth->id,
            'package_id'  => $package_id,
            'lesson_ids'   => $package_info['lesson_ids'],
            'sessions'    => $package_info['sessions'],
            'starttime'   => time(),
            'days'        => $package_info['days'],
            'endtime'     => time() + ($package_info['days'] * 86400),
            'price'       => $package_info['price'],
            'remain'      => $package_info['sessions'],
            'order_status'=> 0,
            'paytime'     => 0,
            'createtime'  => time(),
            'updatetime'  => 0,
            'is_gift'     => 0,
        ];

        //如果有赠品,赠品订单
        $gift = [];
        if(!empty($package_info['gift_lesson_id']) && !empty($package_info['gift_sessions'])){
            $gift = $data;

            //订单号不换了
            $gift['lesson_ids'] = $package_info['gift_lesson_id'];
            $gift['sessions']  = $package_info['gift_sessions'];
            $gift['remain']    = $package_info['gift_sessions'];
            $gift['is_gift']   = 1;
        }

        //支付订单下单
        $pay_order = [];
        $pay_order['user_id'] = $data['user_id'];
        $pay_order['out_trade_no'] = $data['order_no'];
        $pay_order['order_amount'] = $data['price'];
        $pay_order['createtime'] = $data['createtime'];

        $pay_order['pay_type'] = 'hitpay';
        $pay_order['platform'] = 'app';
        $pay_order['order_status'] = 0;
        $pay_order['table_name'] = 'package_order';
        $pay_order['table_id'] = 0;
        $pay_order['args'] = json_encode(['lesson_order_id'=>$lesson_order_id]);//用来支付完成回调时,扣除N节课,并改掉预约单的状态

        //拉起支付
        $notify_url = config('notify_cdnurl');
        $hitpay_return = $this->hitpay_payment($pay_order['out_trade_no'],$pay_order['order_amount'],$notify_url);
        if($hitpay_return['status'] !== true){
            $this->error($hitpay_return['msg']);
        }
        //支付请求id
        $pay_order['payment_request_id'] = $hitpay_return['id'];


        //入库
        Db::startTrans();
        $order_id = Db::name('package_order')->insertGetId($data);
        if(!$order_id){
            Db::rollback();
            $this->error('下单失败');
        }

        //礼物
        if(!empty($gift)){
            $gift_order_id = Db::name('package_order')->insertGetId($gift);
            if(!$gift_order_id){
                Db::rollback();
                $this->error('下单失败');
            }
        }

        //支付单
        $pay_order['table_id'] = $order_id;
        $pay_order_id = Db::name('pay_order')->insertGetId($pay_order);
        if(!$pay_order_id){
            Db::rollback();
            $this->error('下单失败');
        }

        Db::commit();

        $return = [
            'url' => $hitpay_return['url'],
            'id'  => $hitpay_return['id'],
        ];
        $this->success(1,$return);

    }

    //拉起支付
    private function hitpay_payment($out_trade_no,$money,$notifyurl)
    {
        $return = [
            'status' => false,
            'msg'  => '',
            'url' => '',
            'id' => 0,
        ];

        $apiKey = config('hitpay.apikey');

        try {
            $hitPayClient = new \HitPay\Client($apiKey, true);

            $request = new \HitPay\Request\CreatePayment();

            $request->setAmount($money)
                ->setCurrency('SGD')
                ->setPaymentMethods(['paynow_online','card'])
                ->setPurpose('Elin Dance Studio')
                ->setWebhook($notifyurl)
                ->setReferenceNumber($out_trade_no);

            $result = $hitPayClient->createPayment($request);

            $return['status'] = true;
            $return['url'] = $result->getUrl();
            $return['id']  = $result->getId();


            //print_r($result);

            /*$data = $hitPayClient->getPaymentStatus($result->getId());
            dump($data);
            dump($data->status);*/

            /*$data = $hitPayClient->deletePaymentRequest($data->getId());
            print_r($data);*/


        } catch (\Exception $e) {
            $return['msg'] = $e->getMessage();
        }

        return $return;
    }


}