<?php

namespace common\models;

use yii\web\IdentityInterface;

/**
 * User model
 *
 * @property integer $id
 * @property string $username
 * @property string $password_hash
 * @property string $password_reset_token
 * @property string $email
 * @property string $auth_key
 * @property integer $status
 * @property integer $created_at
 * @property integer $updated_at
 * @property string $password write-only password
 * @property boolean $confiance
 */
class User extends ActiveRecord implements IdentityInterface {

    const STATUS_DELETED = 0;
    const STATUS_ACTIVE = 10;
    const STATUS_BOULANGER = 11;
    const STATUS_ADMIN = 13;

    const ID_USER_SYSTEM = 0 ;
    
    var $password_old;
    var $password_new;
    var $password_new_confirm;

    /**
     * @inheritdoc
     */
    public static function tableName() {
        return '{{%user}}';
    }

    /**
     * @inheritdoc
     */
    public function behaviors() {
        return [
            TimestampBehavior::className(),
        ];
    }

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            ['confiance', 'default', 'value' => 1],
            [['no_mail', 'mail_prod_lundi', 'mail_prod_mardi', 'mail_prod_mercredi', 'mail_prod_jeudi', 'mail_prod_vendredi', 'mail_prod_samedi', 'mail_prod_dimanche'], 'boolean'],
            [['nom', 'prenom', 'telephone', 'adresse'], 'string'],
            [['nom', 'prenom'], 'required', 'message' => 'Ce champs ne peut être vide'],
            ['email', 'email', 'message' => 'Cette adresse email n\'est pas valide'],
            ['email', 'verifyEmail'],
            ['status', 'default', 'value' => self::STATUS_ACTIVE],
            ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED, self::STATUS_ADMIN, self::STATUS_BOULANGER]],
            ['password_old', 'verifyPasswordOld'],
            ['password_new', 'verifyPasswordNew'],
            ['password_new_confirm', 'verifyPasswordNewConfirm'],
            [['date_derniere_connexion', 'password_old', 'password_new', 'password_new_confirm', 'password_hash'], 'safe'],
        ];
    }

    public function verifyPasswordOld($attribute, $params) {
        if (strlen($this->password_old)) {
            if (!$this->validatePassword($this->password_old)) {
                $this->addError($attribute, 'Mot de passe invalide.');
            }
        }

        if (!strlen($this->password_old) && (strlen($this->password_new) || strlen($this->password_new_confirm))) {
            $this->addError($attribute, 'Ce champs ne peut être vide');
        }

        if (!strlen($this->password_new) && (strlen($this->password_old) || strlen($this->password_new_confirm))) {
            $this->addError('password_new', 'Ce champs ne peut être vide');
        }

        if (!strlen($this->password_new_confirm) && (strlen($this->password_old) || strlen($this->password_new))) {
            $this->addError('password_new_confirm', 'Ce champs ne peut être vide');
        }
    }

    public function verifyPasswordNew($attribute, $params) {
        if (strlen($this->password_new) < 6) {
            $this->addError($attribute, 'Votre mot de passe doit comporter au moins 6 caractères.');
        }
    }

    public function verifyPasswordNewConfirm($attribute, $params) {
        if ($this->password_new != $this->password_new_confirm) {
            $this->addError($attribute, 'Les deux mots de passe doivent être identiques');
        }
    }

    public function verifyEmail($attribute, $params) {
        $user = User::find()->where("email LIKE :email AND id != :id")->params(array(':email' => '%' . $this->email . '%', ':id' => $this->id))->one();

        if ($user)
            $this->addError($attribute, 'Cette adresse email est déjà utilisée par un autre utilisateur ');
    }

    public function getUserEtablissement() {
        return $this->hasMany(UserEtablissement::className(), ['id_user' => 'id']);
    }

    /**
     * @inheritdoc
     */
    public static function findIdentity($id) {
        return static::findOne(['id' => $id/* , 'status' => self::STATUS_ACTIVE */]);
    }

    /**
     * @inheritdoc
     */
    public static function findIdentityByAccessToken($token, $type = null) {
        throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
    }

    /**
     * Finds user by username
     *
     * @param string $username
     * @return static|null
     */
    public static function findByUsername($username) {
        return static::findOne(['username' => $username/* , 'status' => self::STATUS_ACTIVE */]);
    }

    public static function findByEmail($email) {
        return static::findOne(['email' => $email /* , 'status' => self::STATUS_ACTIVE */]);
    }

    /**
     * Finds user by password reset token
     *
     * @param string $token password reset token
     * @return static|null
     */
    public static function findByPasswordResetToken($token) {
        if (!static::isPasswordResetTokenValid($token)) {
            return null;
        }

        return static::findOne([
                    'password_reset_token' => $token,
        ]);
    }

    public static function findBy($params = []) {
        if (!isset($params['id_etablissement']))
            $params['id_etablissement'] = Yii::$app->user->identity->id_etablissement;        
        
        $query = (new \yii\db\Query())
                ->select(['user.id AS user_id', 'user.prenom', 'user.nom', 'user.telephone', 'user.email', 'user.created_at', 'user.date_derniere_connexion', 'user_etablissement.*'])
                ->from('user');
        
        $actif = (isset($params['inactifs']) && $params['inactifs']) ? 0 : 1 ;
        $query->innerJoin('user_etablissement','user.id = user_etablissement.id_user AND user_etablissement.actif = '.$actif.' AND user_etablissement.id_etablissement = :id_etablissement', [':id_etablissement' => $params['id_etablissement']]) ;
        
        if(isset($params['id_point_vente']) && $params['id_point_vente']) {
            $point_vente = PointVente::findOne(['id' => $params['id_point_vente']]) ;
            if($point_vente->acces_restreint) {
                $query->innerJoin('point_vente_user','user.id = point_vente_user.id_user AND point_vente_user.id_point_vente = :id_point_vente',[':id_point_vente' => $params['id_point_vente']]) ;
            }
            else {
                $query->innerJoin(
                    'commande', 
                    'user.id = commande.id_user AND commande.id_point_vente = :id_point_vente',
                    [':id_point_vente' => $params['id_point_vente']]
                )->groupBy('user.id') ;
            }
        }
        
        if(isset($params['inactifs']) && $params['inactifs']) {
            $query->innerJoin(
                'commande', 
                'user.id = commande.id_user'
            )
            ->groupBy('user.id');
        }
        
        if (isset($params['nom']))
            $query->andFilterWhere(['like', 'nom', $params['nom']]);
        if (isset($params['prenom']))
            $query->andFilterWhere(['like', 'prenom', $params['prenom']]);
        if (isset($params['email']))
            $query->andFilterWhere(['like', 'email', $params['email']]);
        if (isset($params['telephone']))
            $query->andFilterWhere(['like', 'telephone', $params['telephone']]);

        return $query;
    }

    /**
     * Finds out if password reset token is valid
     *
     * @param string $token password reset token
     * @return boolean
     */
    public static function isPasswordResetTokenValid($token) {
        if (empty($token)) {
            return false;
        }
        $expire = Yii::$app->params['user.passwordResetTokenExpire'];
        $parts = explode('_', $token);
        $timestamp = (int) end($parts);
        return $timestamp + $expire >= time();
    }

    /**
     * @inheritdoc
     */
    public function getId() {
        return $this->getPrimaryKey();
    }

    /**
     * @inheritdoc
     */
    public function getAuthKey() {
        return $this->auth_key;
    }

    /**
     * @inheritdoc
     */
    public function validateAuthKey($authKey) {
        return $this->getAuthKey() === $authKey;
    }

    /**
     * Validates password
     *
     * @param string $password password to validate
     * @return boolean if password provided is valid for current user
     */
    public function validatePassword($password) {
        return Yii::$app->security->validatePassword($password, $this->password_hash);
    }

    /**
     * Generates password hash from password and sets it to the model
     *
     * @param string $password
     */
    public function setPassword($password) {
        $this->password_hash = Yii::$app->security->generatePasswordHash($password);
    }

    /**
     * Generates "remember me" authentication key
     */
    public function generateAuthKey() {
        $this->auth_key = Yii::$app->security->generateRandomString();
    }

    /**
     * Generates new password reset token
     */
    public function generatePasswordResetToken() {
        $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
    }

    /**
     * Removes password reset token
     */
    public function removePasswordResetToken() {
        $this->password_reset_token = null;
    }

    public function attributeLabels() {
        return [
            'id' => 'ID',
            'username' => 'Identifiant',
            'password' => 'Mot de passe',
            'rememberMe' => 'Se souvenir de moi',
            'confiance' => 'De confiance',
            'no_mail' => 'Ne pas recevoir d\'email de la part du Chat des Noisettes',
            'mail_prod_lundi' => 'Lundi',
            'mail_prod_mardi' => 'Mardi',
            'mail_prod_mercredi' => 'Mercredi',
            'mail_prod_jeudi' => 'Jeudi',
            'mail_prod_vendredi' => 'Vendredi',
            'mail_prod_samedi' => 'Samedi',
            'mail_prod_dimanche' => 'Dimanche',
            'password_old' => 'Ancien mot de passe',
            'password_new' => 'Nouveau mot de passe',
            'password_new_confirm' => 'Confirmation du nouveau mot de passe',
            'prix_libre' => 'Prix libre',
        ];
    }

    public function isBoulanger() {
        return ($this->status == User::STATUS_ADMIN || $this->status == User::STATUS_BOULANGER) && $this->id_etablissement;
    }

    public function getNomMagasin() {
        $etablissement = Etablissement::findOne($this->id_etablissement);
        return $etablissement->nom;
    }

    public function getEtablissementsFavoris() {
        $etabs = (new \yii\db\Query())
                ->select('*')
                ->from(['user_etablissement', 'etablissement'])
                ->where('user_etablissement.id_etablissement = etablissement.id')
                ->andWhere(['user_etablissement.id_user' => $this->id])
                ->andWhere(['user_etablissement.actif' => 1])
                ->all();

        return $etabs;
    }

    public function etatPaiementEtablissement() {
        $etablissement = Etablissement::findOne($this->id_etablissement);

        if ($etablissement) {
            return $etablissement->etatPaiement();
        }
    }

    public function periodeEssai() {
        $etablissement = Etablissement::findOne($this->id_etablissement);

        if ($etablissement) {
            $date_limite = strtotime($etablissement->date_creation) + 30 * 24 * 60 * 60;
            $date = time();

            if ($date < $date_limite) {
                $date = $date_limite - $date;
                return (int) ($date / (24 * 60 * 60));
            } else {
                return 0;
            }
        }
    }

    public function getCredit($id_etablissement) {
        $user_etablissement = UserEtablissement::find()
                ->where([
                    'id_user' => $this->id,
                    'id_etablissement' => $id_etablissement
                ])
                ->one();

        if ($user_etablissement) {
            return $user_etablissement->credit;
        }

        return 0;
    }

    public function updateDerniereConnexion() {
        $this->date_derniere_connexion = date('Y-m-d H:i:s');
        $this->save();
    }

}