<?php

namespace Softsat\Locacao\Controller\Admin;

use Hwapx\Admin\Controller\Admin\Admin;
use Hwapx\Core\Library\Template;
use Hwapx\Core\Library\Validator;
use HwapX\Admin\Library\Builder\TableBuilder;
use HwapX\Admin\Library\Builder\FormBuilder;
use HwapX\Core\Library\DB\SQL\Mapper;
use Hwapx\Core\Library\Openssl;

class Cliente extends Admin {
    protected $validator = null;
    protected $logger    = null;
    protected $mapper    = null;
    protected $form = array(
        'name'   => 'Cliente',
        'table'  => 'softsat_locacao_admin_cliente_list',
        'depends'=> array(
            'softsat_locacao_contrato' => array(
                'name' => 'Contratos',
                'foreignkey' => 'cliente_id'
            ),
            'softsat_locacao_boleto' => array(
                'name' => 'Boletos',
                'foreignkey' => 'cliente_id '
            ),
        ),
        'fields' =>  array(
            'nome' => array(
                'label' => 'Nome',
                'type'  => 'text',
                'width' => 8,
                'rules' => array(
                    'required',
                    'lengthMax' => 40
                ),
            ),
            'nascimento' => array(
                'label' => 'Data de nascimento',
                'type'  => 'date',
                'width' => 4,
                'rules' => array(
                    'required',
                    'date',
                ),
            ),
            'estrangeiro' => array(
                'label'   => 'Estrangeiro',
                'type'    => 'dropdown',
                'width'   => 2,
                'default' => 0,
                'options' => array(
                    0 => 'NÃO',
                    1 => 'SIM'
                ),
            ),
            'cnpj_cpf' => array(
                'label' => 'CNPJ/CPF',
                'type'  => 'text',
                'width' => 4,
                //'mask'  => '(999.999.999-99)|(99.999.999/9999-99)',
                'rules' => array(
                    'required',
                    'cnpj_cpf_estrangeiro',//'cnpj_cpf',
                    ////'regex' => '/^[0-9]{3}\.[0-9]{3}\.[0-9]{3}-[0-9]{2}|[0-9]{2}.[0-9]{3}.[0-9]{3}\/[0-9]{4}-[0-9]{2}$/',
                    'uniqueRecord' => array(
                        'softsat_locacao_cliente',
                        'cnpj_cpf = @cnpj_cpf AND NOT id <=> @id',
                    ),
                ),
                'attributes' => array(
                    'data-inputmask-keepstatic' => 'true'
                )
            ),
            'ie_rg' => array(
                'label' => 'IE/RG',
                'type'  => 'text',
                'width' => 3,
                //'mask'  => '99.999.9999-9',
                'rules' => array(
                    ////'regex' => '/^\d+$/',
                    'uniqueRecord' => array(
                        'softsat_locacao_cliente',
                        'ie_rg = @ie_rg AND estrangeiro = @estrangeiro AND NOT id <=> @id',
                    ),
                ),
            ),
            'cnh' => array(
                'label' => 'CNH',
                'type'  => 'text',
                'width' => 3,
                'rules' => array(
                    //'required',
                    ////'regex' => '/^\d{11}$/',
                    //'cnh_estrangeiro',//'cnh',
                    'uniqueRecord' => array(
                        'softsat_locacao_cliente',
                        'cnh = @cnh AND NOT id <=> @id',
                    ),
                ),
                'attributes' => array(
                    'maxlength' => 11,
                )
            ),
            'endereco' => array(
                'label' => 'Endereço',
                'type'  => 'text',
                'width' => 8,
                'rules' => array(
                    'required',
                    'lengthMax' => 34
                ),
            ),
            'numero' => array(
                'label' => 'Número',
                'type'  => 'text',
                'width' => 4,
                'rules' => array(
                    'lengthMax' => 5
                ),
            ),
            'bairro' => array(
                'label' => 'Bairro',
                'type'  => 'text',
                'width' => 4,
                'rules' => array(
                    'lengthMax' => 15
                ),
            ),
            'cidade' => array(
                'label' => 'Cidade',
                'type'  => 'text',
                'width' => 5,
                'rules' => array(
                    'lengthMax' => 15
                ),
            ),
            'estado' => array(
                'label'   => 'Estado',
                'type'    => 'dropdown',
                'width'   => 3,
                'options' => array(
                    '' => '-- Selecione --',
                    'AC' => 'Acre',
                    'AL' => 'Alagoas',
                    'AP' => 'Amapá',
                    'AM' => 'Amazonas',
                    'BA' => 'Bahia',
                    'CE' => 'Ceará',
                    'DF' => 'Distrito Federal',
                    'ES' => 'Espírito Santo',
                    'GO' => 'Goiás',
                    'MA' => 'Maranhão',
                    'MT' => 'Mato Grosso',
                    'MS' => 'Mato Grosso do Sul',
                    'MG' => 'Minas Gerais',
                    'PA' => 'Pará',
                    'PB' => 'Paraíba',
                    'PR' => 'Paraná',
                    'PE' => 'Pernambuco',
                    'PI' => 'Piauí',
                    'RJ' => 'Rio de Janeiro',
                    'RN' => 'Rio Grande do Norte',
                    'RS' => 'Rio Grande do Sul',
                    'RO' => 'Rondônia',
                    'RR' => 'Roraima',
                    'SC' => 'Santa Catarina',
                    'SP' => 'São Paulo',
                    'SE' => 'Sergipe',
                    'TO' => 'Tocantins',
                ),
            ),
            'cep' => array(
                'label' => 'CEP',
                'type'  => 'text',
                'width' => 4,
                'mask'  => '99999-999',
            ),
            'celular' => array(
                'label' => 'Celular',
                'type'  => 'text',
                'width' => 4,
                'mask'  => '(99)99999-9999',
                'rules' => array(
                    'required'
                ),
            ),
            'telefone' => array(
                'label' => 'Telefone residencial',
                'type'  => 'text',
                'width' => 4,
                'mask'  => '(99)9999-9999[9]',
            ),
            'telefone_comercial' => array(
                'label' => 'Telefone comercial',
                'type'  => 'text',
                'width' => 4,
                'mask'  => '(99)9999-9999[9]',
            ),
            'email' => array(
                'label' => 'Email',
                'type'  => 'email',
                'width' => 8,
                'rules' => array(
                    'email',
                    'uniqueRecord' => array(
                        'softsat_locacao_cliente',
                        'email = @email AND NOT id <=> @id',
                    ),
                )
            ),
            'senha' => array(
                'label' => 'Senha',
                'type'  => 'password',
                'width' => 4,
            ),
            'foto' => array(
                'label' => 'Foto',
                'type'  => 'image',
                'width' => 4,
            ),
        )
    );

    protected $form_cartao = array(
        'name'   => 'Cartões do cliente',
        'table'  => 'softsat_locacao_admin_cliente_list',
        'groups' => array(
            'cliente' => array(
                'legend' => 'Cliente',
                'fields' =>  array(
                    'nome' => array(
                        'label' => 'Nome',
                        'type'  => 'static',
                        'width' => 12,
                    ),
                    'estrangeiro' => array(
                        'label'   => 'Estrangeiro',
                        'type'    => 'static',
                        'width'   => 2,
                        'default' => 0,
                        'options' => array(
                            0 => 'NÃO',
                            1 => 'SIM'
                        ),
                    ),
                    'cnpj_cpf' => array(
                        'label' => 'CNPJ/CPF',
                        'type'  => 'static',
                        'width' => 4,
                    ),
                    'ie_rg' => array(
                        'label' => 'IE/RG',
                        'type'  => 'static',
                        'width' => 3,
                    ),
                    'cnh' => array(
                        'label' => 'CNH',
                        'type'  => 'static',
                        'width' => 3,
                    ),
                ),
            ),
            'cartao' => array(
                'legend' => 'Cartões',
                'foreignkey' => 'cliente_id',
                'table'  => array(
                    'nome' => array(
                        'label' => 'Nome',
                        'type'  => 'text',
                        'rules' => array(
                            'required'
                        )
                    ),
                    'bandeira' => array(
                        'label'   => 'Bandeira',
                        'type'    => 'dropdown',
                        'default' => 1,
                        'options' => array(
                            '' => '-- Selecione --',
                            'American Express' => 'American Express',
                            'Diners Club' => 'Diners Club',
                            'Elo' => 'Elo',
                            'Hipercard' => 'Hipercard',
                            'Mastercard' => 'Mastercard',
                            'Visa' => 'Visa',
                            'Outra' => 'Outra',
                        ),
                        'rules' => array(
                            'required'
                        ),
                    ),
                    'numero' => array(
                        'label' => 'Número',
                        'type'  => 'text',
                        'mask'  => '(9999-999-999-9999)|(9999-999999-99999)|(9999-9999-9999-9999)',
                        'attributes' => array(
                            'data-inputmask-keepstatic' => 'true'
                        ),
                        'rules' => array(
                            'required',
                            'creditCard'
                        )
                    ),
                    'validade' => array(
                        'label' => 'Validade',
                        'type'  => 'text',
                        'mask'  => '99/99[99]',
                        'rules' => array(
                            'required'
                        )
                    ),
                    'cvv' => array(
                        'label'   => 'CVV',
                        'type'    => 'text',
                        'rules' => array(
                            'required',
                            'numeric'
                        ),
                    ),
                )
            ),
        ),
    );

    protected $table = array(
        'name'   => 'Clientes',
        'cols'   => array(
            'id'    => 'Código',
            'nome'  => 'Nome',
            'cnpj_cpf'   => array(
                'label' => 'CNPJ/CPF',
                //'mask'  => '(999.999.999-99)|(99.999.9999/9999-99)',
            ),
            'ie_rg' => 'IE/RG',
            'cnh'   => 'CNH',
        ),
        'actions' => array(
            array(
                'route'       => 'softsat_locacao_admin_cliente_create',
                'description' => 'Novo',
                'class'       => 'btn-primary',
                'role'        => 'softsat.locacao.cliente_create'
            )
        ),
        'rowactions' => array(
            array(
                'route'       => 'softsat_locacao_admin_cliente_edit',
                'description' => 'Alterar',
                'class'       => 'btn-primary',
                'default'     => true,
                'role'        => 'softsat.locacao.cliente_edit'
            ),
            array(
                'route'       => 'softsat_locacao_admin_cliente_cartao_auth',
                'description' => 'Cartões',
                'class'       => 'btn-warning',
                'default'     => true,
                'role'        => 'softsat.locacao.cliente_cartao'
            ),
            array(
                'route'       => 'softsat_locacao_admin_cliente_remove',
                'description' => 'Remover',
                'class'       => 'btn-danger',
                'confirm'     => true,
                'role'        => 'softsat.locacao.cliente_remove'
            )
        ),
        'rowcount' => true,
        'route'    => 'softsat_locacao_admin_cliente_list'
    );

    public function __construct($f3) {
        parent::__construct($f3);

        $db           = $f3->get('db');
        $this->mapper = new \DB\SQL\Mapper($db, 'softsat_locacao_cliente');
    }

    public function index($f3) {
        $this->module->checkRole('softsat.locacao.cliente_list');

        echo TableBuilder::instance($this->mapper, $this->table)->render();
    }

    public function create($f3) {
        $this->module->checkRole('softsat.locacao.cliente_create');

        $this->configurarValidacao();

        echo FormBuilder::instance($this->mapper, $this->form)->handle();
    }

    public function edit($f3) {
        $this->module->checkRole('softsat.locacao.cliente_edit');

        $this->configurarValidacao();

        echo FormBuilder::instance($this->mapper, $this->form)->handle();
    }

    public function cartao_auth($f3) {
        if($f3->get('VERB') == 'GET') {
            flash('warning', 'Para acessar essa área do cadastro você deve reautenticar-se.');

            echo Template::instance()->render('softsat/locacao/cliente/auth.html');
            return;
        }

        $logger = new \Log(date('Y-m-d') . '_cliente_cartao.log');
        $db = $f3->get('db');

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

        if ($user->dry() || !\Bcrypt::instance()->verify($f3->get('POST.password'), $user->password)) {
            $logger->write('Falha na autenticação com o usuário "' . $f3->get('POST.email') . '" na área de Cartões do cliente');

            flash('error', 'Senha incorreta.');

            $f3->reroute('@softsat_locacao_admin_cliente_cartao_auth');
            return;
        }

        $logger->write('Usuário "' . $f3->get('POST.email') . '" autenticado na área de Cartões do cliente com sucesso');

        flash('softsat_locacao_admin_cliente_cartao_auth.'.$f3->get('PARAMS.id'), time());

        $f3->reroute('@softsat_locacao_admin_cliente_cartao');
    }

    public function cartao($f3) {
        $this->module->checkRole('softsat.locacao.cliente_cartao');

        $authenticated = (int)flash('softsat_locacao_admin_cliente_cartao_auth.'.$f3->get('PARAMS.id'));
        $expire = $f3->get('softsat_locacao_admin_cliente_cartao.auth_expire');

        if(time() - $authenticated > $expire) {
            flash('error', 'Sua sessão expirou!');
            $f3->reroute('@softsat_locacao_admin_cliente_cartao_auth');
            return;
        }

        $persistSession = function() use($f3, $authenticated, $expire) {
            $expire_ms = ($expire + $authenticated) * 1000;
            $f3->set('meta.scripts.raw.cartao_auth', "setTimeout(function() { window.location.reload(); }, (new Date($expire_ms)).getTime() - (new Date()).getTime());");
            flash('softsat_locacao_admin_cliente_cartao_auth.'.$f3->get('PARAMS.id'), $authenticated);
            flash('warning', 'Sua sessão ira expirar em ' . date($f3->get('app.datetime.format'), $authenticated + $expire));
        };

        if($f3->get('VERB') == 'GET')
            $persistSession();

        $mappers = array(
            $this->mapper,
            'cartao' => new \DB\SQL\Mapper($f3->get('db'), 'softsat_locacao_cliente_cartao')
        );

        $openssl = new Openssl();
        $openssl->setKey('file://' . $this->f3->get('ROOT') . '/app/config/app.pem', $f3->get('password.openssl'));
        $openssl->setPadding(OPENSSL_PKCS1_OAEP_PADDING);

        echo FormBuilder::instance($mappers, $this->form_cartao)->afterLoad(function($mapper) use($openssl) {
            if($mapper->nome)
                $mapper->nome = $openssl->privateDecrypt($mapper->nome);
            if($mapper->bandeira)
                $mapper->bandeira = $openssl->privateDecrypt($mapper->bandeira);
            if($mapper->numero)
                $mapper->numero = $openssl->privateDecrypt($mapper->numero);
            if($mapper->validade)
                $mapper->validade = $openssl->privateDecrypt($mapper->validade);
            if($mapper->cvv)
                $mapper->cvv = $openssl->privateDecrypt($mapper->cvv);
        }, 'cartao')->beforeSave(function($mapper) use($openssl) {
            $mapper->nome = $openssl->publicEncrypt($mapper->nome);
            $mapper->bandeira = $openssl->publicEncrypt($mapper->bandeira);
            $mapper->numero = $openssl->publicEncrypt($mapper->numero);
            $mapper->validade = $openssl->publicEncrypt($mapper->validade);
            $mapper->cvv = $openssl->publicEncrypt($mapper->cvv);
        }, 'cartao')->onError($persistSession)->handle();
    }

    public function remove($f3) {
        $this->module->checkRole('softsat.locacao.cliente_remove');

        echo FormBuilder::instance($this->mapper, $this->form)->delete();
    }

    protected function configurarValidacao() {
        Validator::instance()->addRule(
            'cnpj_cpf_estrangeiro',
            function($field, $value, array $params, array $fields) {
                $cnpj_cpf = Validator::instance()->getRuleCallback('cnpj_cpf');

                return $fields['estrangeiro'] || $cnpj_cpf($field, $value, $params, $fields);
            },
            'inválido'
        );
        Validator::instance()->addRule(
            'cnh_estrangeiro',
            function($field, $value, array $params, array $fields) {
                $cnh = Validator::instance()->getRuleCallback('cnh');

                return $fields['estrangeiro'] || $cnh($field, $value, $params, $fields);
            },
            'inválida'
        );

        $this->f3->set('meta.scripts.raw.estrangeiro', '
            var $estrangeiro = $("[name=estrangeiro]");
            var $cpf_cnpj    = $("[name=cnpj_cpf]");
            var $ie_rg       = $("[name=ie_rg");
            $estrangeiro.change(function() {
                var yes = $estrangeiro.find("option:selected").val() == 1;

                if(yes) {
                    $cpf_cnpj.inputmask("remove");
                    $ie_rg.removeAttr("pattern").removeAttr("title");
                } else {
                    $cpf_cnpj.inputmask({
                        mask: "(999.999.999-99)|(99.999.999/9999-99)",
                        keepStatic: true
                    });
                    $ie_rg.attr("pattern", "^[0-9]*$").attr("title", "Apenas números, sem pontuação");
                }
            }).trigger("change");
        ');
    }
}
