<?php
namespace App\Model\Table;

use App\Model\Entity\User;
use Cake\Auth\DefaultPasswordHasher;
use Cake\Log\Log;
use Cake\Mailer\Email;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

/**
 * Users Model
 *
 * @property \Cake\ORM\Association\BelongsTo $Roles
 * @property \Cake\ORM\Association\HasMany $Log
 * @property \Cake\ORM\Association\BelongsToMany $Units
 */
class UsersTable extends Table
{

    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->table('users');
        $this->displayField('name');
        $this->primaryKey('id');

        $this->addBehavior('Timestamp');

        $this->belongsTo('Roles', [
            'foreignKey' => 'role_id',
            'joinType'   => 'INNER',
        ]);

        $this->hasMany('MedicalOpinionRequests', [
            'foreignKey' => 'professional_id',
        ]);

        $this->hasMany('MedicalOpinionAnswers', [
            'foreignKey' => 'professional_id',
        ]);

        $this->hasMany('Log', [
            'foreignKey' => 'user_id',
        ]);

        $this->hasMany('Professionals', [
            'foreignKey' => 'user_id',
        ]);

        $this->belongsToMany('Units', [
            'foreignKey'       => 'user_id',
            'targetForeignKey' => 'unit_id',
            'joinTable'        => 'units_users',
        ]);

        $this->belongsToMany('Privileges', [
            'foreignKey'       => 'user_id',
            'targetForeignKey' => 'privilege_id',
            'joinTable'        => 'units_users',
        ]);
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

        $validator
            ->requirePresence('name', 'create')
            ->notEmpty('name');

        $validator
            ->email('email')
            ->requirePresence('email', 'create')
            ->notEmpty('email');

        $validator
            ->requirePresence('password', 'create')
            ->notEmpty('password')
            ->add('password', 'minlength', [
                'rule'    => ['minLength', 6],
                'message' => 'A senha deve ter no mínimo 6 caracteres.',
            ]);

        $validator
            ->boolean('is_active')
            ->allowEmpty('is_active');

        //$validator
        //->requirePresence('username', 'create')
        //->notEmpty('username');

        return $validator;
    }

    public function validationPassword(Validator $validator)
    {
        //Log::write('debug', "validationPassword INIT");
        $validator
            ->add('old_password', 'custom', [
                'rule'    => function ($value, $context) {
                    $user = $this->get($context['data']['id']);
                    if ($user) {
                        if ((new DefaultPasswordHasher)->check($value, $user->password)) {
                            return true;
                        }
                    }
                    return false;
                },
                'message' => 'A senha atual fornecida está incorreta!',
            ])
            ->notEmpty('old_password');

        $validator
            ->add('password1', [
                'length' => [
                    'rule'    => ['minLength', 6],
                    'message' => 'A senha deve ter no mínimo 6 caracteres!',
                ],
            ])
            ->add('password1', [
                'match' => [
                    'rule'    => ['compareWith', 'password2'],
                    'message' => 'As senhas não estão iguais!',
                ],
            ])
            ->notEmpty('password1');
        $validator
            ->add('password2', [
                'length' => [
                    'rule'    => ['minLength', 6],
                    'message' => 'A senha deve ter no mínimo 6 caracteres!',
                ],
            ])
            ->add('password2', [
                'match' => [
                    'rule'    => ['compareWith', 'password1'],
                    'message' => 'As senhas não estão iguais!',
                ],
            ])
            ->notEmpty('password2');

        return $validator;
    }

    /**
     * Returns a rules checker object that will be used for validating
     * application integrity.
     *
     * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
     * @return \Cake\ORM\RulesChecker
     */
    public function buildRules(RulesChecker $rules)
    {
        //lembrar de descomentar a linha abaixo
        $rules->add($rules->isUnique(['email']));
        //$rules->add($rules->isUnique(['username']));
        $rules->add($rules->existsIn(['role_id'], 'Roles'));
        return $rules;
    }

    //envia a senha por email
    public function sendPassByEmail($user)
    {

        // Sample smtp configuration.
        Email::configTransport('gmail', [
            'host'      => 'ssl://smtp.gmail.com',
            'port'      => 465,
            'email'     => 'gustavo.carvalho@clicksoft.com.br',
            'password'  => 'clicksoft@123',
            'className' => 'Smtp',
        ]);

        $email = new Email(['from' => 'gustavo.carvalho@clicksoft.com.br', 'transport' => 'default']);

        Log::write('debug', 'email =' . $user['email']);
        Log::write('debug', 'email =' . $user['email']);
        Log::write('debug', 'unencrypted_password =' . $user['unencrypted_password']);

        $email->from(['gustavo.carvalho@clicksoft.com.br' => 'GH'])
            ->to($user['email'])
            ->subject('Sistema GH - Usuário e Senha')
            ->emailFormat('html')
            ->send(
                "<b>email</b>: " . $user['email']
                . "<br><b>Senha</b>: " . $user['unencrypted_password']
            );
    }

    //gera uma senha aleatoria
    public function randomPassword($length)
    {
        $chars    = "abcdefghijklmnopqrstuvwxyz0123456789";
        $password = substr(str_shuffle($chars), 0, $length);
        return $password;
    }
}
