<?php
class ControllerCommonHome extends Controller {
    const METHOD_CHART = 'getOrderTotalValueDate';
    const METHOD_DEVICE = 'getOrderValueDevice';
    const METHOD_MARKETPLACE = 'getOrderValueMarketplace';
    const METHOD_SALES_CHANNEL = 'getOrderValueSalesChannel';
    const TIPO_MARKETPLACE = 'Type_MarketplaceInt';
    const TIPO_ORIGEM_SISTEMA = 'Type_OrigemSistema';
    const CACHE_NAME_CHART = 'homeGraph_';
    const NAME_CHART_TOTAL_ORDER = 'order_total_value_';
    const NAME_CHART_DEVICES = 'order_devices_value_';
    const NAME_CHART_MARKETPLACE = 'order_marketplaces_value_';
    const NAME_CHART_SALES_CHANNEL = 'order_sales_channels_value_';
    
    public function index() {
        $language = $this->language->load('common/home');
        $this->data = array_merge($this->data, $language);

        $this->load->type('tipocomum');

        $this->load->model('setting/efutura');

        $skyhub_invalid_credential =  $this->config->get('skyhub_invalid_credential');
        $skyhub_status =  $this->config->get('skyhub_status');
        if($skyhub_status == Type_Status::Tp_Desabilitado && $skyhub_invalid_credential){
            $this->data['show_skyhub_invalid_credentials_message'] = true;
            if (isset($this->data['warning_skyhub_credential'])) {
                $this->data['warning_skyhub_credential'] = sprintf(
                    $this->language->get('warning_skyhub_credential'),
                    $this->url->link('module/skyhub/settings', 'token=' . $this->session->data['token'] . '&type=' . Type_TitleModules::Tp_Marketplace . '#tab-info=0', 'SSL')
                );
            }
        } else {
            $this->data['show_skyhub_invalid_credentials_message'] = false;
        }

        $correios_invalid_credential =  $this->config->get('correios_invalid_credential');
        $correios_tracking_status =  $this->config->get('correios_tracking_status');
        if($correios_tracking_status == Type_Status::Tp_Desabilitado && $correios_invalid_credential){
            $this->data['show_correios_invalid_credentials_message'] = true;
            if (isset($this->data['warning_correios_credential'])) {
                $this->data['warning_correios_credential'] = sprintf(
                    $this->language->get('warning_correios_credential'),
                    $this->url->link('shipping/correios', 'token=' . $this->session->data['token'] . '&type=' . Type_TitleModules::Tp_Envio . '#tab-info=2', 'SSL')
                );
            }
        } else {
            $this->data['show_correios_invalid_credentials_message'] = false;
        }

        $this->data['showECommerceLinks'] = $this->config->get('config_sistema_ecommerce');
        $this->data['showMarketplaceLinks'] =  $this->config->get('config_sistema_marketplace');

        $this->data['production_link_warning'] = $this->config->get('config_sistema_ecommerce') && empty($this->config->get('config_linkproducao_ssl'));
        $this->data['link_manual_dominio'] = 'http://manual.futurasistemas.com.br/manual-do-sistema/como-configurar-dominio-de-complemento-no-cpanel/';

        $this->document->setTitle($this->language->get('heading_title'));

        $this->data['review_link'] = sprintf($this->language->get('text_review_link'), $this->url->link('catalog/review', 'token=' . $this->session->data['token'], 'SSL'));

        $this->data['configbar'] = $this->getChild('common/configbar');
        $this->data['last_sales_order'] = $this->getChild('common/home/last_sales_order');

        $this->data['store_rating_module_status'] = $this->config->get('store_rating_module_status');

        $this->data['link_product'] = $this->url->link('catalog/product', 'token=' . $this->session->data['token'], 'SSL');
        $this->data['link_order'] = $this->url->link('sale/order', 'token=' . $this->session->data['token'], 'SSL');
        $this->data['link_customer'] = $this->url->link('sale/customer', 'token=' . $this->session->data['token'], 'SSL');
        $this->data['link_customer_online'] = $this->url->link('report/customer_online', 'token=' . $this->session->data['token'], 'SSL');
        $this->data['link_searchterms'] = $this->url->link('report/searchterms', 'token=' . $this->session->data['token'], 'SSL');
        $this->data['link_most_viewed'] = $this->url->link('report/product_viewed', 'token=' . $this->session->data['token'], 'SSL');

        $this->document->addScript(array(
            'view/javascript/jquery/charts.js',
            'view/public/js/page-home.js'
        ));

        // Check install directory exists
        if (is_dir(dirname(DIR_APPLICATION) . '/install')) {
            $this->data['error_install'] = $this->language->get('error_install');
        } else {
            $this->data['error_install'] = '';
        }

        // Check image directory is writable
        $file = DIR_IMAGE . 'test';

        $handle = fopen($file, 'a+');

        fwrite($handle, '');

        fclose($handle);

        if (!file_exists($file)) {
            $this->data['error_image'] = sprintf($this->language->get('error_image'). DIR_IMAGE);
        } else {
            $this->data['error_image'] = '';

            unlink($file);
        }

        // Check image cache directory is writable
        $file = DIR_IMAGE . 'cache/test';

        $handle = fopen($file, 'a+');

        fwrite($handle, '');

        fclose($handle);

        if (!file_exists($file)) {
            $this->data['error_image_cache'] = sprintf($this->language->get('error_image_cache'). DIR_IMAGE . 'cache/');
        } else {
            $this->data['error_image_cache'] = '';

            unlink($file);
        }

        // Check cache directory is writable
        $file = DIR_CACHE . 'test';

        $handle = fopen($file, 'a+');

        fwrite($handle, '');

        fclose($handle);

        if (!file_exists($file)) {
            $this->data['error_cache'] = sprintf($this->language->get('error_image_cache'). DIR_CACHE);
        } else {
            $this->data['error_cache'] = '';

            unlink($file);
        }

        // Check download directory is writable
        $file = DIR_DOWNLOAD . 'test';

        $handle = fopen($file, 'a+');

        fwrite($handle, '');

        fclose($handle);

        if (!file_exists($file)) {
            $this->data['error_download'] = sprintf($this->language->get('error_download'). DIR_DOWNLOAD);
        } else {
            $this->data['error_download'] = '';

            unlink($file);
        }

        // Check logs directory is writable
        $file = DIR_LOGS . 'test';

        $handle = fopen($file, 'a+');

        fwrite($handle, '');

        fclose($handle);

        if (!file_exists($file)) {
            $this->data['error_logs'] = sprintf($this->language->get('error_logs'). DIR_LOGS);
        } else {
            $this->data['error_logs'] = '';

            unlink($file);
        }

        $this->data['breadcrumbs'] = array();

        $this->data['breadcrumbs'][] = array(
            'text'      => $this->language->get('text_home'),
            'href'      => $this->url->link('common/home', 'token=' . $this->session->data['token'], 'SSL'),
            'separator' => false
        );

        $this->data['token'] = $this->session->data['token'];


        $update_dashboard = $this->updateDashboard(false);
       
        //Pedidos
        $this->load->model('sale/order');
        $this->data['total_order'] = $update_dashboard['total_order'];
        $this->data['total_order_year'] = $update_dashboard['total_order_year'];

        //Total vendas
        $this->load->model('sale/order');
        $this->data['total_sale'] = $update_dashboard['total_sale'];
        $this->currency->format($update_dashboard['total_sale'], $this->config->get('config_currency'));
        $this->data['total_sale_year'] = $update_dashboard['total_sale_year'];
        sprintf($this->language->get('total_sale_year'), $this->currency->format($update_dashboard['total_sale_year'], $this->config->get('config_currency')));    
    
        //ticket medio
        $this->load->model('sale/order');
        $this->data['average_sale'] = $update_dashboard['average_sale'];
        $this->currency->format($update_dashboard['average_sale'], $this->config->get('config_currency'));

        //Produtos
        $this->load->model('catalog/product');
        $this->data['total_product'] = $update_dashboard['total_product'];
        $this->data['total_product_year'] = $update_dashboard['total_product_year']; 
  
        //Clientes
        $this->load->model('sale/customer');
        $this->data['total_customer'] = $update_dashboard['total_customer'];
        $this->data['total_customer_year'] = $update_dashboard['total_customer_year'];

        //clientes online
        $this->load->model('report/online');
        $this->data['total_customer_online'] = $update_dashboard['total_customer_online'];
        date_default_timezone_set('America/Sao_Paulo');
        $this->data['customers_online_last_refresh'] = date("H:i");

  
        $this->load->model('catalog/review');

        $this->data['total_review'] = $this->model_catalog_review->getTotalReviews();
        $this->data['total_review_approval'] = $this->model_catalog_review->getTotalReviewsAwaitingApproval();

        $this->load->model('catalog/store_rating');
        $this->data['total_store_rating'] = $this->model_catalog_store_rating->getTotalRatings();
        $this->data['total_store_rating_approval'] = $this->model_catalog_store_rating->getTotalRatingsAwaitingApproval();

        $this->load->model('sale/affiliate');

        $this->data['total_affiliate'] = $this->model_sale_affiliate->getTotalAffiliates();
        $this->data['total_affiliate_approval'] = $this->model_sale_affiliate->getTotalAffiliatesAwaitingApproval();

        $this->load->dmodel('catalog/searchterms');
        $this->data['search_terms'] = $this->dmodel_catalog_searchterms->getSearchTermsMostWanted(array('limit' => 10));

        $this->load->model('report/product');
        $this->data['most_viewed_products'] = $this->model_report_product->getProductsViewed(array('limit' => 10, 'start' => 0));

        $this->data['marketplace_status'] = array_filter(array(
            $this->config->get('skyhub_status'),
            $this->config->get('mercadolivre_status'),
            $this->config->get('shopee_status'),
        ));

        $this->data['app_status'] = (int)$this->model_sale_order->getOrderApp();

        $quick_config = $this->config->get('quick_config');

        $userName = $this->user->getUserName();
        $userID = $this->user->getId();

        if (isset($quick_config) && $userName != 'futura') {
            $this->data['exibe_quick_configure'] = (!isset($quick_config[$userID]) || (isset($quick_config[$userID]) && ($quick_config[$userID]['status'] == 1 && strtotime($quick_config[$userID]['date']) < strtotime(date('Y-m-d'))))) ? 1 : 0;
        } else {
            $this->data['exibe_quick_configure'] = 0;
        }

        if (!$this->user->hasPermission('access', Type_PermissaoFuncao::Tp_OrderStats)) {
          $this->data['order_stats_permission'] = false;
        } else {
          $this->data['order_stats_permission'] = true;
        }

        $this->children = array(
            'common/header',
            'common/footer'
        );

        $this->response->setOutput($this->render('common/home'));
    }

    // CHART
    public function chart() {
        $this->chargeDefaults();
        $cache = new CacheFile();

        $data = array();
        $data['order'] = array();
        $data['xaxis'] = array();
        $data['label_order']	  = $this->language->get('text_order');

        $range = $this->request->get['range'] ?? Type_Period::Tp_Month;
        $ignoreCache = isset($this->request->get['ignoreCache']) && $this->request->get['ignoreCache'] === 'true';

        $cacheKey = self::CACHE_NAME_CHART . self::NAME_CHART_TOTAL_ORDER . $range;
        $dataCache = $cache->get($cacheKey);

        if (!$dataCache || $ignoreCache) {
            $methodPrefix = self::METHOD_CHART;
            $result = $this->processChart($range, $methodPrefix);
            $data['order'] = $result['data']['order'];
            $data['xaxis'] = $result['data']['xaxis'];

            if ($dataCache) {
                $cache->delete($cacheKey);
                $dataCache = $cache->get($cacheKey);
            }

            $data['text_refresh_graph_time'] = date('d/m/Y H:i:s');

            if ($range != 'customizable') {
                $cache->set($cacheKey, $data, 3600); // 1 hora
            }
        } else {
            if (isset($dataCache['order'])) {
                $data['order'] = $dataCache['order'];
            }
            if (isset($dataCache['xaxis'])) {
                $data['xaxis'] = $dataCache['xaxis'];
            }
        }

        $this->response->setOutput(json_encode($data));
    }


    // CHART DEVICE
    public function chartDevice(){
        $this->chargeDefaults();
        $cache = new CacheFile();

        $data = array();
        $data['desktop'] = array();
        $data['tablet'] = array();
        $data['mobile'] = array();
        $data['xaxis'] = array();
        $data['label_desktop']  =  $this->language->get('text_desktop');
        $data['label_tablet']   =  $this->language->get('text_tablet');
        $data['label_mobile']   =  $this->language->get('text_mobile');

        $range = $this->request->get['range'] ?? Type_Period::Tp_Month;
        $ignoreCache = isset($this->request->get['ignoreCache']) && $this->request->get['ignoreCache'] === 'true';

        $cacheKey = self::CACHE_NAME_CHART . self::NAME_CHART_DEVICES . $range;
        $dataCache = $cache->get($cacheKey);

        if (!$dataCache || $ignoreCache) {
            $result = $this->processChart($range, self::METHOD_DEVICE);
            $data['desktop'] =$result['data']['desktop'];
            $data['tablet'] = $result['data']['tablet'];
            $data['mobile'] = $result['data']['mobile'];
            $data['xaxis'] = $result['data']['xaxis'];

            if ($dataCache) {
                $cache->delete($cacheKey);
                $dataCache = $cache->get($cacheKey);
            }

            $data['text_refresh_graph_time'] = date('d/m/Y H:i:s');

            if ($range != 'customizable') {
                $cache->set($cacheKey, $data, 3600); // 1 hora
            }
        } else {
            if (isset($dataCache['desktop'])) {
                $data['desktop'] = $dataCache['desktop'];
            }
            if (isset($dataCache['tablet'])) {
                $data['tablet'] = $dataCache['tablet'];
            }
            if (isset($dataCache['mobile'])) {
                $data['mobile'] = $dataCache['mobile'];
            }
            if (isset($dataCache['xaxis'])) {
                $data['xaxis'] = $dataCache['xaxis'];
            }
        }
        $this->response->setOutput(json_encode($data));
    }


    // CHART MARKETPLACE
    public function chartMarketplace() {
        $this->chargeDefaults();
        $cache = new CacheFile();

        $data = array();
        $hasValue = array();

        $range = $this->request->get['range'] ?? Type_Period::Tp_Month;
        $ignoreCache = isset($this->request->get['ignoreCache']) && $this->request->get['ignoreCache'] === 'true';

        $cacheKey = self::CACHE_NAME_CHART . self::NAME_CHART_MARKETPLACE . $range;
        $dataCache = $cache->get($cacheKey);

        foreach (Type_MarketplaceInt::getEnumList() as $key => $value) {
            $data[$key]['label'] = $value;
        }

        if (!$dataCache || $ignoreCache) {
            $result = $this->processChart($range, self::METHOD_MARKETPLACE, self::TIPO_MARKETPLACE, 'marketplace', 'total_marketplace');
            foreach (Type_MarketplaceInt::getEnumList() as $key => $value) {
                $data[$key]['data'] = $result['data'][$key]['data'];
            }
            $data['xaxis'] = $result['data']['xaxis'];
            $hasValue = $result['hasValue'];

            if ($dataCache) {
                $cache->delete($cacheKey);
                $dataCache = $cache->get($cacheKey);
            }

            $dataCacheNew = [
                'data' => $data,
                'hasvalue' => $hasValue
            ];

            $dataCacheNew['text_refresh_graph_time'] = date('d/m/Y H:i:s');

            if ($range != 'customizable') {
                $cache->set($cacheKey, $dataCacheNew, 3600); // 1 hora
            }
        } else {

            foreach (Type_MarketplaceInt::getEnumList() as $key => $value) {
                if (isset($dataCache['data'][$key]['data'])) {
                    $data[$key]['data'] = $dataCache['data'][$key]['data'];
                }
            }
            if (isset($dataCache['data']['xaxis'])) {
                $data['xaxis'] = $dataCache['data']['xaxis'];
            }
            if (isset($dataCache['hasvalue'])) {
                $hasValue = $dataCache['hasvalue'];
            }
        }

        $dataJson = array();
        if ($hasValue) {
            $contador = 1;
            foreach ($data as $key => $value) {
                if (in_array($key, $hasValue, true)) {
                    $dataJson[$contador] = $data[$key];
                    $contador++;
                }
            }
        } else {
            $dataJson[1] = $data[1];
            $dataJson[1]['label'] = "Nenhuma venda de marketplace";
        }
        $dataJson['xaxis'] = $data['xaxis'];

        $this->response->setOutput(json_encode($dataJson));
    }


    // CHART SALES CHANNEL
    public function chartSalesChannel() {
        $this->chargeDefaults();
        $cache = new CacheFile();

        $data = array();
        $hasValue = array();

        $range = $this->request->get['range'] ?? Type_Period::Tp_Month;
        $ignoreCache = isset($this->request->get['ignoreCache']) && $this->request->get['ignoreCache'] === 'true';

        $cacheKey = self::CACHE_NAME_CHART . self::NAME_CHART_SALES_CHANNEL . $range;
        $dataCache = $cache->get($cacheKey);

        foreach (Type_OrigemSistema::getEnumList() as $key => $value) {
            $data[$key]['label'] = $value;
        }

        if (!$dataCache || $ignoreCache) {
            $result = $this->processChart($range, self::METHOD_SALES_CHANNEL, self::TIPO_ORIGEM_SISTEMA, 'origem', 'total_origem');
            foreach (Type_OrigemSistema::getEnumList() as $key => $value) {
                $data[$key]['data'] = $result['data'][$key]['data'];
            }
            $data['xaxis'] = $result['data']['xaxis'];
            $hasValue = $result['hasValue'];

            if ($dataCache) {
                $cache->delete($cacheKey);
                $dataCache = $cache->get($cacheKey);
            }

            $dataCacheNew = [
                'data' => $data,
                'hasvalue' => $hasValue
            ];

            $dataCacheNew['text_refresh_graph_time'] = date('d/m/Y H:i:s');

            if ($range != 'customizable') {
                $cache->set($cacheKey, $dataCacheNew, 3600); // 1 hora
            }
        } else {

            foreach (Type_OrigemSistema::getEnumList() as $key => $value) {
                if (isset($dataCache['data'][$key]['data'])) {
                    $data[$key]['data'] = $dataCache['data'][$key]['data'];
                }
            }
            if (isset($dataCache['data']['xaxis'])) {
                $data['xaxis'] = $dataCache['data']['xaxis'];
            }
            if (isset($dataCache['hasvalue'])) {
                $hasValue = $dataCache['hasvalue'];
            }
        }

        $app_status = (int)$this->model_sale_order->getOrderApp();
        $marketplace_status = array_filter(array(
            $this->config->get('skyhub_status'),
            $this->config->get('mercadolivre_status'),
            $this->config->get('shopee_status')
        ));

        $dataJson = array();
        if ($hasValue) {
            $contador = 1;
            foreach ($data as $key => $value) {
                if (($key !== 'xaxis') and
                    ($key !== Type_OrigemSistema::Tp_Marketplace or $marketplace_status) and
                    ($key !== Type_OrigemSistema::Tp_App or $app_status)) {
                    $dataJson[$contador] = $data[$key];
                    $contador++;
                }
            }
        } else {
            $dataJson[1] = $data[1];
            $dataJson[1]['label'] = "Nenhuma venda encontrada";
        }

        $dataJson['xaxis'] = $data['xaxis'];

        $this->response->setOutput(json_encode($dataJson));
    }


    //  NOVO GRAFICO
    public function chartCustom() {

        $this->language->load('common/home');
        $this->load->model('sale/order');
        $this->load->type('tipocomum');
        $this->load->type('tipofuturaserver');

        $json = [
            'order' => [],
            'xaxis' => [],
            'label_custom' => $this->language->get('text_order_custom')
        ];

        $start_date = DateTime::createFromFormat('d/m/Y', $this->request->get['start_date']);
        $end_date = DateTime::createFromFormat('d/m/Y', $this->request->get['end_date']);   

        if (!$start_date || !$end_date) {
            // define o mes atual como padrao se as datas nao forem definidas
            $start_date = new DateTime(date('Y-m-01'));
            $end_date = new DateTime(date('Y-m-t'));
        }
        
        // converte as datas para objetos DateTime
        $currentDate = clone $start_date;
        $endDate = clone $end_date;
        $order_data = [];

        while ($currentDate <= $endDate) {
            $dateString = $currentDate->format('Y-m-d');
            $total = $this->model_sale_order->getValueByCustomRange($dateString) ?: 0; // se nao tiver vendas define como 0
            $order_data[] = ['date' => $dateString, 'total' => $total];
            $currentDate->modify('+1 day');
        }

        if (!empty($order_data)) {
            $json['xaxis'] = array_column($order_data, 'date');
            $json['order'] = array_column($order_data, 'total');
        } else {
            $json['label_custom'] = 'Sem dados disponíveis para o período selecionado';
        }

        $this->response->setOutput(json_encode($json));
    }

    
    public function login() {
        $route = '';

        if (isset($this->request->get['route'])) {
            $part = explode('/', $this->request->get['route']);

            if (isset($part[0])) {
                $route .= $part[0];
            }

            if (isset($part[1])) {
                $route .= '/' . $part[1];
            }
        }

        $ignore = array(
            'common/login',
            'common/forgotten',
            'common/reset'
        );

        if (!$this->user->isLogged() && !in_array($route, $ignore)) {
            return $this->forward('common/login');
        }

        if (isset($this->request->get['route'])) {
            $ignore = array(
                'common/login',
                'common/logout',
                'common/forgotten',
                'common/reset',
                'error/not_found',
                'error/permission'
            );

            $config_ignore = array();

            if ($this->config->get('config_token_ignore')) {
                $config_ignore = unserialize($this->config->get('config_token_ignore'));
            }

            $ignore = array_merge($ignore, $config_ignore);

            if (!in_array($route, $ignore) && (!isset($this->request->get['token']) || !isset($this->session->data['token']) || ($this->request->get['token'] != $this->session->data['token']))) {
                return $this->forward('common/login');
            }
        } else {
            if (!isset($this->request->get['token']) || !isset($this->session->data['token']) || ($this->request->get['token'] != $this->session->data['token'])) {
                return $this->forward('common/login');
            }
        }
    }

    public function permission() {
        if (isset($this->request->get['route'])) {
            $route = '';

            $part = explode('/', $this->request->get['route']);

            if (isset($part[0])) {
                $route .= $part[0];
            }

            if (isset($part[1])) {
                $route .= '/' . $part[1];
            }

            if(defined('PREFIX_NAME') && in_array(PREFIX_NAME, $part)){
                $route .= '/' . $part[2].'/'.$part[3];
            }

            $ignore = array(
                'common/home',
                'common/login',
                'common/logout',
                'common/forgotten',
                'common/reset',
                'common/notification',
                'common/user',
                'common/nav',
                'user/trocasenha',
                'error/not_found',
                'error/permission',
                'extension/easyconfigure',
                'tool/error_log',
                'tool/error_log_mercadolivre',
                'common/adsbanner',
                'common/manual',
                'marketplace/Marketplacecalls',
                'marketplace/marketprice',
            );
             
            if (!in_array($route, $ignore) && !$this->user->hasPermission('access', $route)) {
                return $this->forward('error/permission');
            }
        }
    }
 
    public function updateDashboard($json=true) {
        // Pedidos     
        $filter_total_order = array(
            'filter_order_status_id' => (int)$this->config->get('config_complete_status_id'),
            'filter_status_futuraserver' => true
        );

        $filter_order = array(
             'filter_order_status_id' => (int)$this->config->get('config_complete_status_id'),
             'filter_date_added_between' => true,
             'filter_status_futuraserver' => true
         );

        //  ------------- pedidos --------------
        $this->load->model('sale/order');
        $data = [];
        $totalOrders = $this->model_sale_order->getTotalOrders($filter_total_order);
        $newOrders = $this->model_sale_order->getTotalOrders($filter_order);

        $order_data = array(
            'total_order' => $totalOrders,
            'total_order_year' => $newOrders
        );

        $data = array_merge($data, $order_data);


        //  ------------- vendas --------------
        $this->load->model('sale/order');
        $totalSales = $this->model_sale_order->getTotalSales();
        $newSales = $this->model_sale_order->getTotalSalesByYear(date('Y')) ?? "0";

        $sales_data = array(
            'total_sale' => $totalSales,
            'total_sale_year' => $newSales
        );

        $data = array_merge($data, $sales_data);


        //  ------------- ticket médio --------------
        $this->load->model('sale/order');
        $totalAverage = $this->model_sale_order->getAverageSalesLast12Months();

        $ticket_data = array(
            'average_sale' => $totalAverage,
        );

        $data = array_merge($data, $ticket_data);


        //Produtos
        $filter_product = array(
            'filter_data_replicacao_ecommerce' => true
        );
        
        // ------------- produtos --------------
        $this->load->model('catalog/product');
        $totalProducts = $this->model_catalog_product->getTotalProducts();
        $newProducts = $this->model_catalog_product->getTotalProducts($filter_product);

        $product_data = array(
            'total_product' => $totalProducts,
            'total_product_year' => $newProducts
        );

        $data = array_merge($data, $product_data);


        $filter_customer = array(
            'filter_approved' => Type_Status::Tp_Habilitado,
            'filter_date_added_between' => true
        );


        // ------------- clientes ----------------
        $this->load->model('sale/customer');
        $totalCustomers = $this->model_sale_customer->getTotalCustomers();
        $newCustomers = $this->model_sale_customer->getTotalCustomers($filter_customer);

        $customer_data = array(
            'total_customer' => $totalCustomers,
            'total_customer_year' => $newCustomers
        );

        $data = array_merge($data, $customer_data);


        // ------------- clientes online ----------------
        $this->load->dmodel('tool/online');
        $this->dmodel_tool_online->cleanonline();

        $this->load->model('report/online');
        $customer_online = $this->model_report_online->getTotalCustomersOnline();
        date_default_timezone_set('America/Sao_Paulo');
        $hour = date("H:i");

        $online_customer_data = array(
          'total_customer_online' => $customer_online,
          'customers_online_last_refresh' => $hour
        );
      
        $data = array_merge($data, $online_customer_data);
             
        $language = $this->language->load('common/home');


        $info['total_order_year'] = sprintf($language['total_order_year'], ($data['total_order_year']));

        $info['total_sale'] = $this->currency->format($data['total_sale'], $this->config->get('config_currency'));    
   
        $info['total_sale_year'] = sprintf($language['total_sale_year'], $this->currency->format($data['total_sale_year'], $this->config->get('config_currency')));        

        $info['average_sale'] = $this->currency->format($data['average_sale'], $this->config->get('config_currency'));       

        $info['text_last_12_months'] = sprintf($language['text_last_12_months']);

        $info['total_product_year'] = sprintf($language['total_product_year'], ($data['total_product_year']));

        $info['total_customer_year'] = sprintf($language['total_customer_year'], ($data['total_customer_year']));

        $info['customers_online_last_refresh'] = $language['text_last_refresh'] . ' ' . date("H:i");

        $data = array_merge($data, $info); 
        
        if ($json) {
            return $this->response->setOutputJson($data);
        } else {
            return $data;
        }
    }


    public function Version(){

        $json = array();

        $this->language->load('common/home');
        $this->load->model('setting/efutura');

        $this->model_setting_efutura->updateVersion();

        $json['success'] = true;

        $this->response->setOutput(json_encode($json));

    }

    public function last_sales_order() {
        $this->load->model('sale/order');
        $this->load->type('tipofuturaserver');
    
        $language = $this->language->load('common/home');
        $this->data = array_merge($this->data, $language);
    
        $proccess_status = (isset($this->request->get['proccess_status']) && $this->request->get['proccess_status'] !== '*') ? $this->request->get['proccess_status'] : '';
        $this->data['linkFilterProcessVenda'] = $this->url->link('sale/order', 'token=' . $this->session->data['token'] . '&filter_order_process_status=' . $proccess_status, 'SSL');
    
        $this->data['contrlProcVenda'] = false;
    
        if($this->config->get('processo_venda_status') == Type_DsimDnao::Tp_Sim){
            foreach(Type_ContrlProcVenda::getEnumlist() as $key => $value){
                $contrlProcVenda[] = array(
                    'key'      => $key,
                    'value'    => $value,
                    'selected' => ftr_geral::isSelected($key, $proccess_status)
                );
            }
            $this->data['contrlProcVenda'] = $contrlProcVenda;
        }
    
        $this->data['orders'] = array();
    
        $data = array(
            'sort'  => 'o.date_added',
            'order' => 'DESC',
            'start' => 0,
            'limit' => 12,
            'filter_order_process_status' => ($proccess_status === '') ? null : $proccess_status
        );
    
        $results = $this->model_sale_order->getOrders($data);
    
        foreach ($results as $result) {
            $this->data['orders'][] = array(
                'order_id'   => $result['order_id'],
                'customer'   => $result['customer'],
                'status'     => $result['status'],
                'date_added' => date($this->language->get('date_format_short'), strtotime($result['date_added'])),
                'total'      => $this->currency->format($result['total'], $result['currency_code'], $result['currency_value']),
                'href'       => $this->url->link('sale/order/info', 'token=' . $this->session->data['token'] . '&order_id=' . $result['order_id'], 'SSL')
            );
        }
    
        $this->response->setOutput($this->render('common/last_sales_order'));
    }

    public function loadTimeCache() {
        $range = $this->request->get['range'] ?? Type_Period::Tp_Month;

        $this->load->library('cacheFile');
        $cache = new CacheFile();
        $files = glob(DIR_CACHE . self::CACHE_NAME_CHART . self::NAME_CHART_TOTAL_ORDER . $range .'.*');
        
        $time = '';

        if ($files) {
            foreach ($files as $file) {
                $filename = basename($file);
                $chave = str_replace('cache.','', $filename);
                $pos = strpos($chave,'.');
                $chave = substr($chave,0,$pos);

                $data = $cache->get($chave);
                if (isset($data['text_refresh_graph_time'])) {
                    if ($time == '' || strtotime($time) > strtotime($data['text_refresh_graph_time'])) {
                        $time = $data['text_refresh_graph_time'];
                    }
                }
            }
        }
        $language = $this->language->load('common/home');
        if ($time == '') {
            $time = date('d/m/Y H:i:s');
        }
        switch ($range) {
            case Type_Period::Tp_Day:
                $periodo = 'Hoje';
                break;
            case Type_Period::Tp_Week:
                $periodo = 'Esta semana';
                break;
            case Type_Period::Tp_Month:
                $periodo = 'Este mês';
                break;
            case Type_Period::Tp_Year:
                $periodo = 'Este ano';
                break;
        }
        $info['text_refresh_graph_time'] = sprintf($language['text_refresh_graph_time'], $time);
        $info['text_refresh_graph_time'] .= ' (período: '. $periodo . ')';

        echo json_encode($info);
    }

    private function chargeDefaults() {
        $this->language->load('common/home');
        $this->load->model('sale/order');
        $this->load->type('tipocomum');
        $this->load->type('tipofuturaserver');
        $this->load->library('cacheFile');
    }

    private function getResultsByRange($range, $methodPrefix, $param) {
        switch ($range) {
            case Type_Period::Tp_Day:
                if (in_array($methodPrefix, [self::METHOD_CHART, self::METHOD_DEVICE])) {
                    return $this->model_sale_order->{$methodPrefix . 'ByHour'}($param);
                } else {
                    return $this->model_sale_order->{$methodPrefix . 'ByDay'}($param);
                }
            case Type_Period::Tp_Week:
                return $this->model_sale_order->{$methodPrefix . 'ByWeek'}($param);
            case Type_Period::Tp_Month:
                return $this->model_sale_order->{$methodPrefix . 'ByMonth'}($param);
            case Type_Period::Tp_Year:
                return $this->model_sale_order->{$methodPrefix . 'ByYear'}($param);
            default:
                return [];
        }
    }

    private function processChart($range, $methodPrefix, $tipoClass = null, $tipo = null, $tipoTotal = null) {
        $results = [];
        $browser = new BrowserInfo();
        switch ($range) {
            case Type_Period::Tp_Day:
                if (in_array($methodPrefix, [self::METHOD_CHART,self::METHOD_DEVICE])) {
                    for ($i = 0; $i < 24; $i++) {
                        if ($methodPrefix == self::METHOD_CHART) {
                            $results['data']['order'][]    = $this->getResultsByRange($range, $methodPrefix,$i);
                        }
                        if ($methodPrefix == self::METHOD_DEVICE) {
                            $responses = $this->getResultsByRange($range, $methodPrefix, $i);
                            $devices = $this->mountGraphDevice($responses, $browser);
                            $results['data']['desktop'][$i] = $devices['data']['desktop'][0];
                            $results['data']['tablet'][$i]  = $devices['data']['tablet'][0];
                            $results['data']['mobile'][$i]  = $devices['data']['mobile'][0];
                        }
                        $results['data']['xaxis'][] = date('H', mktime($i, 0, 0, date('n'), date('j'), date('Y')));
                    }
                }
                if (in_array($methodPrefix, [self::METHOD_MARKETPLACE, self::METHOD_SALES_CHANNEL])) {
                    $responses = $this->getResultsByRange($range, $methodPrefix, date('Y-m-d'));
                    $marketplace = $this->mountGraphMarketplace($responses, 'hora',  24, $tipoClass, $tipo, $tipoTotal);
                    $results['data'] = $marketplace['data'];
                    $results['hasValue'] = $marketplace['hasValue'];
                    for ($hour = 0; $hour < 24; $hour++) {
                        $results['data']['xaxis'][] = date('H', mktime($hour, 0, 0, date('n'), date('j'), date('Y')));
                    }
                }
                break;
            case Type_Period::Tp_Week:
                if (in_array($methodPrefix, [self::METHOD_CHART,self::METHOD_DEVICE])) {
                    $date_start = strtotime('-' . date('w') . ' days');
                    for ($i = 0; $i < 7; $i++) {
                        $date = date('Y-m-d', $date_start + ($i * 86400));
                        if ($methodPrefix == self::METHOD_CHART) {
                            $results['data']['order'][]    = $this->getResultsByRange($range, $methodPrefix, $date);
                        }
                        if ($methodPrefix == self::METHOD_DEVICE) {
                            $responses = $this->getResultsByRange($range, $methodPrefix, $date);
                            $devices = $this->mountGraphDevice($responses, $browser);
                            $results['data']['desktop'][$i] = $devices['data']['desktop'][0];
                            $results['data']['tablet'][$i]  = $devices['data']['tablet'][0];
                            $results['data']['mobile'][$i]  = $devices['data']['mobile'][0];
                        }
                    }
                }
                if (in_array($methodPrefix, [self::METHOD_MARKETPLACE, self::METHOD_SALES_CHANNEL])) {
                    $responses = $this->getResultsByRange($range, $methodPrefix, date('Y-m-d'));
                    $marketplace = $this->mountGraphMarketplace($responses, 'dia', 7, $tipoClass, $tipo, $tipoTotal);
                    $results['data'] = $marketplace['data'];
                    $results['hasValue'] = $marketplace['hasValue'];
                }
                $results['data']['xaxis'] =array(
                    0 => 'Domingo',
                    1 => 'Segunda-feira',
                    2 => 'Terça-feira',
                    3 => 'Quarta-feira',
                    4 => 'Quinta-feira',
                    5 => 'Sexta-feira',
                    6 => 'Sábado'
                );
                break;
            case Type_Period::Tp_Month:
                if (in_array($methodPrefix, [self::METHOD_CHART,self::METHOD_DEVICE])) {
                    for ($i = 1; $i <= date('t'); $i++) {
                        $date = date('Y') . '-' . date('m') . '-' . $i;
                        if ($methodPrefix == self::METHOD_CHART) {
                            $results['data']['order'][] = $this->getResultsByRange($range,$methodPrefix, $date);
                        }
                        if ($methodPrefix == self::METHOD_DEVICE) {
                            $responses = $this->getResultsByRange($range, $methodPrefix,$date);
                            $index = $i -1;
                            $devices = $this->mountGraphDevice($responses, $browser);
                            $results['data']['desktop'][$index] = $devices['data']['desktop'][0];
                            $results['data']['tablet'][$index]  = $devices['data']['tablet'][0];
                            $results['data']['mobile'][$index]  = $devices['data']['mobile'][0];
                        }
                        $results['data']['xaxis'][] = date('j', strtotime($date));
                    }
                }
                if (in_array($methodPrefix, [self::METHOD_MARKETPLACE, self::METHOD_SALES_CHANNEL])) {
                    $results['hasValue'] = [];
                    $responses = $this->getResultsByRange($range, $methodPrefix, date('Y-m-d'));
                    $marketplace = $this->mountGraphMarketplace($responses, 'dia', date('t'), $tipoClass, $tipo, $tipoTotal, 1);
                    $results['data'] = $marketplace['data'];
                    $results['hasValue'] = $marketplace['hasValue'];
                    for ($dia = 1; $dia <= date('t'); $dia++) {
                        $results['data']['xaxis'][] = date('j', strtotime(date('Y') . '-' . date('m') . '-' . $dia));
                    }
                }
                break;
            case Type_Period::Tp_Year:
                if (in_array($methodPrefix, [self::METHOD_CHART,self::METHOD_DEVICE])) {
                    for ($i = 1; $i <= 12; $i++) {
                        if ($methodPrefix == self::METHOD_CHART) {
                            $results['data']['order'][] = $this->getResultsByRange($range,$methodPrefix, $i);
                        }
                        if ($methodPrefix == self::METHOD_DEVICE) {
                            $responses = $this->getResultsByRange($range, $methodPrefix,$i);
                            $index = $i -1;
                            $devices = $this->mountGraphDevice($responses, $browser);
                            $results['data']['desktop'][$index] = $devices['data']['desktop'][0];
                            $results['data']['tablet'][$index]  = $devices['data']['tablet'][0];
                            $results['data']['mobile'][$index]  = $devices['data']['mobile'][0];
                        }
                    }
                }
                if (in_array($methodPrefix, [self::METHOD_MARKETPLACE, self::METHOD_SALES_CHANNEL])) {
                    $results['hasValue'] = [];
                    $responses = $this->getResultsByRange($range, $methodPrefix, date('Y-m-d'));
                    $marketplace = $this->mountGraphMarketplace($responses, 'mes', 13, $tipoClass, $tipo, $tipoTotal, 1);
                    $results['data'] = $marketplace['data'];
                    $results['hasValue'] = $marketplace['hasValue'];
                }
                $results['data']['xaxis'] =array(
                    0 => 'Janeiro',
                    1 => 'Fevereiro',
                    2 => 'Março',
                    3 => 'Abril',
                    4 => 'Maio',
                    5 => 'Junho',
                    6 => 'Julho',
                    7 => 'Agosto',
                    8 => 'Setembro',
                    9 => 'Outubro',
                    10 => 'Novembro',
                    11 => 'Dezembro'
                );
                break;
            default:
                $results = [];
        }
        return $results;
    }

    private function mountGraphDevice($responses, $browser) {
        $results = array();
        if ($responses) {
            foreach ($responses as $response) {
                if($response['device']==$browser::IsDeskTop){
                    $results['data']['desktop'][0] = $response['total_device'];
                } else {
                    if (!isset($results['data']['desktop'][0])) {
                        $results['data']['desktop'][0] = 0;
                    }
                } 
                if($response['device']==$browser::IsTablet){
                    $results['data']['tablet'][0] = $response['total_device'];
                } else {
                    if (!isset($results['data']['tablet'][0])) {
                        $results['data']['tablet'][0] = 0;
                    }
                }
                if($response['device']==$browser::IsMobile){
                    $results['data']['mobile'][0] = $response['total_device'];
                } else {
                    if (!isset($results['data']['mobile'][0])) {
                        $results['data']['mobile'][0] = 0;
                    }
                }
            }
        }else{
            $results['data']['desktop'][] = 0 ;
            $results['data']['tablet'][]  = 0 ;
            $results['data']['mobile'][]  = 0 ;
        }
        return $results;
    }

    private function mountGraphMarketplace($responses, $campo, $limit, $tipoClass = null, $tipo = null, $tipoTotal = null, $inital = 0) {
        $results = [];
        $results['hasValue'] = [];
        foreach ($tipoClass::getEnumList() as $key => $value) {
            for ($iterator = $inital; $iterator < $limit; $iterator++) {
                if ($responses) {
                    $response = array_filter($responses, function ($reg) use ($iterator, $key, $campo, $tipo) {
                        return $reg[$campo] == $iterator && $reg[$tipo] == $key;
                    });
                } else  {
                    $response = [];
                }
                if (!empty($response)) {
                    $results['data'][$key]['data'][] = (float)current($response)[$tipoTotal];
                    if (!in_array($key, $results['hasValue'])) {
                        $results['hasValue'][] = $key;
                    }
                } else {
                    $results['data'][$key]['data'][] = 0;
                }
            }
        }
        return $results;
    }

}
