<?php

namespace app\common\command;


use app\common\model\MemberModel;
use app\common\model\OrderModel;
use app\common\model\ProductModel;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\Db;

/**
 * 测试用例
 * Class Testing
 * @package app\common\command
 */
class Testing extends Command
{
    protected function configure()
    {
        $this->setName('testing')
            ->addArgument('action', Argument::REQUIRED, "add front member")
            ->addOption('username', 'u', Option::VALUE_OPTIONAL, 'username, usefor prefix if count great then 1')
            ->addOption('count', 'c', Option::VALUE_OPTIONAL, 'count of user, default 1')
            ->addOption('password', 's', Option::VALUE_OPTIONAL, 'password of all user, default 123456')
            ->addOption('parent', 'p', Option::VALUE_OPTIONAL, 'reference of the users.')
            ->addOption('buyproduct', 'b', Option::VALUE_OPTIONAL, 'auto recharge and buy the specified product.')
            ->addOption('type', 't', Option::VALUE_OPTIONAL, 'type of product for member upgrade, default 4')
            ->setDescription('Testing command');
    }

    /**
     * 命令调度
     * @param Input $input
     * @param Output $output
     * @return mixed
     */
    protected function execute(Input $input, Output $output)
    {
        $action=$input->getArgument('action');

        if(method_exists($this,'action'.ucfirst($action))){
            call_user_func([$this,'action'.ucfirst($action)],$input,$output);
        }else{
            $output->error('act error. excepted actions: random, adduser, resetrcount, order');
        }
        $output->writeln('exit.');
    }

    /**
     * 重置会员的推荐人数目
     * @param Input $input
     * @param Output $output
     */
    protected function actionResetrcount(Input $input, Output $output)
    {
        Db::name('member')->where('id','GT',0)->update(['recom_count'=>0,'team_count'=>0]);
        $members=Db::name('member')->field('id,referer')
            ->where('is_agent','GT',0)
            ->where('referer','GT',0)
            ->select();
        $layer=getSetting('performance_layer');
        foreach ($members as $member){
            $parents=getMemberParents($member['id'],$layer);
            if(!empty($parents)) {
                Db::name('member')->where('id', $parents[0])->setInc('recom_count', 1);
                Db::name('member')->whereIn('id', $parents)->setInc('team_count', 1);
                $output->writeln('user '.$member['id'].'\'s parents recommend count updated');
            }else{
                $output->error('user '.$member['id'].'\'s parent '.$member['referer'].' not found');
            }
        }
    }

    /**
     * 随机数据测试
     * @param Input $input
     * @param Output $output
     */
    protected function actionRandom(Input $input, Output $output)
    {
        $pid=0;
        $ptype=4;
        if($input->hasOption('buyproduct')){
            $pid=$input->getOption('buyproduct');
        }
        if($input->hasOption('type')){
            $ptype=$input->getOption('type');
        }

        $count=$input->getOption('count');
        while($count--){
            $isnew = rand(0,99)>50;
            if($isnew){
                $product=$this->getProduct($pid, $ptype);
            }else{
                $product=$this->getProduct($pid, 1);
            }
            if(empty($product)){
                $output->writeln('No suitable goods.');
                break;
            }
            $member=Db::name('member')->where('is_agent','GT',0)->order(Db::raw('rand()'))->find();
            if($isnew){
                $output->writeln('User '.$member['username'].'['.$member['id'].'] recommended new member: ');

                $newname='u'.random_str(mt_rand(5,8));
                while(Db::name('member')->where('username',$newname)->count()){
                    $newname='u'.random_str(mt_rand(5,8));
                }

                $this->createUser($output,$newname,'123456',$member['id'],$product);
            }else{
                $output->writeln('User '.$member['username'].'['.$member['id'].'] buy goods:');

                $this->makeOrder($output,$member,$product);
            }

            sleep(1);
        }

    }

    /**
     * 添加会员的命令
     * @param Input $input
     * @param Output $output
     */
    protected function actionAdduser(Input $input, Output $output)
    {
        if(!$input->hasOption('username')){
            $output->error('username option must be specified.');
            return;
        }
        $username=$input->getOption('username');
        $count=1;
        $password='123456';
        $parent=0;
        $buyproduct=0;
        $product=[];
        $address=[];
        if($input->hasOption('count')){
            $count=intval($input->getOption('count'));
        }
        if($input->hasOption('password')){
            $password=intval($input->getOption('password'));
        }
        if($input->hasOption('parent')){
            $parent=intval($input->getOption('parent'));
        }
        if($input->hasOption('buyproduct')){
            $buyproduct=intval($input->getOption('buyproduct'));
        }
        if($buyproduct>0){
            $product=$this->getProduct($buyproduct);
        }

        if($count<=1){
            $this->createUser($output,$username,$password,$parent,$product);
        }else{
            for($i=0;$i<$count;$i++){
                $sufix=str_pad($i,strlen($count),'0',STR_PAD_LEFT);
                $address['receive_name']=$username.$sufix;
                $this->createUser($output,$username.$sufix,$password,$parent,$product);
            }
        }
    }

    /**
     * 调用下单命令
     * @param Input $input
     * @param Output $output
     */
    protected function actionOrder(Input $input, Output $output)
    {
        $userid='';
        $buyproduct=0;
        if($input->hasOption('username')){
            $userid=$input->getOption('username');
        }
        if($input->hasOption('buyproduct')){
            $buyproduct=intval($input->getOption('buyproduct'));
        }

        if(!$userid){
            $output->error('username option must be specified.');
            return;
        }
        if(!$buyproduct){
            $output->error('buyproduct option must be specified.');
            return;
        }

        $product=$this->getProduct($buyproduct);

        $user=Db::name('Member')->where('id|username',$userid)->find();
        $this->makeOrder($output,$user,$product);
    }

    /**
     * 根据会员的推荐人的地址新增一条，如果没有，使用默认数据
     * @param $user
     */
    private function createAddress($user)
    {
        $address=Db::name('MemberAddress')->where('member_id',$user['referer'])->find();
        if(empty($address)){
            $address=[
                'receive_name'=>$user['nickname']?:$user['username'],
                'mobile'=>$user['mobile']?:'13866888866',
                'province'=>$user['province']?:'广东省',
                'city'=>$user['city']?:'中山市',
                'area'=>$user['area']?:'市区',
                'address'=>$user['address']?:'测试地址',
                'code'=>'000000',
                'is_default'=>1
            ];
        }else{
            $address['is_default']=1;
            $address['receive_name']=$user['nickname']?:$user['username'];
            if(!empty($user['mobile']))$address['mobile']=$user['mobile'];
            if(!empty($user['province']))$address['province']=$user['province'];
            if(!empty($user['city']))$address['city']=$user['city'];
            if(!empty($user['area']))$address['area']=$user['area'];
            if(!empty($user['address']))$address['address']=$user['address'];
            unset($address['address_id']);
        }
        $address['receive_name'] = filter_emoji($address['receive_name']);
        $address['member_id'] = $user['id'];
        Db::name('MemberAddress')->insert($address);
    }

    /**
     * 创建一个会员，如果指定了商品id，则顺便下单购买了
     * @param Output $output
     * @param $username
     * @param $password
     * @param $parent
     * @param $product
     * @return bool
     */
    private function createUser(Output $output,$username,$password,$parent,$product)
    {
        $data['username']=$username;
        $data['salt']=random_str(8);
        $data['password']=encode_password($password,$data['salt']);
        $data['referer']=$parent;
        $data['level_id']=getDefaultLevel();
        $model=MemberModel::create($data);
        if(empty($model['id'])){
            $output->error('Create user '.$username.' failed!');
            return false;
        }
        //$model->setReferer($parent);
        $output->writeln('Create user '.$username.'['.$model['id'].','.$parent.'] successed!');
        if(!empty($product)){
            $this->makeOrder($output,$model,$product);
        }
        return true;
    }

    /**
     * 获取指定产品用于下单,不指定id则随机获取一件激活商品
     * @param int $id
     * @return array|null|\PDOStatement|string|\think\Model
     */
    private function getProduct($id=0, $type=2)
    {
        if(!$id){
            $aprods = Db::name('product')->where('type',$type)->where('status',1)->field('id,min_price')->select();
            $aprod = weight_random($aprods,'min_price', false);
            $id=$aprod['id'];
        }
        $sku = Db::name('productSku')->where('product_id',$id)->find();

        $products=ProductModel::getForOrder([$sku['sku_id']=>1]);

        return $products[0];
    }

    /**
     * 自动充值并下单
     * @param Output $output
     * @param $user
     * @param $product
     */
    private function makeOrder(Output $output,$user,$product){

        money_log($user['id'],$product['product_price']*100,'Testing recharge','system');

        $address=Db::name('MemberAddress')
            ->where('member_id',$user['id'])
            ->order('is_default DESC')->find();
        if(empty($address)){
            $this->createAddress($user);
            $address=Db::name('MemberAddress')
                ->where('member_id',$user['id'])
                ->order('is_default DESC')->find();
        }
        $model = new OrderModel();
        $result=$model->makeOrder($user,[$product],$address,'Testing order',1);
        if($result){
            $output->writeln('User '.$user['username'].'['.$user['id'].'] order successed!');
        }else{
            $output->error('User '.$user['username'].'['.$user['id'].'] order failed:'.$model->getError());
        }
    }
}