<?php
/**
 * Created by PhpStorm.
 * User: leo
 * Date: 2018/2/24
 * Time: 下午12:48
 */

namespace frontendApi\modules\v1\controllers;

use common\helpers\bonus\CalcCache;
use common\helpers\Cache;
use common\helpers\Email;
use common\helpers\Form;
use common\helpers\LoggerTool;
use common\helpers\Tool;
use common\helpers\user\Info;
use common\models\BaUser;
use common\models\Config;
use common\models\Countries;
use common\models\Currency;
use common\models\CurrencyConversions;
use common\models\DeclarationLevel;
use common\models\DeclarationPackage;
use common\models\DecOrder;
use common\models\forms\ApproachDeclarationLoopForm;
use common\models\forms\BaApproachDeclarationLoopForm;
use common\models\forms\ApproachDeclarationUpgradeForm;
use common\models\forms\BaUserForm;
use common\models\forms\DeclarationForm;
use common\models\forms\BaDeclarationForm;
use common\models\forms\DeclarationLoopForm;
use common\models\forms\BaDeclarationLoopForm;
use common\models\forms\UploadForm;
use common\models\forms\UserBindForm;
use common\models\forms\UserForm;
use common\models\Instalment;
use common\models\OpenBank;
use common\models\Period;
use common\models\ReceiveAddress;
use common\models\Region;
use common\models\ShopGoods;
use common\models\ShopGoodsNature;
use common\models\UpgradeType;
use common\models\User;
use common\models\UserBind;
use common\models\UserBonus;
use common\models\UserInfo;
use common\models\BaUserInfo;
use common\models\UserNetwork;
use common\models\forms\DeclarationUpgradeForm;
use common\models\UserPerformance;
use common\models\UserWallet;
use frontendApi\modules\v1\models\Relation;
use Yii;
use yii\db\Exception;
use yii\web\UploadedFile;

class UserController extends BaseController {
    public $modelClass = UserInfo::class;

    const LOOP_FINISH = 1;

    /**
     * 会员资料
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionIndex() {
        $allNation = \Yii::$app->params['nation'];
        $allOpenBank = OpenBank::findAllAsArray('STATUS=1');
        $data['allNation'] = $allNation;
        $data['allOpenBank'] = $allOpenBank;
        $data['userInfo'] = User::getEnCodeInfo(\Yii::$app->user->id);
        $data['userInfo']['NATION'] = $data['userInfo']['NATION_ID'];
        return static::notice($data);
    }

    /**
     * 编辑会员资料
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionEdit() {
        if(\Yii::$app->request->isPost){
            $form = new UserForm();
            $post = \Yii::$app->request->post();
            $form->scenario = 'modifyProfile';
            if($form->load($post, '') && $result = $form->modifyProfile()){
                return static::notice(Yii::t('app', 'personalDataModifiedSuccessfully'), 400);
            } else {
                return static::notice(Form::formatErrorsForApi($form->getErrors()), 400);
            }
        }
        return static::notice(Yii::t('app', 'illegalRequest'), 400);
    }

    /**
     * 修改登录密码
     */
    public function actionPassword(){
        if(\Yii::$app->request->isPost){
            $form = new UserForm();
            $form->scenario = 'modifyPassword';
            $post = \Yii::$app->request->post();
            if($form->load($post, '') && $result = $form->modifyPassword()){
                return static::notice(Yii::t('app', 'passwordModifiedSuccessfully'), 400);
            } else {
                return static::notice(Form::formatErrorsForApi($form->getErrors()), 400);
            }
        }
        return static::notice(Yii::t('app', 'illegalRequest'), 400);
    }

    /**
     * 修改支付密码
     */
    public function actionPayPassword(){
        if(\Yii::$app->request->isPost){
            $form = new UserForm();
            $form->scenario = 'modifyPasswordPay';
            $post = \Yii::$app->request->post();
            $form->userId = \Yii::$app->user->id;
            if($form->load($post, '') && $result = $form->modifyPasswordPay()){
                return static::notice(Yii::t('app', 'passwordModifiedSuccessfully'));
            } else {
                return static::notice(Form::formatErrorsForApi($form->getErrors()), 400);
            }
        }
        return static::notice(Yii::t('app', 'illegalRequest'), 400);
    }

    /**
     * 直推会员列表
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionRecUser() {
        $allData = UserInfo::lists('AND REC_UID=:REC_UID', [':REC_UID' => \Yii::$app->user->id], ['useSlaves' => true, 'select'=>'USER_ID,CREATED_AT']);
        foreach ($allData['list'] as $key => $data) {
            $userBaseInfo = User::getEnCodeInfo($data['USER_ID']);
            $userBaseInfo['NATION'] = \Yii::$app->params['nation'][$userBaseInfo['NATION']]['name'] ?? '';
            $allData['list'][$key]['BASE_INFO'] = $userBaseInfo;
        }
        return static::notice($allData);
    }

    /**
     * 上传身份证
     * @return mixed
     * @throws \yii\base\Exception
     * @throws \yii\web\HttpException
     */
    public function actionIdCard() {
        if (\Yii::$app->request->isPost) {
            $formModel = new UploadForm();
            $formModel->scenario = 'idCardFront';
            $formModel->file = UploadedFile::getInstanceByName('file');
            //$formModel->token = \Yii::$app->request->post('uploadToken');
            $formModel->token = \Yii::$app->request->request('uploadToken');
            if ($formModel->file && $formModel->upload()) {
                return static::notice(Yii::t('app', 'successfully'));
            } else {
                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
            }
        }
        // 查看该用户是否已经上传过身份证
        $oneData = User::find()->select('ID_IMAGE')->where('ID=:ID', [':ID' => \Yii::$app->user->id])->asArray()->one();
        if ($oneData['ID_IMAGE']) {
            return static::notice($oneData);
        } else {
            $token = Cache::setUploadToken();
            return static::notice($token);
        }
    }

    /**
     * 点位绑定
     * @return mixed
     * @throws \yii\base\Exception
     * @throws \yii\web\HttpException
     */
    public function actionBind() {
        $userBind = UserBind::findOneAsArray('USER_ID=:USER_ID AND IS_DEL=0', [':USER_ID' => \Yii::$app->user->id]);
        $allData['list']=UserBind::findAllAsArray('MAIN_UID=:MAIN_UID AND IS_DEL=0', [':MAIN_UID' => $userBind['MAIN_UID']], 'ID,USER_ID,MAIN_UID,CREATED_AT,UPDATED_AT');
        foreach ($allData['list'] as $key => $value) {
            $baseInfo = Info::baseInfoZh($value['USER_ID']);
            if ($baseInfo['STATUS'] != 1) {
                unset($allData['list'][$key]);
                continue;
            }
            $allData['list'][$key]['USER_NAME'] = $baseInfo['USER_NAME'];
            $allData['list'][$key]['REAL_NAME'] = $baseInfo['REAL_NAME'];
            $allData['list'][$key]['BANK_PROVINCE_NAME'] = $baseInfo['BANK_PROVINCE_NAME'];
            $allData['list'][$key]['BANK_CITY_NAME'] = $baseInfo['BANK_CITY_NAME'];
            $allData['list'][$key]['BANK_COUNTY_NAME'] = $baseInfo['BANK_COUNTY_NAME'];
            $allData['list'][$key]['OPEN_BANK_NAME'] = $baseInfo['OPEN_BANK_NAME'];
            $allData['list'][$key]['BANK_NO'] = $baseInfo['BANK_NO'];
            $allData['list'][$key]['MAIN_USER_NAME'] =Info::getUserNameByUserId($value['MAIN_UID']);
        }
        $allData['list'] = array_values($allData['list']);
        return static::notice($allData);
    }

    /**
     * 编辑点位绑定
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionBindEdit(){
        $id = \Yii::$app->request->get('id');
        if(\Yii::$app->request->isPost) {
            return parent::edit(UserBindForm::class, Yii::t('app', 'successfully'), 'frontEdit', ['frontEdit'], null, function($form, $result){
                //log
            });
        }
        // 获得当前会员的用户名等信息
        $userBind = UserBind::findOneAsArray('ID=:ID AND IS_DEL=0', [':ID' => $id]);
        $userBinds = UserBind::findAllAsArray('MAIN_UID=:MAIN_UID AND IS_DEL=0',[':MAIN_UID'=>$userBind['MAIN_UID']], 'ID,USER_ID,MAIN_UID,CREATED_AT,UPDATED_AT');
        foreach($userBinds as $key=>$value){
            $status = Info::getStatusByUserId($value['USER_ID']);
            if ($status != 1) {
                unset($userBinds[$key]);
                continue;
            }
            $userBinds[$key]['USER_NAME'] = Info::getUserNameByUserId($value['USER_ID']);

        }
        $userBinds = array_values($userBinds);
        return static::notice(['userBinds' => $userBinds,'mainUid'=>$userBind['MAIN_UID']]);
    }

    // 会员升级,通过会员的编号,获取会员信息
    public function actionUpgradeInfo() {
        $isSwitchUpgrade = Config::find()
        ->where("CONFIG_NAME='isOpenUpgrade'")
        ->asArray()
        ->one();
        $isOpen = !empty($isSwitchUpgrade) && isset($isSwitchUpgrade['VALUE']) ? $isSwitchUpgrade['VALUE'] : 0;
        if ($isOpen < 1) {
            return static::notice(Yii::t('app', 'theFunctionIsNotAvailable'), 400);
        }
        $userNumber = \Yii::$app->request->request('userName');
        $baseInfo = Info::baseInfoZhByUserName($userNumber);
        if ($baseInfo['STATUS'] != 1) {
            return static::notice(Yii::t('app', 'inactiveUser'), 400);
        }

        $loginUserInfo = User::getEnCodeInfo(\Yii::$app->user->id);
        if ($baseInfo['COUNTRY_ID'] !== $loginUserInfo['COUNTRY_ID']) {
            return static::notice(Yii::t('app', 'memberNumberDoesNotExist'), 400);
        }

        // 1. 如果是最高级别,则只显示用户基本信息
        // 2. 如果不是最高级别,如果用户累计报单数据是0, 或者用户累计报单业绩不符合级别信息,则提示 请联系客服核对业绩
        $userId = $baseInfo['ID'];
        $userDecId = $baseInfo['DEC_LV'];// 用户当前的级别
        // 获取系统中的DEC 报单级别配置
        $decConfig = DeclarationLevel::getAllData();
        $userDecInfo = $decConfig[$userDecId]; // 会员的级别具体信息
        $maxPerfInfo = DeclarationLevel::getMaxDecPref();
        $maxDecId = $maxPerfInfo['ID']; // 级别配置中最高级别ID
        $observe = Config::getConfigByType('observe'); // 获取观察期配置信息
        $observeLimit = $observe['observePeriodLimit']['value']; // 月份限制
        $isObserve = User::checkIsObserve($baseInfo['CREATED_AT'], $observeLimit); // 判断用户是否再观察期中
        // 如果用户已经是最高级别,则只展示用户信息
        $isMax = false;
        if ($maxDecId == $userDecId) {
            $isMax = true;
        }

        // NA级别暂时不提供升级
        if ($userDecInfo['ID'] == '67ABC6AO8YTK2LN0E055736AECE8644D') {
            return static::notice(Yii::t('app', 'upgradeNotSupport'), 400);
        }

        // 分期的总期数
        $instalmentConfig = intval(Cache::getSystemConfig()['instalment']['VALUE'] ?? 3);
        // 查询是否有FX的分期订单
        $stageFX = Instalment::getOneStage($baseInfo['ID'], 'FX');
        if ($stageFX && $stageFX < $instalmentConfig) {
            $instalment = false;
        } else {
            // 是否有未完成的BD类型的分期订单
            $stage = Instalment::getOneStage($userId, 'BD');
            if ($stage && $stage < $instalmentConfig) {
                $instalment = true;
            } else if ($isMax && $stage == $instalmentConfig) {
                $instalment = false;
            } else {
                $instalment = false;
            }
        }

        // 如果用户已经是最高级别,则只展示用户信息
        $userInfo = [
            'DEC_NAME' => $baseInfo['DEC_LV_NAME'], // 用户级别中文
            'DEC_ID' => $userDecId, // 用户级别id
            'REAL_NAME' => $baseInfo['REAL_NAME'], // 真实姓名
            'ADD_AT' => date('Y-m-d', $baseInfo['CREATED_AT']), // 加入时间
            'COUNTRY_NAME' => $baseInfo['COUNTRY_NAME'], // 国家
            'IS_OBSERVE' => $isObserve, // 是否是观察期  true为是观察期
            'IS_MAX' => $isMax, // 是否已是最大级别 最大级别不需要判断报单总PV是多少 只展示基本信息
            'INSTALMENT' => $instalment,
            'NOW_PERF' => User::sumDevPvByUserId($userId), // 用户所有报单PV总和
        ];

        // 如果是最高级别了,则无需升级
        if ($isMax) {
            return static::notice(['baseInfo' => $userInfo]);
        }

        $levelPerf = $userDecInfo['PERF'];// 用户当前级别对应的业绩值
        if (!$isMax) {
            $userDecPvSum = User::sumDevPvByUserId($userId); // 用户所有报单PV总和
            // // 如果总和小于级别业绩 去掉这校验直接补比如3000-980的差值
            // if ($userDecPvSum < $levelPerf) {
            //     return static::notice('请联系客服人员核对业绩',400);
            // }
            // 下一级业绩
            $nextLevelPerf = DeclarationLevel::getNextDecPref($levelPerf)['PERF'];
            // 如果总和超过了下一级业绩
            if ($userDecPvSum >= $nextLevelPerf) {
                return static::notice(Yii::t('app', 'checkPerformance'), 400);
            }
            $type = $isObserve ? 1 : 2;
            $userInfo['UPGRADE_FUNC'] = $isObserve ? Yii::t('app', 'fillingUpOfADeficit') : Yii::t('app', 'fullPayment');
            $upgradeType = UpgradeType::getOneByType($type);
            // 如果用户不是最大级别,则需要获取是否观察期,算出PV是否有问题,应该补多少,
            $userInfo['UPGRADE_TYPE'] = $upgradeType;
            $userInfo['NOW_PERF'] = $userDecPvSum;
            $userInfo['NEXT_PERF'] =  $nextLevelPerf;
            // 用户可选择的级别列表
            $userInfo['LEVEL_LIST'] = DeclarationLevel::getNextAll($levelPerf);// 用户可选择的级别列表
            // 如果用户正处于报单分期中，则可以升级到Elite
            $userInstalmentInfo = Instalment::getInfo($userId);
            if($userInstalmentInfo){
                if ($userInstalmentInfo['ORDER_TYPE']=='BD' && $userInstalmentInfo['STAGE'] < 3){
                    $userInfo['LEVEL_LIST'] = DeclarationLevel::getNextAll(12);// 用户可选择的级别列表
                    unset($userInfo['LEVEL_LIST'][$userDecId]);
                }
            }
            // 循环列表,补充升级所需要的补差
            foreach ($userInfo['LEVEL_LIST'] as &$v) {
                $v['REPAIR_PV'] = $isObserve ? $v['PERF'] - $userInfo['NOW_PERF'] : $v['PERF'];
            }
        }

        return static::notice(['baseInfo' => $userInfo]);
    }

    // 会员升级管理
    public function actionUpgrade() {
        $isMax = \Yii::$app->request->get('isMax');
        $userNumber = \Yii::$app->request->get('userName');

        $isSwitchUpgrade = Config::find()
        ->where("CONFIG_NAME='isOpenUpgrade'")
        ->asArray()
        ->one();
        $isOpen = !empty($isSwitchUpgrade) && isset($isSwitchUpgrade['VALUE']) ? $isSwitchUpgrade['VALUE'] : 0;
        if ($isOpen < 1) {
            return static::notice(Yii::t('app', 'theFunctionIsNotAvailable'), 400);
        }
        // 开始升级
        if (\Yii::$app->request->isPost) {
            $post = \Yii::$app->request->post();
            // 根据支付方式区分逻辑
            $payMethod = \Yii::$app->request->post('payType', '');
            if ($payMethod === 'pay_stack') {
                $formModel = new ApproachDeclarationUpgradeForm();
            } else {
                unset($post['payType']);
                $formModel = new DeclarationUpgradeForm();
            }

            $stockist = $post['decUserName'] ?? '';
            if (!$stockist) {
                return static::notice(Yii::t('app', 'stockistDoesNotExist'), 400);
            }

            $post['type'] = DeclarationForm::TYPE_ZC;
            if ($formModel->load($post, '') && $result = $formModel->add($post)) {
                return static::notice($result);// Upgrade declaration succeeded升级报单成功
            } else {
                return static::notice(Form::formatErrorsForApi($formModel->getErrors()),400);
            }
        }

        // 升级的会员
        $userName = \Yii::$app->request->get('userName');
        // 会员信息
        $user = User::findOneAsArray('USER_NAME=:USER_NAME', [':USER_NAME' => trim($userName)]);
        if (!$user) {
            return static::notice(Yii::t('app', 'memberNumberDoesNotExist'), 400);
        }

        //所有报单套餐
        $allDecPackage = DeclarationPackage::getAllData();
        $decLevels = Cache::getDecLevelConfig();
        foreach ($allDecPackage as $k=>$v){
            $levelName = $decLevels[$v['LEVEL_ID']]['LEVEL_NAME'] ?? '';
            $allDecPackage[$k]['LEVEL_NAME'] = $levelName;
        }

        $baseInfo = Info::baseInfoZhByUserName($userNumber);
        // 分期的总期数
        $instalmentConfig = intval(Cache::getSystemConfig()['instalment']['VALUE'] ?? 3);
        // 查询是否有FX的分期订单
        $stageFX = Instalment::getOneStage($baseInfo['ID'], 'FX');
        if ($stageFX && $stageFX < $instalmentConfig) {
            if ($isMax === "true") {
                $condition = ") AND S.INSTALMENT = 1000";
            } else {
                $condition = ") AND (S.INSTALMENT = 0 OR S.INSTALMENT = 1000)";
            }
        } else {
            // 是否有未完成的BD类型的分期订单
            $stageBD = Instalment::getOneStage($baseInfo['ID'], 'BD');
            if ($isMax === "true") {
                if ($stageBD > 0 && $stageBD < $instalmentConfig) {
                    $condition = ") AND (S.INSTALMENT = " . ($stageBD + 1) . ")";
                } else {
                    $condition = ") AND S.INSTALMENT = 0";
                }
            } else {
                if ($stageBD > 0 && $stageBD < $instalmentConfig) {
                    $condition = ") AND (S.INSTALMENT = 0 OR S.INSTALMENT = " . ($stageBD + 1) . ")";
                } else {
                    $condition = ") AND (S.INSTALMENT = 0 OR S.INSTALMENT = 1)";
                }
            }
        }

        //所有自选商品
        $isDecReg = Cache::getSystemConfig()['isDecReg']['VALUE'];
        $isDec = User::getEnCodeInfo(\Yii::$app->user->id)['IS_DEC'];
        $isStudio = User::getEnCodeInfo(\Yii::$app->user->id)['IS_STUDIO'];
        $decUserName = User::getEnCodeInfo(\Yii::$app->user->id)['USER_NAME'];
        $query_condition= " AND (1<>1";
        if(!$isDecReg || ($isDecReg && $isDec==1)){
            $query_condition = " AND (FIND_IN_SET(1, S.GIFT_TYPE)>0";
        }
        if($isStudio==1){
            $query_condition .= " OR FIND_IN_SET(3, S.GIFT_TYPE)>0";
        }

        $query_condition .= $condition . ' AND N.COUNTRY_ID=:COUNTRY_ID ';

        $allGoods = ShopGoods::find()
            ->alias('S')
            ->select('S.*,N.MARKET_PRICE,N.SELL_PRICE,N.TAX_RATE,N.LOCAL_CURRENCY_ID,N.COUNTRY_ID,C.CODE')
            ->join('INNER JOIN', ShopGoodsNature::tableName() . ' AS N', 'N.GOODS_ID=S.ID')
            ->join('INNER JOIN', Currency::tableName() . ' AS C', 'C.ID=N.LOCAL_CURRENCY_ID')
            ->where("STATUS=1 AND CATEGORY_TYPE=1 " . $query_condition, [':COUNTRY_ID' => $user['COUNTRY_ID']])
            ->orderBy('SORT ASC')
            ->asArray()
            ->all();

        foreach ($allGoods as &$goods) {
            $goods['TAX'] = Tool::calculateTax($goods['SELL_PRICE'], $goods['TAX_RATE']);
        }

        // 报单中心汇率
        $decCountryId = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
        $decCountry = Countries::getById($decCountryId);
        $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']);
        // 升级会员汇率
        $country = Countries::getById($user['COUNTRY_ID']);
        $currencyRate = CurrencyConversions::getToUSDRate($country['LOCAL_CURRENCY_ID']);
        // 升级会员币种
        $currency = Currency::getById($country['LOCAL_CURRENCY_ID']);

        $userBalance = [
            'cash' => 0,
            'localCash' => 0,
            'coin' => '',
        ];
        // 会员余额
        $userCash = UserWallet::findOneAsArray(['USER_ID' => \Yii::$app->user->id]);
        if ($userCash) {
            $userBalance['cash'] = $userCash['CASH'];
            $userBalance['coin'] = $currency['CODE'] ?? '';
            $userBalance['localCash'] = Tool::convertAmount($userCash['CASH'], $decUserCurrencyRate, $currencyRate);
        }
        // 会员绩效奖金
        $userPerformanceAmount = UserPerformance::getAmounts(\Yii::$app->user->id);

        $userBalance['prp'] = $userPerformanceAmount ?? 0;
        $userBalance['localPrp'] = Tool::convertAmount($userPerformanceAmount, $decUserCurrencyRate, $currencyRate);

        // 行政区划
        $region = Region::getByCountryId($user['COUNTRY_ID']);
        // 支付方式
        $payList = ShopGoods::payTypes();
        unset($payList['prp']);
        // 售卖方式
        $sellType = ShopGoods::getCategoryType();
        unset($sellType[0]['sell_type'][1]);

        return static::notice([
            'allDecPackage' => $allDecPackage,
            'allGoods' => $allGoods,
            'decUserName'=>$decUserName,
            'payList' => $payList,
            'sellType' => $sellType,
            'categoryType' => ShopGoods::getCategoryType()[0]['id'],
            'userBalance' => $userBalance,
            'decUserCurrencyRate' => $decUserCurrencyRate,
            'userCurrencyRate' => $currencyRate,
            'region' => $region,
        ]);
    }

    /**
     * 报单管理
     */
    public function actionDec() {
        $redis = \Yii::$app->redis;
        $post = \Yii::$app->request->post();
        if (\Yii::$app->request->isPost) {
            $email = $post['email'] ?? '';
            if ($email && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
                return static::notice(Yii::t('app', 'invalidEmail'), 400);
            }

            $stockist = $post['decUserName'] ?? '';
            if (!$stockist) {
                return static::notice(Yii::t('app', 'stockistDoesNotExist'), 400);
            }

            $loginUserInfo = User::getEnCodeInfo(\Yii::$app->user->id);
            if($loginUserInfo['IS_DEC'] == 1 && !empty($post['decUserName']) && $post['decUserName'] != $loginUserInfo['USER_NAME']){
                return static::notice(Yii::t('app', 'decUserNameIsWrong'), 400);
            }
            if($loginUserInfo['IS_DEC'] == 0 && $post['decUserName']){
                //查询报单编号是否存在
                $userId = Info::getUserIdByUserName($post['decUserName']);
                if(!$userId){
                    return static::notice(Yii::t('app', 'decUserNameIsWrong'), 400);
                }
                $isDec = User::getEnCodeInfo($userId)['IS_DEC'];
                if(!$isDec){
                    return static::notice(Yii::t('app', 'decUserNameIsWrong'), 400);
                }
            }

            $conUserName = trim($post['conUserName']); // 实际推荐人
            $recUserName = trim($post['recUserName']);

            // 如果推荐人和实际推荐人是同一人,则跳过检查
            if ($recUserName != $conUserName) {
                // 实际推荐人必须是推荐人的推荐网上级
                $sqlUp = <<<SQL
            WITH recursive t_rec AS 
            (
                SELECT
                    m.USER_ID,
                    U.USER_NAME,
                    m.PARENT_UID,
                    U2.USER_NAME AS PARENT_NAME,
                    1 AS node_level 
                FROM
                    AR_USER_RELATION_NEW m 
                    LEFT JOIN AR_USER U ON U.ID = m.USER_ID
                    LEFT JOIN AR_USER U2 ON U2.ID = m.PARENT_UID
                WHERE
                    U.USER_NAME = :USER_NAME 
                    
                UNION ALL
                
                SELECT
                    t1.USER_ID,
                    U.USER_NAME,
                    t1.PARENT_UID,
                    U2.USER_NAME AS PARENT_NAME,
                    t2.node_level + 1 -- 结点层级
                    
                FROM
                    AR_USER_RELATION_NEW t1
                    JOIN t_rec t2 ON t2.PARENT_UID = t1.USER_ID
                    LEFT JOIN AR_USER U ON U.ID = t1.USER_ID
                    LEFT JOIN AR_USER U2 ON U2.ID = t1.PARENT_UID
                ) 
            SELECT
                * 
            FROM
                t_rec
SQL;
                // 查询推荐人的所有上级
                $relationNodeUp = \Yii::$app->db->createCommand($sqlUp)
                    ->bindValue(':USER_NAME', $post['recUserName'])
                    ->queryAll();

                $relationNodeUp = array_column($relationNodeUp, 'USER_NAME');
                unset($relationNodeUp[$post['recUserName']]);

                if (!in_array($post['conUserName'], $relationNodeUp)) {
                    return static::notice(Yii::t('app', 'fillSponsorUpline'), 400);
                }
            }

            // 根据支付方式区分逻辑
            $payMethod = \Yii::$app->request->post('payType', '');

            if ($payMethod === 'pay_stack') {
                $formModel = new ApproachDeclarationLoopForm();
            } else {
                unset($post['payType']);
                $formModel = new DeclarationLoopForm();
            }

            $formModel->scenario = 'userDec';

            $post['province'] = $post['province'] ? :1;
            $post['city'] = $post['city'] ? :1;
            $post['county'] = $post['county'] ? :1;

            $post['cityName'] = trim($post['cityName']);
            $post['lgaName'] = trim($post['lgaName']);

            // 针对那群沙雕移除安置网络的行为,强制增加自动安置左侧
            $recUserId = Info::getUserIdByUserName($conUserName);
            $bottomPlace = UserNetwork::getBottomPlace($recUserId,'', 'left');
            $bottomUser = UserNetwork::find()->select('USER_ID')->where('LOCATION_TAG=:LOCATION_TAG', ['LOCATION_TAG' => $bottomPlace])->asArray()->one();
            $bottomUser = User::findOneAsArray('ID=:ID', [':ID' => $bottomUser['USER_ID']], 'USER_NAME');
            $bottomUser = $bottomUser['USER_NAME']; // 推算出的安置人

            $post['conUserName'] = $bottomUser; // 安置人
            $post['recUserName'] = $conUserName; // 实际推荐人
            $post['bottomUserName'] = $recUserName; // 推荐人

            $post['location'] = 1;

            // 针对于会员编号的判断
            $insertUserName = strtoupper($post['insertUserName']);
            $getRedisUserName = $redis->get('key_' . $insertUserName);
            if (!$getRedisUserName){
                return static::notice(Yii::t('app', 'memberNumberExpired'), 400);
            }
            if ($insertUserName != $getRedisUserName){
                return static::notice(Yii::t('app', 'memberNumberDoesNotConformTo'), 400);
            }

            $post['insertUserName'] = $insertUserName;
            $post['type'] = DeclarationForm::TYPE_ZC;

            $allData['data'][] = $post;

            try {
                if ($formModel->load($allData, '') && $result = $formModel->add()) {
                    //发送邮件
//                    Email::sendRegistrationEmail($post['email'], $post['insertUserName'], $post['password']);
                    return static::notice($result);//报单成功
                } else {
                    return static::notice(Form::formatErrorsForApi($formModel->getErrors()),400);
                }
            } catch (\Exception $e) {
                LoggerTool::error($e->getMessage() . '; ' . $e->getLine() . '; ' . $e->getFile());
                return static::notice(Form::formatErrorsForApi($formModel->getErrors()),400);
            }
        }

        // 默认国家
        $countryId = \Yii::$app->request->get('countryId');
        if (!$countryId) {
            return static::notice(Yii::t('app', 'countryDoesNotSelect'), 400);
        }
        // 生成随机码 , 初始化redis
        $userName = Info::generateWebName($countryId);

        //所有报单套餐
        $allDecPackage = DeclarationPackage::getAllData();
        $decLevels = Cache::getDecLevelConfig();
        foreach ($allDecPackage as $k=>$v){
            $levelName = $decLevels[$v['LEVEL_ID']]['LEVEL_NAME'] ?? '';
            $allDecPackage[$k]['LEVEL_NAME'] = $levelName;
        }
        //所有自选商品
        $isDecReg = Cache::getSystemConfig()['isDecReg']['VALUE'];
        $isDec = User::getEnCodeInfo(\Yii::$app->user->id)['IS_DEC'];
        $isStudio = User::getEnCodeInfo(\Yii::$app->user->id)['IS_STUDIO'];

        $query_condition = " AND (1<>1";
        if(!$isDecReg || ($isDecReg && $isDec==1)){
            $query_condition = " AND (FIND_IN_SET(1, S.GIFT_TYPE)>0";
        }
        if($isStudio==1){
            $query_condition .= " OR FIND_IN_SET(3, S.GIFT_TYPE)>0";
        }
        $query_condition .= ") AND (S.INSTALMENT=0 OR S.INSTALMENT=1) AND N.COUNTRY_ID=:COUNTRY_ID";

        // 只查询普通商品
        $allGoods = ShopGoods::find()
            ->alias('S')
            ->select('S.*,N.MARKET_PRICE,N.SELL_PRICE,N.TAX_RATE,N.LOCAL_CURRENCY_ID,N.COUNTRY_ID,C.CODE')
            ->join('INNER JOIN', ShopGoodsNature::tableName() . ' AS N', 'N.GOODS_ID=S.ID')
            ->join('INNER JOIN', Currency::tableName() . ' AS C', 'C.ID=N.LOCAL_CURRENCY_ID')
            ->where("STATUS=1 AND CATEGORY_TYPE=1 " . $query_condition, [':COUNTRY_ID' => $countryId])
            ->orderBy('SORT ASC')
            ->asArray()
            ->all();

        // 银行开户行
        $allOpenBank = OpenBank::find()
            ->where('STATUS=:STATUS AND COUNTRY_ID=:COUNTRY_ID', [':STATUS' => 1, ':COUNTRY_ID' => $countryId])
            ->orderBy('BANK_NAME ASC')
            ->asArray()
            ->all();

        if (!$userName) {
            return static::notice(Yii::t('app',  'failedToGenerateMemberNumber'), 400);
        }
        //随机码保存在redis中方便进行比对
        $redis->setex('key_'.$userName , 3600 , $userName);

        // 报单中心会员的本地汇率
        $decCountryId = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
        $decCountry = Countries::getById($decCountryId);
        $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']);
        // 新会员的本地汇率
        $country = Countries::getById($countryId);
        $currencyRate = CurrencyConversions::getToUSDRate($country['LOCAL_CURRENCY_ID']);
        // 新会员币种
        $currency = Currency::getById($country['LOCAL_CURRENCY_ID']);

        // 会员账户
        $userBalance = [
            'cash' => 0,
            'localCash' => 0,
            'coin' => '',
        ];
        $userCash = UserWallet::findOneAsArray(['USER_ID' => \Yii::$app->user->id]);
        if ($userCash) {
            $userBalance['cash'] = $userCash['CASH'];
            $userBalance['localCash'] = Tool::convertAmount($userCash['CASH'], $decUserCurrencyRate, $currencyRate);
            $userBalance['coin'] = $currency['CODE'] ?? '';
        }
        // 行政区划
        $region = Region::getByCountryId($countryId);
        // 支付方式
        $payList = ShopGoods::payTypes();
        unset($payList['prp']);
        // 售卖方式
        $sellType = ShopGoods::getCategoryType();
        unset($sellType[0]['sell_type'][1]);

        return static::notice([
            'allDecPackage' => $allDecPackage,
            'allGoods' => $allGoods,
            'allOpenBank' => $allOpenBank,
            'userName' => $userName,
            'payList' => $payList,
            'sellType' => $sellType,
            'categoryType' => ShopGoods::getCategoryType()[0]['id'],
            'userBalance' => $userBalance,
            'isDec' => $isDec,
            'decUserCurrencyRate' => $decUserCurrencyRate,
            'userCurrencyRate' => $currencyRate,
            'region' => $region,
            'decLevel' => DeclarationLevel::getData(),
        ]);
    }

    /**
     * 报单级别套餐
     */
    public function actionDecPackage() {
        $decLv = \Yii::$app->request->get('id');
        //所有报单级别套餐
        $allDecPackage = DeclarationPackage::getPackageFromLevelId($decLv);
        return static::notice(['allDecPackage' => $allDecPackage]);
    }

    /*
     * 从会员名和左右，获取底部安置人
     *
     */
    public function actionGetAutoPlace() {
        $userName = \Yii::$app->request->get('userName');
        $side = \Yii::$app->request->get('side');
        $userId = Info::getUserIdByUserName($userName);
        $bottomPlace = UserNetwork::getBottomPlace($userId,'', $side);
        $bottomUser = UserNetwork::find()->select('USER_ID')->where('LOCATION_TAG=:LOCATION_TAG', ['LOCATION_TAG' => $bottomPlace])->asArray()->one();
        $bottomUser = User::findOneAsArray('ID=:ID', [':ID' => $bottomUser['USER_ID']], 'USER_NAME');
        return static::notice($bottomUser);
    }

    /**
     * 会员信息查询
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionFullInfo()
    {
        $userName = \Yii::$app->request->get('userName');
        $userId = Info::getUserIdByUserName($userName);
        $userInfo['REAL_NAME'] = '';
        $user = User::findOneAsArray('ID=:ID', [':ID' => $userId]);

        $loginUserInfo = User::getEnCodeInfo(\Yii::$app->user->id);
        if ($user['COUNTRY_ID'] !== $loginUserInfo['COUNTRY_ID']) {
            return static::notice(Yii::t('app', 'memberNumberDoesNotExist'), 400);
        }

        if($user){
            $userInfo['REAL_NAME'] = $user['REAL_NAME'];
            $allChildUser = UserNetwork::getFirstFloorChildren($userId);
            $isLocation = [1 => 'Left-Null', 2 => 'Right-Null'];
            if($allChildUser) {
                foreach ($allChildUser as $child) {
                    if ($child['RELATIVE_LOCATION']<'3'){
//                        $isLocation[$child['RELATIVE_LOCATION']].= 'Full';
                        $isLocation[$child['RELATIVE_LOCATION']] = str_replace('Null', 'Full', $isLocation[$child['RELATIVE_LOCATION']]);
                    }
                }
            }

            $userInfo['countryId'] = $user['COUNTRY_ID'];
            $userInfo['userId'] = $userId;
            $userInfo['isLocation'] = '('.implode(',',$isLocation).')';
            return static::notice($userInfo);
        }else{
            return static::notice(Yii::t('app', 'memberNumberDoesNotExist'), 400);
        }
    }

    public function actionInspectNetwork()
    {
        // 推荐人信息
        $recommenderName= \Yii::$app->request->get('recommenderName');
        $userId = Info::getUserIdByUserName($recommenderName);
        $recommender = User::findOneAsArray('ID=:ID', [':ID' => $userId]);
        if (!$recommender) {
            return static::notice(Yii::t('app', 'memberNumberDoesNotExist'), 400);
        }

        // 实际推荐人信息
        $recommenderActualName= \Yii::$app->request->get('recommenderActualName');
        $actualId = Info::getUserIdByUserName($recommenderActualName);
        $recommenderActual = User::findOneAsArray('ID=:ID', [':ID' => $actualId]);
        if (!$recommenderActual) {
            return static::notice(Yii::t('app', 'memberNumberDoesNotExist'), 400);
        }

        // 实际推荐人是否是推荐人本人
        if ($actualId == $userId) {
            return static::notice([
                'REAL_NAME' => $recommenderActual['REAL_NAME'],
                'userId' => $recommenderActual['ID'],
            ]);
        }

        // 实际推荐人必须是推荐人的推荐网上级
        $sqlUp =<<<SQL
            WITH recursive t_rec AS 
            (
                SELECT
                    m.USER_ID,
                    U.USER_NAME,
                    m.PARENT_UID,
                    U2.USER_NAME AS PARENT_NAME,
                    1 AS node_level 
                FROM
                    AR_USER_RELATION_NEW m 
                    LEFT JOIN AR_USER U ON U.ID = m.USER_ID
                    LEFT JOIN AR_USER U2 ON U2.ID = m.PARENT_UID
                WHERE
                    U.USER_NAME = :USER_NAME 
                    
                UNION ALL
                
                SELECT
                    t1.USER_ID,
                    U.USER_NAME,
                    t1.PARENT_UID,
                    U2.USER_NAME AS PARENT_NAME,
                    t2.node_level + 1 -- 结点层级
                    
                FROM
                    AR_USER_RELATION_NEW t1
                    JOIN t_rec t2 ON t2.PARENT_UID = t1.USER_ID
                    LEFT JOIN AR_USER U ON U.ID = t1.USER_ID
                    LEFT JOIN AR_USER U2 ON U2.ID = t1.PARENT_UID
                ) 
            SELECT
                * 
            FROM
                t_rec
SQL;
        // 查询推荐人的所有上级
        $relationNodeUp = \Yii::$app->db->createCommand($sqlUp)
            ->bindValue(':USER_NAME' , $recommenderName)
            ->queryAll();

        $relationNodeUp = array_column($relationNodeUp, 'USER_NAME');
        unset($relationNodeUp[$recommenderName]);

        if (in_array($recommenderActualName, $relationNodeUp)) {
            return static::notice([
                'REAL_NAME' => $recommenderActual['REAL_NAME'],
                'userId' => $recommenderActual['ID'],
            ]);
        }

        return static::notice(Yii::t('ctx', 'fillSponsorUpline'), 400);
    }

    /**
     * 复消会员信息查询
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionUserBaseInfo()
    {
        $userName = \Yii::$app->request->get('userName');
        $userId = Info::getUserIdByUserName($userName);
        if($userId){
            $allAddress = ReceiveAddress::findAllAsArray('USER_ID=:USER_ID', [':USER_ID'=>$userId]);
            if($allAddress) {
                foreach ($allAddress as $key => $row) {
                    $allAddress[$key]['PROVINCE_NAME'] = Region::getCnName($row['PROVINCE']);
                    $allAddress[$key]['CITY_NAME'] = Region::getCnName($row['CITY']);
                    $allAddress[$key]['COUNTY_NAME'] = Region::getCnName($row['COUNTY']);
                }
            }

            $userInfo = Info::baseInfoWithNet($userId);
//            $decLevelConfig = Cache::getDecLevelConfig();
//            $empLevelConfig = Cache::getEmpLevelConfig();

            $arr = [
                'REAL_NAME'=>$userInfo['REAL_NAME'],
//                'DEC_LEVEL_NAME' => $decLevelConfig[$userInfo['DEC_LV']]['LEVEL_NAME'],
//                'EMP_LEVEL_NAME'=>$empLevelConfig[$userInfo['EMP_LV']]['LEVEL_NAME'],
//                'REC_UID'=>$userInfo['REC_USER_NAME'].'('.$userInfo['REC_REAL_NAME'].')',
//                'CON_UID'=>$userInfo['CON_USER_NAME'].'('.$userInfo['CON_REAL_NAME'].')',
                'allAddress'=>$allAddress
            ];
            return static::notice($arr);
        }else{
            return static::notice(Yii::t('app', 'repeatSalesMemberNoDoesNotExist'), 400);
        }
    }

    /**
     * 会员资料
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionBaInfo()
    {
        $data['userInfo'] = BaUser::getEnCodeInfo(\Yii::$app->user->id);
        $data['userInfo']['NATION'] = $data['userInfo']['NATION_ID'];
        // 推荐人
        $baUserInfo = BaUserInfo::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => \Yii::$app->user->id]);
        $sponsor = User::findOneAsArray('ID=:USER_ID', [':USER_ID' => $baUserInfo['REC_UID']]);
        $data['userInfo']['SponsorCode'] = $sponsor['USER_NAME'];
        $data['userInfo']['SponsorName'] = $sponsor['REAL_NAME'];

        return static::notice($data);
    }

    /**
     * 编辑会员资料
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionBaEdit()
    {
        if(\Yii::$app->request->isPost)
        {
            $form = new BaUserForm();
            $post = \Yii::$app->request->post();
            $form->scenario = 'modifyProfile';
            if ($form->load($post, '') && $result = $form->modifyProfile()){
                return static::notice(Yii::t('app', 'personalDataModifiedSuccessfully'), 400);
            } else {
                return static::notice(Form::formatErrorsForApi($form->getErrors()), 400);
            }
        }

        return static::notice(Yii::t('app', 'illegalRequest'), 400);
    }

    /**
     * 修改登录密码
     */
    public function actionBaPassword(){
        if(\Yii::$app->request->isPost) {
            $form = new BaUserForm();
            $form->scenario = 'modifyPassword';
            $post = \Yii::$app->request->post();
            if($form->load($post, '') && $result = $form->modifyPassword()){
                return static::notice(Yii::t('app', 'passwordModifiedSuccessfully'), 400);
            } else {
                return static::notice(Form::formatErrorsForApi($form->getErrors()), 400);
            }
        }
        return static::notice(Yii::t('app', 'illegalRequest'), 400);
    }

    /**
     * 修改支付密码
     */
    public function actionBaPayPassword(){
        if(\Yii::$app->request->isPost){
            $form = new BaUserForm();
            $form->scenario = 'modifyPasswordPay';
            $post = \Yii::$app->request->post();
            $form->userId = \Yii::$app->user->id;
            if($form->load($post, '') && $result = $form->modifyPasswordPay()){
                return static::notice(Yii::t('app', 'passwordModifiedSuccessfully'), 400);
            } else {
                return static::notice(Form::formatErrorsForApi($form->getErrors()), 400);
            }
        }
        return static::notice(Yii::t('app', 'illegalRequest'), 400);
    }

    /**
     * BA报单管理
     */
    public function actionBaDec() {
        // 生成随机码 , 初始化redis
        $userName = Info::generateWebUserName('NG',9);
        $redis = \Yii::$app->redis;
        $post = \Yii::$app->request->post();

        if (\Yii::$app->request->isPost) {
            // 根据支付方式区分逻辑
            $payMethod = \Yii::$app->request->post('payType', '');

            if ($payMethod === 'pay_stack') {
                $formModel = new BaApproachDeclarationLoopForm();
            } else {
                unset($post['payType']);
                $formModel = new BaDeclarationLoopForm();
            }

            $formModel->scenario = 'userDec';

            $post['province'] = $post['province'] ? :1;
            $post['city'] = $post['city'] ? :1;
            $post['county'] = $post['county'] ? :1;
//            $post['conUserName'] = trim($post['conUserName']);
            $post['recUserName'] = trim($post['recUserName']);
            $post['cityName'] = trim($post['cityName']);
            $post['lgaName'] = trim($post['lgaName']);

            // 针对于会员编号的判断
            $insertUserName = strtoupper($post['insertUserName']);
            $getRedisUserName = $redis->get('key_' . $insertUserName);
            if (!$getRedisUserName){
                return static::notice(Yii::t('app', 'memberNumberExpired'), 400);
            }
            if ($insertUserName != $getRedisUserName){
                return static::notice(Yii::t('app', 'memberNumberDoesNotConformTo'), 400);
            }

            $post['insertUserName'] = $insertUserName;
            $post['type'] = BaDeclarationForm::TYPE_ZC;
            $allData['data'][] = $post;
            if ($formModel->load($allData, '') && $result = $formModel->add()) {
                return static::notice($result); // 报单成功
            } else {
                return static::notice(Form::formatErrorsForApi($formModel->getErrors()),400);
            }
        }

        // 只查询普通商品
        $allGoods = ShopGoods::find()->where("ID='375895243322691584'")->orderBy('SORT ASC')->asArray()->all();
        if (!$userName) {
            return static::notice(Yii::t('app', 'failedToGenerateMemberNumber'), 400);
        }
        //随机码保存在redis中方便进行比对
        $redis->setex('key_'.$userName , 3600 , $userName);
        // 会员账户
        $userBalance = [
            'cash' => 0,
//            'tourism_points' => 0,
//            'garage_points' => 0,
//            'villa_points' => 0,
        ];
        $userCash = UserWallet::findOneAsArray(['USER_ID' => \Yii::$app->user->id]);
        if ($userCash) {
            $userBalance['cash'] = $userCash['CASH'];
        }

        return static::notice([
            'allGoods' => $allGoods,
            'userName' => $userName,
            'payList' => ShopGoods::payTypes(),
            'sellType' => ShopGoods::getCategoryType(),
            'categoryType' => ShopGoods::getCategoryType()[0]['id'],
            'userBalance' => $userBalance,
        ]);
    }

    /**
     * BA会员信息
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionBaUserInfo()
    {
        $userName = \Yii::$app->request->get('userName');
        $userId = Info::getBaUserIdByUserName($userName);
        $userInfo['REAL_NAME'] = '';
        $user = BaUser::findOneAsArray('ID=:ID', [':ID' => $userId], 'REAL_NAME');
        $uInfo = BaUserInfo::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $userId], 'REC_UID');
        if($user){
            $rec_user = UserInfo::findOneAsArray('USER_ID=:USER_ID',[':USER_ID' => $uInfo['REC_UID']], 'USER_ID, USER_NAME');
            $userInfo['REAL_NAME'] = $user['REAL_NAME'];
            $userInfo['REC_USER_ID'] = $rec_user['USER_ID'];
            $userInfo['REC_USER_NAME'] = $rec_user['USER_NAME'];
            return static::notice($userInfo);
        }else{
            return static::notice(Yii::t('app', 'memberNumberDoesNotExist'), 400);
        }
    }
}
