<?php


class limiterlock
{
    private $text_lock = '';
    private $time_unlock = '';
    private $registry;
    private $config;
    private $load;
    private $db;
    private $request;
    private $session;
    private $log;
    private $validate;
    private $customer;
    private $language;

    public function __construct($registry)
    {
        $this->registry = $registry;
        $this->config = $registry->get('config');
        $this->load = $registry->get('load');
        $this->db = $registry->get('db');
        $this->request = $registry->get('request');
        $this->session = $registry->get('session');
        $this->log = $registry->get('log');
        $this->validate = $registry->get('validate');
        $this->customer = $registry->get('customer');
        $this->language = $registry->get('language');

    }

    public function getTimeUnlock()
    {
        return $this->time_unlock;
    }

    public function operationsLock($time_lock, $id)
    {
        if (!$this->config->get('safety_limiter_status')) {
            return false;
        }
        if ($time_lock) {
            $limiter = json_decode(Crypto::descriptografarAES256($time_lock, Crypto::CAES256));
            if (!$limiter) {
                $this->text_lock = "Atividades suspeitas identificadas, informações do usuário fora do comum";
                return true;
            }
            if (!isset($limiter->customer_id) or ((int) $limiter->customer_id <> (int) $id)) {
                $this->text_lock = "Atividades suspeitas identificadas, informações do usuário fora do comum";
                return true;
            } else {
                $now = new DateTime($this->db->dataAtual(), new DateTimeZone('America/Sao_Paulo'));

                if (isset($limiter->date_lock) and $limiter->date_lock == "0") {
                    return false;
                }

                if (isset($limiter->date_unlock)) {
                    if ($limiter->date_unlock == "0") {
                        $this->text_lock = "Atividades suspeitas identificadas
                                Movimentações: " . $limiter->count_limiter->value . " no período definido
                                Bloqueio por tempo indeterminado";
                        return true;

                    }

                    $unlock = new DateTime($limiter->date_unlock->date, new DateTimeZone('America/Sao_Paulo'));
                    if ($unlock->format("Y-m-d H:i:s")) {
                        if ($unlock->format("Y-m-d H:i:s") <= $now->format("Y-m-d H:i:s")) {
                            $this->unlock($id);
                            return false;
                        } else {
                            $this->text_lock = "Atividades suspeitas identificadas
                                Movimentações: " . $limiter->count_limiter->value . " no período definido
                                Desbloqueio " . $unlock->format("d/m/Y H:i");
                            $this->time_unlock = "Desbloqueio " . $unlock->format("d/m/Y H:i");
                            return true;
                        }
                    }
                }
            }
        } else {
            $this->text_lock = "Atividades suspeitas identificadas, informações do usuário fora do comum";
            return true;
        }
    }

    public function checklimit($customer)
    {
        $this->load->dmodel('checkout/order');

        $safety = [];
        $configs = ['safety_limiter_status', 'safety_limiter_time_break', 'safety_limiter_transaction', 'safety_limiter_transaction_time', 'safety_limiter_client', 'safety_limiter_ip', 'safety_limiter_mail'];

        foreach ($configs as $value) {
            $safety[$value] = $this->config->get($value);
        }

        if ($safety['safety_limiter_status']) {
            $bBanIp = false;
            $bBanAccount = false;

            if ($safety['safety_limiter_ip']) {
                $count_ip_limiter = $this->load->dmodel_checkout_order->getOrdersLimiterByIP($this->request->server['REMOTE_ADDR'], $safety);
                if ($count_ip_limiter['value'] > $safety['safety_limiter_transaction']) {
                    $bBanIp = true;
                    $this->customer->setIPLock($this->request->server['REMOTE_ADDR']);
                }
            }

            if ($safety['safety_limiter_client']) {
                $count_customer_limiter = $this->load->dmodel_checkout_order->getOrdersLimiterByCustommer($customer->getId(), $safety);
                if ($count_customer_limiter['value'] > $safety['safety_limiter_transaction']) {
                    $customer->setCustomerLock($customer->getId(), $count_customer_limiter, $safety);
                    $bBanAccount = true;
                }
            }

            if ($bBanIp || $bBanAccount) {
                if ($bBanAccount) {
                    $this->connectEmail($this->customer);
                }
                $this->customer->logout();
                $_SESSION['customer_id'] = 0;
                $this->text_lock = $this->language->get('t_e_limiter_ip');

            }
        }

        if ($this->text_lock != '') {
            return true;
        } else {
            return false;
        }
    }

    private function unlock($customer_query)
    {
        $this->db->query("UPDATE oc_customer SET time_lock = '" . Crypto::criptografarAES256(json_encode(['customer_id' => $customer_query, 'date_lock' => '0']), Crypto::CAES256) . "'WHERE customer_id = {$customer_query};");
    }

    public function getInformation()
    {
        return $this->text_lock;
    }

    private function connectEmail($customer)
    {
        $config_smtp_host = $this->config->get('config_smtp_host');
        $config_smtp_username = $this->config->get('config_smtp_username');
        $config_smtp_password = $this->config->get('config_smtp_password');
        $config_smtp_port = $this->config->get('config_smtp_port');
        $config_smtp_timeout = $this->config->get('config_smtp_timeout');
        $config_mail_parameter = $this->config->get('config_mail_parameter');
        $config_mail_protocol = $this->config->get('config_mail_protocol');
        $config_email_test = $this->config->get('safety_limiter_mail');
        $config_owner = $this->config->get('config_owner');

        $errors = $this->validate->execute([
            'config_smtp_host' => [
                'value' => $config_smtp_host,
                'validates' => ['isEmpty'],
            ],
            'config_smtp_username' => [
                'value' => $config_smtp_username,
                'validates' => ['isEmpty'],
            ],
            'config_smtp_password' => [
                'value' => $config_smtp_password,
                'validates' => ['isEmpty'],
            ],
            'config_smtp_port' => [
                'value' => $config_smtp_port,
                'validates' => ['isEmpty'],
            ],
            'config_smtp_timeout' => [
                'value' => $config_smtp_timeout,
                'validates' => ['isEmpty'],
            ],
            'config_mail_protocol' => [
                'value' => $config_mail_protocol,
                'validates' => ['isEmpty'],
            ],
            'config_email_test' => [
                'value' => $config_email_test,
                'validates' => ['isEmpty', 'isEmail'],
            ],
            'config_owner' => [
                'value' => $config_owner,
                'validates' => ['isEmpty'],
            ],
        ]);

        $response = [];

        if ($errors) {
            $response['errors'] = $errors;
            return $response;
        }

        try {
            $mail = new Mail($this->registry ?? null);

            $mail->protocol = $config_mail_protocol;
            $mail->parameter = $config_mail_parameter ?? false;
            $mail->hostname = $config_smtp_host;
            $mail->username = $config_smtp_username;
            $mail->password = $config_smtp_password;
            $mail->port = $config_smtp_port;
            $mail->timeout = $config_smtp_timeout;

            $mail->setTo($config_email_test);
            $mail->setFrom($config_smtp_username);
            $mail->setSender($config_owner);
            $mail->setSubject("Informativo de bloqueio de usuário por atividades suspeitas");
            $mail->setText("Informativo do Sistema,
            O usuario " . $customer->getFirstName() . ", ID: " . $customer->getId() . " 
            Foi bloqueado devido a atividades suspeitas identificadas através do módulo de segurança Limitador de transações.");
            ;


            $mail->send(true);

            $response['success'] = 'Envio de teste realizado com sucesso';
        } catch (Exception $e) {
            $response['warning'] = 'Erro ao enviar contato tente novamente mais tarde!';
            if ($this->config->get('config_error_log')) {
        $logData = [
            'message'  => 'Erro ao Enviar contato',
            'exception'=> [
                'type'    => get_class($e),
                'message' => $e->getMessage(),
                'code'    => $e->getCode(),
                'file'    => $e->getFile(),
                'line'    => $e->getLine(),
                'trace'   => $e->getTraceAsString()
            ],
            'datetime' => date('c'), // data/hora no padrão ISO
        ];
                $this->log->write(json_encode($logData, JSON_UNESCAPED_UNICODE));
            }
        }

        return $response;
    }
}