<?php
    namespace common\modules\comment\models;

    use common\models\Currency;
    use common\models\File;
    use common\models\Project;
    use common\models\User;
    use yii\db\ActiveQuery;
    use yii\db\ActiveRecord;
    use yii\web\UploadedFile;

    /**
     * Class Comment
     * @property bool     $guestComment
     * @property integer  $comment_id
     * @property string   $text
     * @property int      $user_id
     * @property int      $status
     * @property string   $date_add
     * @property string   $date_update
     * @property string   $date_delete
     * @property string   $model
     * @property int      $model_id
     * @property string   $files
     * @property float    $budget_from
     * @property float    $budget_to
     * @property int      $term_from
     * @property int      $term_to
     * @property int      $state
     * @property Currency $currency
     * @property Project  $project
     * @package common\modules\comment\models
     */
    class CommentProject extends \yii\db\ActiveRecord
        implements \common\modules\comment\interfaces\CommentInterface
    {

        const STATUS_HIDDEN = 0;
        const STATUS_DELETED = 2;
        const STATUS_ACTIVE = 1;
        const STATUS_PERSONAL = 3;
        const STATUS_ANONYMOUS = 4;

        const STATE_NEW = 1;
        const STATE_CANDIDATE = 2;
        const STATE_PERFORMER = 3;
        const STATE_DENY = 4;
        const STATE_TRASH = 5;

        const SCENARIO_USER = 'user';
        const SCENARIO_GUEST = 'guest';
        const SCENARIO_STATE = 'state';
        const SCENARIO_OWNER = 'owner';

        /**
         * @var bool
         */
        public $guestComment = false;

        public $file;

        public function rules()
        {
            return [
                [
                    [
                        'text',
                        'budget_from',
                        'budget_to',
                        'term_from',
                        'term_to',
                        'budget_currency',
                    ],
                    'required',
                ],
                [
                    [
                        'budget_currency',
                    ],
                    'integer',
                ],
                [
                    [
                        'budget_from',
                        'budget_to',
                        'term_from',
                        'term_to',
                    ],
                    'integer',
                    'min' => 0,
                ],
                [
                    [
                        'budget_currency',
                    ],
                    'default',
                    'value' => 3,
                ],
                [
                    [ 'budget_currency' ],
                    'exist',
                    'targetClass'     => Currency::className(),
                    'targetAttribute' => 'currency_id',
                ],
                [
                    [
                        'files',
                    ],
                    'string',
                ],
                [
                    [
                        'file',
                    ],
                    'safe',
                ],
                [
                    [ 'status' ],
                    'default',
                    'value' => 1,
                ],
                [
                    [ 'state' ],
                    'integer',
                    'max' => 4,
                    'min' => 1,
                    'on'  => self::SCENARIO_STATE,
                ],
                [
                    [ 'state' ],
                    'required',
                    'on' => self::SCENARIO_STATE,
                ],
                [
                    [ 'state' ],
                    'required',
                    'on' => self::SCENARIO_OWNER,
                ],
                [
                    [ 'state' ],
                    'in',
                    'range' => [
                        1,
                        5,
                    ],
                    'on'    => self::SCENARIO_OWNER,
                ],
            ];
        }

        public function scenarios()
        {
            return [
                self::SCENARIO_USER  => [
                    'text',
                    'budget_from',
                    'budget_to',
                    'term_from',
                    'term_to',
                    'file',
                ],
                self::SCENARIO_GUEST => [

                ],
                self::SCENARIO_STATE => [
                    'state',
                ],
                self::SCENARIO_OWNER => [
                    'state',
                ],
            ];
        }

        /**
         * @inheritdoc
         */
        public function behaviors()
        {
            return [
                [
                    'class'              => \yii\behaviors\TimestampBehavior::className(),
                    'createdAtAttribute' => 'date_add',
                    'updatedAtAttribute' => 'date_update',
                    'value'              => new \yii\db\Expression('NOW()'),
                ],
            ];
        }

        public static function tableName()
        {
            return '{{%comment_project}}';
        }

        /**
         * @inheritdoc
         */
        public function attributeLabels()
        {
            return [
                'text'        => \Yii::t('app', 'Текст ответа'),
                'budget_from' => \Yii::t('app', 'от'),
                'budget_to'   => \Yii::t('app', 'до'),
                'term_from'   => \Yii::t('app', 'от'),
                'term_to'     => \Yii::t('app', 'до'),
            ];
        }

        public function getGuestComment()
        {
            return $this->guestComment;
        }

        //        public function setGuestComment($value)
        //        {
        //            $this->guestComment = $value;
        //        }

        /**
         * @param string  $model
         * @param integer $model_id
         *
         * @return ActiveQuery
         */
        public function getComments($model, $model_id)
        {
            return $this->find()
                        ->where([
                            'comment_project.model'    => $model,
                            'comment_project.model_id' => $model_id,
                            'comment_project.status'   => 1,
                        ])
                        ->with('currency', 'user', 'user.userInfo', 'user.companyInfo', 'user.comments');
        }

        public function postComment()
        {
            if($this->checkCreate()) {
                if(!empty( \Yii::$app->request->post($this->formName())[ 'anonymous' ] )) {
                    $this->status = self::STATUS_ANONYMOUS;
                }
                $this->file = UploadedFile::getInstances($this, 'file');
                if(!empty( $this->file )) {
                    $file_id = [ ];
                    if(is_array($this->file)) {
                        foreach($this->file as $file) {
                            if($file instanceof UploadedFile) {
                                $file_model = new File();
                                $file_id[] = $file_model->saveFile($file);
                            }
                        }
                    } else {
                        if($this->file instanceof UploadedFile) {
                            $file_model = new File();
                            $file_id[] = $file_model->saveFile($this->file);
                        }
                    }
                    $this->files = json_encode($file_id);
                }
                if($this->insert()) {
                    $this->clearSafe();
                    return true;
                } else {
                    return false;
                }
            } else {
                $this->addError('comment_id', 'You can`t post comment here');
                return false;
            }
        }

        public function updateComment()
        {
            if($this->checkUpdate()) {
                if(empty( $this->comment_id )) {
                    $this->addError('comment_id', 'Comment ID not found');
                    return false;
                } else {
                    if($this->update()) {
                        $this->clearSafe();
                        return true;
                    } else {
                        return false;
                    }
                }
            } else {
                $this->addError('comment_id', 'You can`t update this post');
                return false;
            }
        }

        public function deleteComment()
        {
            if($this->checkDelete()) {
                if(empty( $this->comment_id )) {
                    $this->addError('comment_id', 'Comment ID not found');
                    return false;
                } else {
                    if($this->status == self::STATUS_DELETED) {
                        return false;
                    }
                    $this->status = self::STATUS_DELETED;
                    if($this->update()) {
                        $this->clearSafe();
                        return true;
                    } else {
                        return false;
                    }
                }
            } else {
                $this->addError('comment_id', 'You can`t delete this post');
                return false;
            }
        }

        public function checkCreate()
        {
            if($this->getGuestComment()) {
                return true;
            } else {
                return \Yii::$app->user->can(\common\modules\comment\Permissions::CREATE, [
                    'model'    => $this->model,
                    'model_id' => $this->model_id,
                ]);
            }
        }

        public function checkUpdate()
        {
            if($this->scenario == self::SCENARIO_GUEST) {
                return false;
            } else {
                return \Yii::$app->user->can(\common\modules\comment\Permissions::UPDATE, [
                    'model'    => $this->model,
                    'model_id' => $this->model_id,
                ]) || \Yii::$app->user->can(\common\modules\comment\Permissions::UPDATE_OWN, [
                    'model'    => $this->model,
                    'model_id' => $this->model_id,
                ]);
            }
        }

        public function checkDelete()
        {
            if($this->scenario == self::SCENARIO_GUEST) {
                return false;
            } else {
                return \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE, [
                    'model'    => $this->model,
                    'model_id' => $this->model_id,
                ]) || \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE_OWN, [
                    'model'    => $this->model,
                    'model_id' => $this->model_id,
                ]);
            }
        }

        protected function clearSafe($setNew = true)
        {
            $safe = $this->safeAttributes();
            $count = count($safe);
            $values = array_fill(0, $count, NULL);
            $result = array_combine($safe, $values);
            $this->setAttributes($result);
            $this->setIsNewRecord($setNew);
        }

        public function getAuthor()
        {
            //            if($this->user_id != NULL) {
            return $this->hasOne(\common\models\User::className(), [ 'id' => 'user_id' ]);
            //            } else {
            //                return ['firstname' => $this->user_name, 'email' => $this->user_email];
            //            }
        }

        /**
         * @return ActiveQuery
         */
        public function getCurrency()
        {
            return $this->hasOne(Currency::className(), [ 'currency_id' => 'budget_currency' ]);
        }

        /**
         * @return File[]
         */
        public function getFilesList()
        {
            $files = json_decode($this->files);
            if(!empty( $files )) {
                return File::findAll($files);
            } else {
                return [ ];
            }
        }

        /**
         * @return ActiveRecord
         * @throws \TypeError
         */
        public function getOwner()
        {
            $model = new $this->model();
            if($model instanceof ActiveRecord) {
                return $model->findOne($this->model_id);
            } else {
                throw new \TypeError('Model must extends Active Record Class');
            }
        }

        public function getProject()
        {
            return $this->hasOne(Project::className(), [ 'project_id' => 'model_id' ]);
        }

        /**
         * @return User
         */
        public function getUser()
        {
            return $this->hasOne(User::className(), [ 'id' => 'user_id' ]);
        }

        public function changeState()
        {
            if($this->isAttributeChanged('state')) {
                if($this->save()) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return true;
            }
        }

    }
