<?php
namespace common\models\forms;

use common\components\Model;
use common\helpers\Cache;
use common\helpers\Date;
use common\helpers\Form;
use common\helpers\LoggerTool;
use common\libs\logging\operate\AdminOperate;
use common\models\Countries;
use common\models\CurrencyConversions;
use common\models\ShopGoods;
use common\models\ShopGoodsNature;
use yii\base\Exception;

/**
 * Login form
 */
class ShopGoodsForm extends Model
{
    public $selectedIds;
    public $id;
    public $goodsName;
    public $type;
    public $sellDiscount;
    public $giftType;
    public $sellType;
    public $pvSplit;
    public $goodsNo;
    public $unit;
    public $cover;
    public $sellPriceStandard;
    public $pricePv;
    public $storeNums;
    public $content;
    public $sort;
    public $status;
    public $categoryType;
    public $nature;
    public $autoMaintenance = 0;

    private $_model;

    public function init() {
        parent::init();
        $this->adminOperateLogger = new AdminOperate([
            'fetchClass' => ShopGoods::class,
        ]);
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['id','sellDiscount','giftType','sellType','goodsNo', 'goodsName', 'unit', 'pricePv', 'storeNums', 'content', 'sort','status','cover'], 'trim'],
            [['goodsName','sellDiscount','giftType','goodsNo', 'storeNums','pricePv', 'sort','status', 'categoryType', 'sellPriceStandard', 'nature'], 'required'],
            [['id'], 'required', 'on'=>'edit'],
            [['id'], 'exist', 'targetClass'=>ShopGoods::class, 'targetAttribute'=>'ID'],
            [['sellPrice','marketPrice','pricePv', 'sellPriceStandard'], 'price'],
            [['id'], 'initModel'],
            [['selectedIds'], 'isSelected'],
            [['sort'], 'isSort'],
            [['sellDiscount'], 'isDiscount'],
            [['sellPriceStandard'], 'isPrice'],
        ];
    }

    public function attributeLabels()
    {
        return [
            'selectedIds' => 'ID',
            'id' => 'Product ID',
            'goodsName' => 'Product Name', // 商品名称
            'sellDiscount' => 'Discount Rate', // 会员折扣
            'giftType' => 'Product Type', // 商品类型
            'categoryType' => 'Product Category', // 商品分类
            'sellType' => 'SellType', // 出售方式
            'pvSplit' => 'PV Split', // pv分期
            'goodsNo' => 'Product Code', // 产品编号
            'unit' => 'Unit', // 单位
            'cover' => 'Cover',// 封面
            'sellPriceStandard' => 'US price',
            'pricePv' => 'BV', // 销售PV
            'storeNums' => 'Inventory', // 库存
            'content' => 'Content',
            'listOrder' => 'Order',// 排序
            'autoMaintenance' => 'Auto Maintenance',
        ];
    }

    /**
     * 指定场景
     * @return array
     */
    public function scenarios()
    {
        $parentScenarios =  parent::scenarios();
        $customScenarios = [
            'add' => ['goodsName','sellDiscount','giftType', 'sellType','goodsNo','unit','pricePv','storeNums', 'content','sort','cover', 'categoryType', 'sellPriceStandard', 'taxRate', 'taxAmount','pvSplit', 'nature', 'autoMaintenance'],
            'edit' => ['id','goodsName','sellDiscount','giftType', 'sellType','goodsNo','unit','pricePv', 'storeNums', 'content','sort','cover', 'categoryType', 'sellPriceStandard', 'nature','pvSplit', 'autoMaintenance'],
            'changeStatus' => ['selectedIds', 'status'],
        ];
        return array_merge($parentScenarios, $customScenarios);
    }

    /**
     * 初始化model
     * @param $attributes
     */
    public function initModel($attributes) {
        $this->_model = ShopGoods::findOne(['ID' => $this->id]);
        if (!$this->_model) {
            $this->addError($attributes, \Yii::t('ctx', 'dataDoesNotExists')); // 数据不存在
        }
    }

    /**
     * 前置数据填充和校验.
     * @return bool
     */
    public function beforeValidate()
    {
        if($this->categoryType){
            // 处理sellType
            $categoryType = array_column(ShopGoods::CATEGORY_TYPE, NULL, 'id');
            $sellType = $categoryType[$this->categoryType]['sell_type'] ?? [];
            if (!$sellType) {
                $this->addError('add', \Yii::t('ctx', 'shopBuyActionErrorNotice'));
            } else {
                foreach ($sellType as $item) {
                    if (!in_array($item['id'], array_keys(ShopGoods::getSaleType()))) {
                        $this->addError('add', \Yii::t('ctx', 'shopBuyActionErrorNotice'));
                        break;
                    }
                }
                // 购买方式格式化为','分割的方式
                $this->sellType = implode(',', array_column($sellType, 'id'));
                // 如果是普通商品,有PV，旅游、名车、豪宅商品没有PV
                if ($this->categoryType != 1) {
                    $this->pricePv = 0;
                }
            }
        }

        return parent::beforeValidate();
    }

    /**
     * 批量数据
     * @param $attributes
     */
    public function isSelected($attributes) {
        if (!$this->selectedIds) {
            $this->addError($attributes, \Yii::t('ctx', 'aPieceMustBeSelected')); // 必须选择一条数据
        }
        if (!is_array($this->selectedIds)) {
            $this->selectedIds = [$this->selectedIds];
        }
    }
    /**
     * 排序需大于等于1
     * @param $attributes
     */
    public function isSort($attributes) {
        if ($this->sort < 1) {
            $this->addError($attributes, \Yii::t('ctx', 'shopSortMoreThanOne'));
        }
    }

    // 折扣为0-1
    public function isDiscount($attributes) {
        if ($this->sellDiscount < 0 || $this->sellDiscount > 1 || !is_numeric($this->sellDiscount)) {
            $this->addError($attributes, \Yii::t('ctx', 'shopDiscountZeroBetweenOne'));
        }
    }

    public function isPrice($attributes)
    {
        if ($this->sellPriceStandard <= 0) {
            $this->addError($attributes, \Yii::t('ctx', 'sellPriceStandardMustGreaterThanZero'));
        }
    }

    /**
     * 添加
     * @return ShopGoods|null
     * @throws \yii\db\Exception
     */
    public function add() {
        if (!$this->validate()) {
            return null;
        }

        $transaction = \Yii::$app->db->beginTransaction();
        try {
            // 添加商品
            $shopGoods = new ShopGoods();
            $shopGoods->GOODS_NAME = $this->goodsName;
            $shopGoods->SELL_DISCOUNT = $this->sellDiscount;
            $shopGoods->GIFT_TYPE = implode(',',$this->giftType);
            $shopGoods->SELL_TYPE = $this->sellType;
            $shopGoods->PV_SPLIT = $this->pvSplit;
            $shopGoods->GOODS_NO = $this->goodsNo;
            $shopGoods->UNIT = $this->unit ?: '个';
            $shopGoods->COVER = $this->cover ?: '';
            $shopGoods->SELL_PRICE_STANDARD = $this->sellPriceStandard;
            $shopGoods->PRICE_PV = $this->pricePv;
            $shopGoods->CONTENT = $this->content;
            $shopGoods->STORE_NUMS = $this->storeNums;
            $shopGoods->SORT = $this->sort;
            $shopGoods->CATE_ID = '1';
            $shopGoods->CREATED_AT = Date::nowTime();
            $shopGoods->CATEGORY_TYPE = $this->categoryType;
            $shopGoods->AUTO_MAINTENANCE = $this->autoMaintenance ?? 0;
            if (!$shopGoods->save()) {
                throw new Exception(Form::formatErrorsForApi($shopGoods->getErrors()));
            }

            // 商品属性
            foreach ($this->nature as $item) {
                // 国家
                $country = Countries::getById($item['ID']);

                $shopGoodsNature = new ShopGoodsNature();
                $shopGoodsNature->GOODS_ID = $shopGoods->ID;
                $shopGoodsNature->COUNTRY_ID = $item['ID'];
                $shopGoodsNature->LOCAL_CURRENCY_ID = $country['LOCAL_CURRENCY_ID'];
                $shopGoodsNature->SELL_PRICE = round($item['sellPrice']);
                $shopGoodsNature->MARKET_PRICE = round($item['marketPrice']);
                $shopGoodsNature->TAX_RATE = $item['taxRate'];
                if (!$shopGoodsNature->save()) {
                    $transaction->rollBack();
                    throw new Exception(Form::formatErrorsForApi($shopGoodsNature->getErrors()));
                }
            }

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->addError('add', $e->getMessage());
            return null;
        }
        return $shopGoods;
    }

    /**
     * 编辑商品
     * @return null
     * @throws \yii\db\Exception
     */
    public function edit() {
        if (!$this->validate()) {
            return null;
        }

        $transaction = \Yii::$app->db->beginTransaction();
        try {
            $model = $this->_model;
            $model->GOODS_NAME = $this->goodsName;
            $model->TYPE = 0;
            $model->SELL_DISCOUNT = $this->sellDiscount;
            $model->GIFT_TYPE = implode(',',$this->giftType);
            $model->SELL_TYPE = $this->sellType;
            $model->PV_SPLIT = $this->pvSplit;
            $model->GOODS_NO = $this->goodsNo;
            $model->UNIT = $this->unit ?: '个';
            $model->COVER = $this->cover ?: '';
            $model->SELL_PRICE_STANDARD = $this->sellPriceStandard;
            $model->PRICE_PV = $this->pricePv;
            $model->CONTENT = $this->content;
            $model->STORE_NUMS = $this->storeNums;
            $model->SORT = $this->sort;
            $model->UPDATED_AT = Date::nowTime();
            $model->CATEGORY_TYPE = $this->categoryType;
            $model->AUTO_MAINTENANCE = $this->autoMaintenance ?? 0;
            if (!$model->save()) {
                throw new Exception(Form::formatErrorsForApi($model->getErrors()));
            }

            ShopGoodsNature::deleteAll(['GOODS_ID' => $model->ID]);

            // 商品属性
            foreach ($this->nature as $item) {
                $country = Countries::getById($item['ID']);

                $shopGoodsNature = new ShopGoodsNature();
                $shopGoodsNature->GOODS_ID = $model->ID;
                $shopGoodsNature->COUNTRY_ID = $item['ID'];
                $shopGoodsNature->LOCAL_CURRENCY_ID = $country['LOCAL_CURRENCY_ID'];
                $shopGoodsNature->SELL_PRICE = round($item['sellPrice']);
                $shopGoodsNature->MARKET_PRICE = round($item['marketPrice']);
                $shopGoodsNature->TAX_RATE = $item['taxRate'];
                if (!$shopGoodsNature->save()) {
                    $transaction->rollBack();
                    throw new Exception(Form::formatErrorsForApi($shopGoodsNature->getErrors()));
                }
            }

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->addError('edit', $e->getMessage());
            return null;
        }
        return $model;
    }

    /**
     * 上下架
     * @return null|static
     * @throws \yii\db\Exception
     */
    public function changeStatus() {
        if (!$this->validate()) {
            return null;
        }
        $db = \Yii::$app->db;
        $transaction = $db->beginTransaction();
        try {
            foreach ($this->selectedIds as $select) {
                $oneGoods = ShopGoods::findOne(['ID' => $select]);
                //判断状态
                if (($msg = ShopGoods::chkAuditStatus($oneGoods->STATUS, $this->status)) != '') {
                    throw new Exception($msg);
                }
                $oneGoods->STATUS = $this->status;
                $oneGoods->UPDATED_AT = Date::nowTime();
                if (!$oneGoods->save()) {
                    throw new Exception(Form::formatErrorsForApi($oneGoods->getErrors()));
                }
            }
            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->addError('changeStatus', $e->getMessage());
            return null;
        }
        return ['status' => $this->status];
    }

    /**
     * 异步更新商品属性表
     * @return bool
     */
    public function updateAsync($id){
        // 汇率配置
        $currencyConversions = CurrencyConversions::findOne(['ID' => $id]);
        // 商品属性
        $shopGoodsNature = ShopGoodsNature::findAll(['LOCAL_CURRENCY_ID' => $currencyConversions->TO_CURRENCY_ID]);

        $transaction = \Yii::$app->db->beginTransaction();
        try {
            foreach ($shopGoodsNature as $goodsNature) {
                // 商品
                $shopGoods = ShopGoods::findOne(['ID' => $goodsNature->GOODS_ID]);
                // 刷新销售价格、市场价格
                $goodsNature->SELL_PRICE = $shopGoods->SELL_PRICE_STANDARD * $currencyConversions->PRODUCT_RATE;
                $goodsNature->MARKET_PRICE = $shopGoods->SELL_PRICE_STANDARD * $currencyConversions->PRODUCT_RATE * 1.2;
                if (!$goodsNature->save()) {
                    $transaction->rollBack();
                    throw new Exception(Form::formatErrorsForApi($goodsNature->getErrors()));
                }
            }

            echo "商品更新成功！" . PHP_EOL;

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->addError('update', $e->getMessage());
            return false;
        }
        return true;
    }
}
