<?php

namespace Config;

use App\Models\UserModel;
use function constant;

//--------------------------------------------------------------------
// Custom Rule Functions
//--------------------------------------------------------------------

class CustomRules
{
    public function validate_cpf($cpf)
    {
        if ($cpf === null) {
            return true;
        }
        // Verifica formato de cpf
        if (preg_match(REGEX_CPF, $cpf)) {
            $primeiro_digito_verificador = (int)substr($cpf, -2, -1);
            $segundo_digito_verificador = (int)substr($cpf, -1);
            $cpf = preg_replace('/[.-]/', '', $cpf);
            $digitos_repetidos = !!preg_match('/^(.)\1+$/', $cpf);
            if ($digitos_repetidos) {
                return false;
            }
            $digitos = array_map(function ($digito) {
                return (int)$digito;
            }, str_split($cpf));

            // Verifica primeiro dígito verificador
            $soma = 0;
            $j = 0;
            for ($i = 10; $i >= 2; $i--) {
                $soma += $i * $digitos[$j++];
            }
            $resto = $soma * 10 % 11;
            $resto = $resto >= 10 ? 0 : $resto;
            if ($resto !== $primeiro_digito_verificador) {
                return false;
            }

            // Verifica segundo dígito verificador
            $soma = 0;
            $j = 0;
            for ($i = 11; $i >= 2; $i--) {
                $soma += $i * $digitos[$j++];
            }
            $resto = $soma * 10 % 11;
            $resto = $resto >= 10 ? 0 : $resto;
            return $resto === $segundo_digito_verificador;
        } else {
            return false;
        }
    }

    public function validate_cnpj ($cnpj) {
        if (is_null($cnpj)) {
            return true;
        }
        if (preg_match(REGEX_CNPJ, $cnpj)) {
            $primeiro_digito_verificador = (int)substr($cnpj, -2, -1);
            $segundo_digito_verificador = (int)substr($cnpj, -1);
            $cnpj = str_split(preg_replace('/[-.\/]/', '', $cnpj));
            // Cálculo do primeiro dígito verificador
            $ref_calculo_digito = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
            for($i = 0, $soma = 0; $i < 12; $i++) {
                $soma += $ref_calculo_digito[$i] * (int)$cnpj[$i];
            }
            $resto = $soma % 11;
            $digito_verificador = $resto < 2 ? 0 :  11 - $resto;
            if ($digito_verificador !== $primeiro_digito_verificador) {
                return false;
            }
            // Cálculo do segundo dígito verificador
            $ref_calculo_digito = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
            for($i = 0, $soma = 0; $i < 13; $i++) {
                $soma += $ref_calculo_digito[$i] * (int)$cnpj[$i];
            }
            $resto = $soma % 11;
            $digito_verificador = $resto < 2 ? 0 :  11 - $resto;
            return $digito_verificador === $segundo_digito_verificador;
        } else {
            return false;
        }
    }

    public function validate_rg ($str) {
        return !!preg_match(REGEX_RG, $str);
    }

    public function only_letters_and_spaces($str){
        return !!preg_match(REGEX_ONLY_LETTERS_SPACES, $str);
    }


    public function validate_date($date)
    {
        if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
            $ano = (int)substr($date, 0, 4);
            $mes = (int)substr($date, 5, 6);
            $dia = (int)substr($date, 8, 9);
            return !!checkdate($mes, $dia, $ano);
        } else {
            return !$date;
        }
    }

    /* Valida datas que sejam anteriores à data atual */
    public function validate_birthdate($str)
    {
        // Esse método deve sempre ser usado em conjunto com o
        // validar_data, pois ele pressupõe que a entrada este-
        // ja no formato yyyy-mm-dd. Se não estiver neste for-
        // mato, não irá funcionar como esperado.
        if ($str === null || $str === '') {
            return true;
        } else {
            $data_nascimento = date_create($str);
            $data_atual = date_create();
            $idade = $data_nascimento->diff($data_atual)->y;
            $atende_idade_minima = $idade >= MIN_AGE_REGISTER;
            $atende_idade_maxima = $idade <= MAX_AGE_REGISTER;
            return $atende_idade_minima && $atende_idade_maxima;
        }
    }

    public function validate_cep($cep)
    {
        return $cep === null || $cep === ''
            ? true
            : !!preg_match(REGEX_CEP, $cep);
    }

    public function validate_phone($telefone)
    {
        return $telefone === null || $telefone === ''
            ? true
            : !!preg_match(REGEX_PHONE, $telefone);
    }

    public function validate_phonelandline($telefone)
    {
        return $telefone === null || $telefone === ''
            ? true
            : !!preg_match(REGEX_PHONE_LANDLINE, $telefone);
    }

    public function validate_horario (string $time) {
        return !!preg_match(REGEX_HORARIO, $time);
    }

}
