<?php

namespace Hwapx\Admin\Controller\Admin;

use \Bcrypt;
Use \Image;

use HwapX\Core\Library\DB\SQL\Mapper;
use HwapX\Core\Library\Template;
use HwapX\Core\Library\Validator;

class Dashboard extends Admin
{
    /*const MENU = array(
        'admin_dashboard' => array('icon' => 'fa-dashboard', 'label' => 'Dashboard'),
    );*/

    public function index($f3)
    {
        $db = $f3->get('db');

        $f3->set('page.title', 'Dashboard');
        $f3->set('page.description', 'Inicio');
        echo Template::instance()->render('hwapx/admin/admin/dashboard.html');
    }

    public static function login($f3)
    {
        $ip_hash      = md5($f3->get('SERVER.REMOTE_ADDR'));
        $max_attempts = $f3->get('app.auth.max_attempts');
        $block_time   = $f3->get('app.auth.block_time');
        $attempts     = 0;
        $time         = $f3->exists("auth.attempts.$ip_hash", $attempts);
        $time         = $time ? $time[0] + $time[1] : 0;

        $logger = new \Log(date('Y-m-d') . '_access.log');

        if ($attempts <= $max_attempts && $f3->get('VERB') == 'POST') {
            $db = $f3->get('db');

            $user = new \DB\SQL\Mapper($db, 'hwapx_user');
            $user->load(array('LOWER(email) = LOWER(?) AND active = 1', $f3->get('POST.email')));

            $hook = $f3->get('events.admin_login');
            $hookResult = null;

            if (!$user->dry() && 
                Bcrypt::instance()->verify($f3->get('POST.password'), $user->password) && 
                (!$hook || ($hookResult = $hook($f3, $user)) === true)) {
                $f3->clear("auth.attempts.$ip_hash");

                $user->last_login = date('Y-m-d H:i:s');
                $user->last_ip    = $f3->get('IP');
                $user->session_id = md5($f3->get('IP').$f3->get('AGENT'));
                $user->save();

                static::_user($user->id);

                //if($f3->get('POST.remember'))
                //  $f3->set('SESSION.admin', $f3->get('SESSION.admin'), $f3->get('app.auth.remember'));

                $logger->write('Usuário "' . $f3->get('POST.email') . '" autenticado com sucesso');

                $f3->reroute('@admin_dashboard');
            } else {
                $logger->write('Falha na autenticação com o usuário "' . $f3->get('POST.email') . '"');
                $f3->set("auth.attempts.$ip_hash", $attempts + 1, $block_time);

                if(is_string($hookResult)) {
                    $logger->write('Hook: ' . $hookResult);
                    flash('error', $hookResult);
                } else {
                    flash('error', 'Usuário ou senha inválidos.');
                }
                if($attempts > 0)
                flash('warning', 'O Acesso será bloqueado por ' . date('i:s', $block_time) . ' minutos após mais ' . ($max_attempts - $attempts) .
                    ' tentativas incorretas.');
            }
        }

        if ($attempts >= $max_attempts) {
            $logger->write('Acesso bloqueado durante ' . date('i:s', $block_time) . ' minutos por excesso de tentativas');
            flash('error', 'Numero de tentativas de login excedidas, o acesso será liberado após ' . date('i:s', $time - time()) . ' minutos.');
        }

        echo Template::instance()->render('hwapx/admin/admin/login.html');
    }

    public static function logout($f3)
    {
        $logger = new \Log(date('Y-m-d') . '_access.log');
        $logger->write('Usuário "' . $f3->get('SESSION.admin.email') . '" se desconectou explicitamente');
        $f3->clear('SESSION.admin');
        $f3->clear('COOKIE.admin');
        $f3->reroute('@admin_login');
    }

    public static function captcha($f3)
    {
        $img = new Image();
        $img->captcha('hwapx/admin/fonts/OpenSans-Regular.ttf',20,6,'SESSION.captcha');
        $img->render();
    }

    public static function reset($f3)
    {
        $logger = new \Log(date('Y-m-d') . '_user.log');

        $sent = false;

        if($f3->get('VERB') === 'POST') {
            if(strtoupper($f3->get('POST.captcha')) !== $f3->get('SESSION.captcha')) {
                flash('error', 'O código da imagem é inválido.');
                $f3->reroute('@admin_reset_password');
                return;
            }

            $mapper = new Mapper($f3->get('db'), 'hwapx_user');
            $mapper->load(array('email = LOWER(?)', $f3->get('POST.email')));

            if($mapper->dry()) {
                $logger->write('Solicitação de redefinição de senha para um usuário inexistente "' . $f3->get('POST.email') . '".');
                flash('error', 'Email não cadastrado ou inválido.');
            } else {
                $mapper->reset_token  = md5($mapper->email . time() . 'set' . rand() . $f3->get('app.password.salt'));
                $mapper->reset_expire = date('Y-m-d H:i:s', strtotime('+1 day'));
                $mapper->reset_requested_on = date('Y-m-d H:i:s');
                $mapper->save();

                $sent = SMTPMessage('reset_password', array('usuario' => $mapper->cast()), $mapper->email);

                if($sent) {
                    $logger->write('Solicitação de redefinição de senha para o usuário "' . $mapper->email . '".');
                    flash('success', 'Em breve você receberá um email com as instruções para redefinir sua senha.');
                    $f3->reroute('@admin_login');
                }
                
                flash('error', 'Falha ao enviar o email tente novamente mais tarde.');
            }
        }

        echo Template::instance()->render('hwapx/admin/admin/reset.html');
    }

    public static function setPassword($f3)
    {
        $logger = new \Log(date('Y-m-d') . '_user.log');

        $token = $f3->get('PARAMS.token');

        $mapper = new Mapper($f3->get('db'), 'hwapx_user');
        $mapper->load(array('reset_token = ? AND reset_expire >= CURRENT_TIMESTAMP AND COALESCE(reset_token, \'\') <> \'\'', $token));

        if($mapper->dry()) {
            $logger->write('Tentativa de acessar a página de redefinição de senha com um token inválido.');
            flash('error', 'Sua solicitação de redefinição de senha é inválida ou expirou, mas não se preocupe você pode solicitar uma nova aqui.');
            $f3->reroute('@admin_reset_password');
            return;
        }

        if($f3->get('VERB') === 'POST') {
            $validator = new Validator($f3->get('POST'));
            $validator->rule('equals', 'confirm', 'password')->label('Confirmação');
            $validator->rule('required', 'password')->label('Senha');
            $validator->rule('lengthMin', 'password', 6)->label('Senha');
            $validator->rule('password', 'password')->label('Senha');

            if($validator->validate()) {
                $password = $f3->get('POST.password');

                $mapper->reset_token  = null;
                $mapper->reset_expire = null;
                $mapper->last_reset   = date('Y-m-d H:i:s');
                $mapper->password     = Bcrypt::instance()->hash($password);
                $mapper->save();

                $logger->write('Usuário "' . $mapper->email . '" definiu uma nova senha.');
                flash('success', 'Sua senha foi redefinida com sucesso, você já pode acessar utilizando a nova senha.');
                $f3->reroute('@admin_login');
                return;
            }

            $logger->write('Usuário "' . $mapper->email . '" tentou definir uma nova senha muito fraca.');
            flash('error', $validator->errorMessage());
        }

        echo Template::instance()->render('hwapx/admin/admin/password.html');
    }

    public function phpinfo($f3) {
        $logger = new \Log(date('Y-m-d') . '_api.log');

        if($f3->get('SESSION.admin.id') == 1) {
            $logger->write('Usuário "' . $f3->get('SESSION.admin.email') . '" acessou a página de configurações do PHP.');
            return phpinfo();
        }

        $logger->write('Usuário "' . $f3->get('SESSION.admin.email') . '" teve o acesso negado a página de configurações do PHP.');

        $f3->error(404);
    }
}
