<?php

class ControllerCommonTracking extends Controller
{

    public function index()
    {

        $this->load->dmodel('setting/task');

        $this->ftrgeralregistry->permissaoAcessoUrl($this->dmodel_setting_task->getTaskByType(Type_TaskUrl::Tp_TaskCorreioRastreio));

        if ($this->config->get('correios_tracking_status')) {

            if (isset($this->request->get['order_id'])) {
                ini_set("default_socket_timeout", 10);
            }

            $this->load->type('tipocomum');
            $this->load->dmodel('tracking/tracking');
            $this->load->dmodel('mercadolivre/meliproduto');
            $this->load->helper('ftr_geral');

            $result = $this->dmodel_setting_task->getTaskByType(['type' => Type_TaskUrl::Tp_TaskCorreioRastreio]);
            $time = (($result['time_execution'] * 60) - 60);

            $dataTask = array(
                'date_last_acting' => $this->db->dataAtual(),
                'type' => Type_TaskUrl::Tp_TaskCorreioRastreio
            );
            $this->dmodel_setting_task->editDateTaskByType($dataTask);

            $minutos = $time / 60;
            $tempoLimite = (new DateTime($this->db->dataAtual()))->add(new DateInterval('PT' . $minutos . 'M'));

            $json = array();

            $tracking_date_att = $this->db->dataAtual();

            $data = array(
                'order_id' => (isset($this->request->get['order_id'])) ? $this->request->get['order_id'] : false,
                'origem_pedido' => Type_OrigemSistema::Tp_Ecommerce,
                'date_added_betwenn' => '(DATE(o.date_added) BETWEEN  CURDATE() - INTERVAL 60 DAY AND DATE(NOW()))',
                'tracking_complete' => Type_Status::Tp_Desabilitado,
                'sort' => 'ot.tracking_date_att',
                'order' => 'DESC',
                'start' => 0,
                'limit' => 20
            );

            $trackings = $this->dmodel_tracking_tracking->getTrackingsEcommerce($data);

            if ($trackings) {
                $trackingData = array();
                foreach ($trackings as $key => $tracking) {
                    $shipping_code = ftr_geral::removeString($tracking['shipping_code'], '.');
                    $trackingData[$shipping_code][$key] = ['tracking_code' => trim($tracking['tracking_code']), 'order_id' => $tracking['order_id']];
                }

                if ($trackingData) {
                    foreach ($trackingData as $key => $tracking) {
                        $status = $this->dmodel_tracking_tracking->verifyStatus($key);

                        if ($status) {
                            $configTracking = $this->dmodel_tracking_tracking->getConfigTracking($key);
                            try {
                                $trackingInstance = AbstractFactoryTrackingMethod::getInstance($key);

                                $trackingInstance->autentication(['usuario' => $configTracking['usuario'], 'senha' => $configTracking['senha']]);

                                $trackingInstance->getObjectTracking(implode('', array_map(function ($array) {
                                    return $array['tracking_code'];
                                }, $tracking)));

                                $dataTracking = array();
                                foreach ($tracking as $key => $value) {
                                    $dataTracking['tracking_code'][$key] = $value['tracking_code'];
                                    $dataTracking['order_id'][$value['order_id']] = $value['tracking_code'];
                                }

                                $events = $trackingInstance->getEvents($dataTracking);

                                if ($events || array_filter(array_values($events))) {
                                    $events['tracking_date_att'] = $tracking_date_att;

                                    $this->dmodel_tracking_tracking->addTrackingEcommerceEvent($events, $key);

                                    $json['success'] = 'Status de envio atualizado com sucesso. A página será recarregada em breve!';

                                } else {
                                    $json['error'] = 'Erro ao atualizar status de envio. Objeto não encontrado na base dos correios!';
                                }


                            } catch (Exception $e) {
                                $error_message = $e->getMessage();
                                if(str_contains(strtolower($error_message), 'usuário e/ou senha inválidos')){
                                    $this->db->query("UPDATE oc_setting SET `value` = '0' WHERE `group` = 'correios' AND `key` = 'correios_tracking_status' AND store_id = '0'");
                                    $this->db->query("INSERT INTO oc_setting SET store_id = '0', `group` = 'correios', `key` = 'correios_invalid_credential', `value` = '1'");
                                }

                                $trackingInstance->setErrorLog($this->config->get('config_error_filename'), $shipping_code, $e->getMessage());
                                $json['error'] = 'Erro ao atualizar status de envio. Tente novamente mais tarde ou consulte pelo site da transportadora!';
                                unset($trackingInstance);
                            }
                        }

                        if (($tempoLimite) && (new DateTime($this->db->dataAtual()) > $tempoLimite)){
                          break;
                        }
                    }

                }

            }

            if (isset($this->request->get['order_id'])) {
                $this->response->setOutputJson($json);
            }

        } else {
            throw new Exception('Configuração de verificação de atualização dos status de envio dos pedido que utlizarem correios esta desabilitada!');
        }

        // Melhor envio - alterar status de pedidos entregues
        if (($this->config->get('melhorenvio_status')) && ($this->config->get('melhorenvio_tracking_status'))) {

            if (isset($this->request->get['order_id'])) {
                ini_set("default_socket_timeout", 10);
            }

            $this->load->type('tipocomum');
            $this->load->type('tipofrete');
            $this->load->dmodel('shipping/shippinglabel');
            $this->load->dmodel('checkout/order');
            $this->load->helper('ftr_geral');

            $result = $this->dmodel_setting_task->getTaskByType(['type' => Type_TaskUrl::Tp_TaskCorreioRastreio]);
            $time = (($result['time_execution'] * 60) - 60);
            ini_set('max_execution_time', $time);

            $dataTask = array(
                'date_last_acting' => $this->db->dataAtual(),
                'type' => Type_TaskUrl::Tp_TaskCorreioRastreio
            );
            $this->dmodel_setting_task->editDateTaskByType($dataTask);

            $json = array();

            $tracking_date_att = $this->db->dataAtual();

            $data = array(
                'order_id' => (isset($this->request->get['order_id'])) ? $this->request->get['order_id'] : false,
                'date_added_betwenn' => '(DATE(o.date_added) BETWEEN  CURDATE() - INTERVAL 60 DAY AND DATE(NOW()))',
                'shipping_code' => Type_ShippingCode::Tp_ShippingMelhorEnvio,
                'label_complete' => Type_Status::Tp_Desabilitado,
                'sort' => 'sl.date_att',
                'order' => 'DESC',
                'start' => 0,
                'limit' => 20
            );

            $labels = $this->dmodel_shipping_shippinglabel->getShippingLabelsByFields($data);

            if ($labels) {

                try{
                    $labelsTrackings = $this->melhorenvio->getTrackingInfo(array_column($labels, 'shipping_label'));
                } catch(Exception $e){
                    $this->log->write('Rota: common/tracking - Error: Não foi possível obter as informações de rastreio do melhor envio! - ' . $e->getMessage());
                    return;
                }

                $orderLabels = array();
                foreach ($labels as $key => $label) {
                    $orderLabels[$label['order_id']]['labels'][] = $label['shipping_label'];
                }

                foreach ($labels as $key => $label) {
                    try {
                        $labelTracking = $labelsTrackings->{$label['shipping_label']};

                        if ($labelTracking) {
                            if (!empty($labelTracking->delivered_at)) {
                                // teste
//                if (!empty($labelTracking->posted_at)){
//                atualiza a etiqueta
                                $this->dmodel_shipping_shippinglabel->setShippingLabelComplete($label['order_id'], $label['shipping_code'], $label['shipping_label']);

                                $json['success'] = 'Status de envio atualizado com sucesso. A página será recarregada em breve!';
                            }
                        } else {
                            $json['error'] = 'Erro ao atualizar status do pedido: ' . $label['order_id'] . '. Objeto: ' . $label['shipping_label'] . ' não encontrado na base do Melhor Envio!';
                        }


                    } catch (Exception $e) {
                        $trackingInstance->setErrorLog($this->config->get('config_error_filename'), $label['shipping_label'], $e->getMessage());
                        $json['error'] = 'Erro ao atualizar status de envio. Tente novamente mais tarde ou consulte pelo site da transportadora!';
                        unset($trackingInstance);
                    }
                }

//        atualiza o status dos pedido
                $orders = array_unique(array_column($labels, 'order_id'));
                $ordersInfo = $this->dmodel_shipping_shippinglabel->getOrdersShippingLabelInfo(array_values($orders));

                $dataStatus = array(
                    'order_status_id' => $this->config->get('melhorenvio_tracking_delivered_status'),
                    'cometario_html' => false,
                    'comment' => ''
                );
                foreach ($ordersInfo as $orderInfo) {
                    if (($orderInfo['complete'] == Type_Status::Tp_Habilitado)
                        && ($orderInfo['order_status_id'] != $this->config->get('melhorenvio_tracking_delivered_status'))) {
                        $this->dmodel_checkout_order->addOrderHistory($orderInfo['order_id'], $dataStatus);
                    }
                }

            }

            if (isset($this->request->get['order_id'])) {
                $this->response->setOutputJson($json);
            }
        } else {
            throw new Exception('Configuração de rastreio do MelhorEnvio esta desabilitada!');
        }

    }
}
