<?php

use Win7\App;
use Win7\Phone\Controller\CallController;
use Win7\Phone\Manager\CallManager;

require_once (__DIR__ . "/Banco_Dados.php");
require_once (__DIR__ . "/Banco_Dados_Fone.php");
require_once (__DIR__ . "/Banco_Dados_Leads.php");
require_once (__DIR__ . "/Filtro.php");
require_once (__DIR__ . "/Mascara.php");

/* Classe responsável por controlar o sistema do Win7 Fone */
class Sistema_Win7Fone{
	public $bd;
	/** @var \Banco_Dados */
	public $bd_sys;
	public $id;

	function __construct($id, $bd){
		$this->bd = new Banco_Dados_Fone();
		$this->id = $id;
		$this->bd_sys = $bd;
	}

	/* Obtém a lista de ramais */
	function obter_nomes(){
		$dados = $this->bd_sys->executar("SELECT NU_VONOID, TXT_NOME FROM TBL_VONOIDS WHERE NU_IDCLIENTE = :id", array(":id" => $this->id), Banco_Dados::FETCH_ALL);

		// Monta-se aqui a array associativa que contém cada nome associado a um id
		$ids = array();
		if ($this->bd_sys->quantidade() > 0) {
		    foreach($dados as $row){
		        $ids[strval($row['NU_VONOID'])] = $row['TXT_NOME'];
		    }
		}

		return $ids;
	}

	/* Obtém uma array com os valores das ligações */
	function obter_valores($valor_ligacoes){
		$valor_ligacoes = explode(",", $valor_ligacoes);
		for($i = 0;$i < count($valor_ligacoes);$i++){
			$val = $valor_ligacoes[$i];
			$valor_ligacoes[$i] = floatval($val);
		}
		return $valor_ligacoes;
	}

	/* Ajusta o filtro para seguir a data mínima e máxima especificada no admin */
	function corrigir_filtro($filtro, $inicio, $fim){
		if(!empty($inicio)){
			$dtinicio = str_replace(array('/'), '-', $inicio);
			$dtinicio = new DateTime($dtinicio);
			$dtinicio_str = $dtinicio->format('Y-m-d 00:00:00-03');
			$dtinicio = strtotime($dtinicio_str);
			$dtinicio_pers = strtotime($filtro[0]);
			if($dtinicio > $dtinicio_pers)
				$filtro[0] = $dtinicio_str;
		}

		if(!empty($fim)){
			$dtfinal = str_replace(array('/'), '-', $fim);
			$dtfinal = new DateTime($dtfinal);
			$dtfinal_str = $dtfinal->format('Y-m-d 00:00:00-03');
			$dtfinal = strtotime($dtfinal_str);
			$dtfinal_pers = strtotime($filtro[0]);
			if($dtfinal < $dtfinal_pers)
				$filtro[1] = $dtfinal_str;
		}

		return $filtro;
	}

	/* Soma as durações de ligação que estão na array */
	function somar_duracoes($duracoes){
		$horas = 0;
		$minutos = 0;
		$segundos = 0;

		foreach($duracoes as $dur){
			$dur = explode(":", $dur);
			$segundos += intval($dur[2]);
			$minutos += intval($dur[1]);
			$horas += intval($dur[0]);
		}

		$minutos += intval($segundos / 60);
		$segundos = intval($segundos % 60);
		$horas += intval($minutos / 60);
		$minutos = intval($minutos % 60);
		return sprintf("%02d:%02d:%02d", $horas, $minutos, $segundos);
	}

    /**
     * Filtra o número especificado.
     * Retorna uma array contendo os índices:
     * - 0: número filtrado
     * - 1: se ele é número válido ou é um nome de ramal
     * - 2: se ele é celular ou fixo
     *
     * @param $numero
     * @param $display - nome de display do número caso seja ramal
     * @return array
     */
	function filtrarNumero($numero, $display = null){
        $numero_valido = 0;
        $tipo_numero = 0;

	    // Removemos os dois pontos e o que houve depois, caso tenha
        $posicaoDoisPontos = strpos($numero, ":");
        if(strpos($numero, ":") !== false){
            $numero = substr($numero, 0, $posicaoDoisPontos);
        }

        // Preparamos, nos seguintes IFs, o número de origem para exibição
        if(substr($numero, 0, 4 ) === "Ext."){ // O número de origem é um ramal?
            // Se o nome display foi configurado, refazemos a filtragem
            if($display != null){
                // Remove o número do ramal que está entre parênteses
                $numero = trim(preg_replace("/\([^)]+\)/", "", $display)); // Remove número do ramal entre parênteses
                $resultadoFiltragem = $this->filtrarNumero($numero);
                $numero = $resultadoFiltragem[0];
                $numero_valido = $resultadoFiltragem[1];
                $tipo_numero = $resultadoFiltragem[2];
            }
        }
        else if(is_numeric($numero)){ // O número de origem não é um ramal?
            $size = strlen($numero); // obtém o tamanho do número
            if($size == 11 & $numero[0] == "0"){ // Se tem tamanho 11 e começa com 0, é um número de tamanho 8 com DDD. Ex: 06199123432
                $primeiro_numero = $numero[3]; // Obtém o primeiro número do telefone
                $tipo_numero = $primeiro_numero == "9" ? 1 : 2; // Se começa com 9, é celular, senão é fixo
                $numero_valido = 1; // Marca o número como sendo válido
                $numero = Mascara::aplicar_mascara_telefone(substr($numero, 1, $size - 1)); // formata o número para exibição
            }
            else if($size == 12 & $numero[0] == "0"){ // Se tem tamanho 12 e começa com 0, é um número de tamanho 9 com DDD. Ex: 061999123432
                $primeiro_numero = $numero[3]; // Obtém o primeiro número do telefone
                $tipo_numero = $primeiro_numero == "9" ? 1 : 2; // Se começa com 9, é celular, senão é fixo
                $numero_valido = 1; // Marca o número como sendo válido
                $numero = Mascara::aplicar_mascara_telefone(substr($numero, 1, $size - 1)); // formata o número para exibição
            }
            else if(($size == 12 || $size == 13) & substr( $numero, 0, 2 ) == "55"){ // é um número no formato global. Ex: 5561993213567
                $primeiro_numero = $numero[4]; // Obtém o primeiro número do telefone
                $tipo_numero = $primeiro_numero == "9" ? 1 : 2; // Se começa com 9, é celular, senão é fixo
                $numero_valido = 1; // Marca o número como sendo válido
                $numero = Mascara::aplicar_mascara_telefone(substr($numero, 2, $size - 2)); // formata o número para exibição
            }
            else if($size == 8 || $size == 9){ // Se tem tamanho 8 ou 9, é o número sem DDD
                $primeiro_numero = $numero[0]; // Obtém o primeiro número do telefone
                $tipo_numero = $primeiro_numero == "9" ? 1 : 2;  // Se começa com 9, é celular, senão é fixo
                $numero_valido = 1; // Marca o número como sendo válido
                $numero = Mascara::aplicar_mascara_telefone($numero); // formata o número para exibição
            }
            else if($size == 10 || $size == 11){
                $primeiro_numero = $numero[2]; // Obtém o primeiro número do telefone
                $tipo_numero = $primeiro_numero == "9" ? 1 : 2;  // Se começa com 9, é celular, senão é fixo
                $numero_valido = 1; // Marca o número como sendo válido
                $numero = Mascara::aplicar_mascara_telefone($numero); // formata o número para exibição
            }
            else if($size >= 14){
                if(substr($numero,0,4) == "0055"){
                    $primeiro_numero = $numero[6]; // Obtém o primeiro número do telefone
                    $tipo_numero = $primeiro_numero == "9" ? 1 : 2;  // Se começa com 9, é celular, senão é fixo
                    $numero_valido = 1;
                    $numero = substr($numero,4,$size - 4);

                    if(substr($numero,0,2) == "00"){
                        $numero = substr($numero,2,$size - 2);
                    }
                    $numero = Mascara::aplicar_mascara_telefone($numero);
                }
            }
        }

        return array($numero, $numero_valido, $tipo_numero);
    }

	// Adiciona a ligação especificada à array de dados
	function adicionar_ligacao($adicionar, $nomes, $ramal, &$rows, &$total_gasto, $valor_ligacoes, $grafico = false){
		$qtd = count($adicionar); // Calcula a quantidade de caminhos da ligação
		$origem = $adicionar[0]['source_caller_id']; // Obtém o número de origem
		$destino = $adicionar[$qtd-1]['destination_caller_id']; // Obtém o número de destino
		$fila = $nomes[$ramal]; // Obtém o nome do ramal
		$id = $adicionar[0]['call_id']; // Obtém a ID da ligação

		// Obtém a duração do último caminho, para fins de cálculo do valor da ligação
		$duracao_final = empty($adicionar[$qtd-1]['talking_duration']) ? "00:00:00" : $adicionar[$qtd-1]['talking_duration'];

		// Filtra o número de origem
		$resultadoFiltragem = $this->filtrarNumero($origem, $adicionar[0]['source_display_name']);
		$numero_valido = $resultadoFiltragem[1];
		$origem = $resultadoFiltragem[0];

		// Filtra o número de destino
		$resultadoFiltragem = $this->filtrarNumero($destino, $adicionar[$qtd-1]['destination_caller_id']);
		$tipo_numero = $resultadoFiltragem[2];
		$destino = $resultadoFiltragem[0];

		$ligacao_final = end($adicionar);
		$atendida = $ligacao_final['answered'] == "t" ? "Atendida" : "Não Atendida"; // Verifica se a ligação foi atendida
		if($atendida == "Atendida"){
			$talking_dur = explode(":", $ligacao_final['talking_duration']);
			if(intval($talking_dur[2]) < 10 && intval($talking_dur[1]) == 0 && intval($talking_dur[0]) == 0){
				$atendida = "Não Atendida";
			}
		}

		// Calcula o tempo de ligação e o tempo de espera totais
		$duracao = array();
		$espera = array();
		foreach($adicionar as $segmento){
			$duracao[] = empty($segmento['talking_duration']) ? "00:00:00" : $segmento['talking_duration'];
			$espera[] = empty($segmento['ringing_duration']) ? "00:00:00" : $segmento['ringing_duration'];
		}
		$duracao = $this->somar_duracoes($duracao);
		$espera = $this->somar_duracoes($espera);

		// BEGIN: Calcula o valor da ligação com base na duração do último caminho
		$dur = explode(":", $duracao_final);
		$segundos = intval($dur[2]);
		$minutos = intval($dur[1]);
		$horas = intval($dur[0]);
		$val = 0;
		if(!is_array($valor_ligacoes) || empty($valor_ligacoes) || count($valor_ligacoes) < 2){
			$valor_ligacoes = array();
			$valor_ligacoes[] = 0;
			$valor_ligacoes[] = 0;
		}
		if($tipo_numero == 1){ // Se é número celular
			$val = $minutos * $valor_ligacoes[0]; // Múltiplica a quantidade de minutos pelo preço por minuto
			$val += $horas * 60 * $valor_ligacoes[0]; // Múltiplica a quantidade de hora vezes 60 pelo preço por minuto
			if($segundos > 0) $val += $valor_ligacoes[0]; // Se tem mais que 0 segundos, conta como um minuto inteiro para fins de cobrança
		}
		else if($tipo_numero == 2){ // Se é número fixo
			$val = $minutos * $valor_ligacoes[1]; // Múltiplica a quantidade de minutos pelo preço por minuto
			$val += $horas * 60 * $valor_ligacoes[1]; // Múltiplica a quantidade de hora vezes 60 pelo preço por minuto
			if($segundos > 0) $val += $valor_ligacoes[1]; // Se tem mais que 0 segundos, conta como um minuto inteiro para fins de cobrança
		}
		// Transforma-se abaixo o valor calculado em string
		if($val == 0)
			$valor = 'R$ 0,00';
		else{
			$total_gasto += $val;
			$valor = 'R$ ' . number_format($val,2);
			$valor = str_replace('.', ',', $valor);
		}
		// END: Calcula o valor da ligação com base na duração do último caminho

		// Obtém a data e horário da ligação
		$dataatual = strtotime($adicionar[0]['start_time']);
		if($dataatual > $rows[0]['data']) $rows[0]['data'] = $dataatual;  // vê se a data da ligação é a maior
		if($dataatual < $rows[0]['data2']) $rows[0]['data2'] = $dataatual;  // vê se a data da ligação é a menor

		$rows[] = array(
			'fonte' => $fila,
			'origem' => $origem,
			'destino' => $destino,
			'data' => ($grafico ? date("Y-m-d", $dataatual) : date("Y-m-d H:i:s", $dataatual)),
			'valor' => $valor,
			'duracao' => $duracao,
			'valido' => $numero_valido,
			'id' => $id,
			'atendida' => $atendida,
			'espera' => $espera,
			'duracaofinal' => $duracao_final
		);
	}

	// Adicionas as ligações que foram obtidas no banco à array de dados
	function adicionar_ligacoes($dados, &$ligacoes, &$rows, $ramal, $nomes, &$total_gasto, $valor_ligacoes, $grafico = false){
		date_default_timezone_set('America/Sao_Paulo');
		if(!in_array($ramal, $rows[0]['ids'])) $rows[0]['ids'][] = $ramal;
		$ultima_id = "-1";

		foreach($dados as $row){
			$id = $row['call_id'];

			if($id == $ultima_id){ // Se já existe a ID, adiciona o caminho à lista da ligação
				$ligacoes[$id][] = $row;
			}
			else if($ultima_id != "-1"){ // Se mudou de ligação, então adiciona a ligação antiga ao resultado
				$adicionar = $ligacoes[$ultima_id];
				$this->adicionar_ligacao($adicionar, $nomes, $ramal, $rows, $total_gasto, $valor_ligacoes, $grafico);
				$ultima_id = "-1";
			}

			if(!array_key_exists($id, $ligacoes)){
				$ligacoes[$id] = array();
				$ligacoes[$id][] = $row;
				$ultima_id = $id;
			}
		}

		if($ultima_id != "-1"){
			$adicionar = $ligacoes[$ultima_id];
			$this->adicionar_ligacao($adicionar, $nomes, $ramal, $rows, $total_gasto, $valor_ligacoes, $grafico);
		}

		$rows[0]['totalgasto'] = "R$ " . str_replace('.', ',', number_format($total_gasto,2));
	}
	/* Obtém os dados da ligação com a ID especificada */
	function obter_ligacao($id){
        App::initialize();
        $usarSistemaNovo = App::getConfig()->get('phone.usar_novo');

		if($usarSistemaNovo){
            $manager = App::getContainer()->get(CallManager::class);
            $dados = $manager->getDadosLigacao($id);

            if($dados === null){
                return -1;
            }
        } else{
            $dados = $this->bd->executar("SELECT * FROM cl_get_call_log_by_callid($1)", array($id), Banco_Dados::FETCH_ALL);

            if($this->bd->quantidade() == 0){
                return -1;
            }
        }


		return $this->processar_ligacao($dados);
	}

    // processar os dados da ligação obtidos do banco de dados
    function processar_ligacao($dados){
        $quantidade_seg = 1;

        $resultado = array();

        foreach($dados as $row){
            $origem = $row['source_caller_id'];
            $destino = $row['destination_caller_id'];
            $action_destino = $row['action_dn_caller_id'];
            $duracao = empty($row['talking_duration']) ? "00:00:00" : $row['talking_duration'];
            $espera = empty($row['ringing_duration']) ? "00:00:00" : $row['ringing_duration'];
            $atendida = $row['answered'] == "t" ? "Ligação Atendida" : "Ligação Não Atendida";

            // Filtra o número de origem
            $resultadoFiltragem = $this->filtrarNumero($origem, $row['source_display_name']);
            $origem = $resultadoFiltragem[0];

            // Filtra o número de destino
            $resultadoFiltragem = $this->filtrarNumero($destino, $row['destination_display_name']);
            $destino = $resultadoFiltragem[0];

            // Filtra o número de ação
            $resultadoFiltragem = $this->filtrarNumero($action_destino, $row['action_dn_display_name']);
            $action_destino = $resultadoFiltragem[0];

            if(isset($row['descricao_cdr'])){
                $motivo = $row['descricao_cdr'];
            } else{
                $motivo = $this->obter_resultado_ligacao($origem, $destino, intval($row['action_type']), $action_destino);
            }

            // Obtém o endereço onde está localizado o aúdio no servidor do 3cx
            $audio = substr($row['recording_url'],0,5). rawurlencode(substr($row['recording_url'],5,strlen($row['recording_url'])-5));
            // Obtém o novo nome do aúdio no servidor do sistema
            $new_audio = substr($row['recording_url'],0,4)."-".rawurldecode(substr($row['recording_url'],5,strlen($row['recording_url'])-9));
            // Obtém o caminho absoluto para o áudio no servidor do sistema
            $file_name = substr($row['recording_url'],0,4)."-".rawurldecode(substr($row['recording_url'],5,strlen($row['recording_url'])-5));
            $file_name_mp3 = substr($row['recording_url'],0,4)."-".rawurldecode(substr($row['recording_url'],5,strlen($row['recording_url'])-8)) . "mp3";
            $audio_path = realpath(__DIR__ . "/../../3cx-audio/") . '/'. $file_name;
            // Obtém o caminho absoluto para o áudio no servidor do sistema, em MP3
            $new_path = realpath(__DIR__ . "/../../3cx-audio/") . '/' . $file_name_mp3;
            // Se existe gravação...

            if(!empty($audio)){
                try{
                    if(!file_exists($new_path)){ // Se a gravação não foi salva no servidor, baixa ela agora e a converte
                        ignore_user_abort(true); // Ignoramos caso o usuário cancele a operação
                        $curlSession = curl_init();
                        curl_setopt($curlSession, CURLOPT_URL, "http://34.35.53.44:8080/". $audio);
                        curl_setopt($curlSession, CURLOPT_BINARYTRANSFER, true);
                        curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, true);
                        $contents = curl_exec($curlSession);
                        $httpcode = curl_getinfo($curlSession, CURLINFO_HTTP_CODE);
                        curl_close($curlSession);

                        if($contents != false && $httpcode == 200){
                            if(file_put_contents($audio_path, $contents) != false){ // Salvamos a ligação em WAV
                                exec('ffmpeg -i "'.$audio_path.'" "'.$new_path.'"'); // Converte a ligação para MP3
                                unlink($audio_path); // Deleta a ligação que está em formato WAV
                            }
                        }

                        ignore_user_abort(false); // Agora que a operação crítica acabou, permite-se ao cliente abortar a operação
                    }
                }
                catch(Exception $e){}
            }

            if(isset($row['origem_cdr'])){
                $origem = $row['origem_cdr'];
            }

            if(isset($row['destino_cdr'])){
                $destino = $row['destino_cdr'];
            }

            $resultado[] = array(
                "ordem" => $quantidade_seg,
                "audio" => $audio,
                "caminho-audio" => $new_audio,
                "caminho-audio-absoluto" => $new_path,
                "origem" => $origem,
                "destino" => $destino,
                "atendida" => $atendida,
                "espera" => $espera,
                "duracao" => $duracao,
                "resultado" => $motivo
            );

            $quantidade_seg += 1;
        }

        return $resultado;
    }

	/* Retorna uma string que informa o resultado da ligação */
	function obter_resultado_ligacao($origem, $destino, $acao, $destino_acao){
		switch($acao){
			case 1:
				return "Conectado.";
			case 2:
				return sprintf("Atendido por %s.", $destino_acao);
			case 5:
				return sprintf("Encerrado por %s.", $origem);
			case 6:
				return sprintf("Encerrado por %s.", $destino);
			case 7:
				return sprintf("Transferência de %s falhou.", $origem);
			case 9:
				return sprintf("%s substituído por %s.", $origem, $destino_acao);
			case 10:
				return sprintf("%s substituído por %s.", $destino, $destino_acao);
			case 12:
				return sprintf("Atendido por %s.", $destino);
			case 13:
				return sprintf("Abandonado, enviado para %s.", $destino_acao);
			case 101:
				return sprintf("Sem resposta, redirecionado para %s.", $destino_acao);
			case 102:
				return sprintf("Ocupado, redirecionado para %s.", $destino_acao);
			case 103:
				return sprintf("Não registrado, redirecionado para %s.", $destino_acao);
			case 104:
				return sprintf("Transferido para %s.", $destino_acao);
			case 400:
				return "Falhou.";
			case 408:
				return "Destino não encontrado.";
			case 418:
				return "Falha, cancelado.";
			case 419:
				return sprintf("Redirecionado para %s.", $destino_acao);
			case 426:
				return "Chamada externa desabilitada.";
			default:
				return "";
		}
	}

	/* Obtém todas as ligações de todos os clientes */
	function obter_ligacoes_todos_clientes($data, $data_inicial, $data_final){
		$filtro = Filtro::filtrar_3cx($data, $data_inicial, $data_final);
		$dados = $this->bd->executar('SELECT *  FROM cl_get_call_log_win7($1, $2, 0, \'\', 0, \'\', 0, 0, NULL, NULL, true)', array($filtro[0],$filtro[1]), Banco_Dados::FETCH_ALL);
		return $dados;
	}

	/* Conta a quantidade de ligações */
	function contar_ligacoes($data, $data_inicial, $data_final, $agrupar_numeros = false, $mostrar_total_real = true){
        // Script antigo
		// $rows = $this->obter_ligacoes($data, $data_inicial, $data_final, false, false, $agrupar_numeros, $mostrar_total_real);
		// return array($rows[0]['totalligacoes'], $rows[0]['naoatendidas']);

		// Script novo
		// Seleciona os dados do cliente no banco
		$cliente = $this->bd_sys->executar("SELECT NU_PRECO_LIGACAO, DT_VONOINICIO, DT_VONOFIM, NU_VONOID, NU_ESCONDER_LIGACOES_EFETUADAS  FROM TBL_CLIENTE WHERE ID_CLIENTE = :id", array(":id" => $this->id), Banco_Dados::FETCH);

        App::initialize();
        $usarSistemaNovo = App::getConfig()->get('phone.usar_novo');

        if ($usarSistemaNovo) {
            $manager = App::getContainer()->get(CallManager::class);

            $valor_ligacoes = $this->obter_valores($cliente["NU_PRECO_LIGACAO"]);
            $nomes          = $this->obter_nomes();
            $exploded       = empty($cliente['NU_VONOID']) ? false : explode(',', $cliente['NU_VONOID']);
            $ids_3cx        = !$exploded ? [] : $exploded;
            $filtro         = Filtro::filtrar_3cx($data, $data_inicial, $data_final);
            $filtro         = $this->corrigir_filtro($filtro, $cliente["DT_VONOINICIO"], $cliente["DT_VONOFIM"]);

            $params                      = [];
            $params['dataInicial']       = substr($filtro[0], 0, -3);
            $params['dataFinal']         = substr($filtro[1], 0, -3);
            $params['valores']           = $valor_ligacoes;
            $params['nomes']             = $nomes;
            $params['ramais']            = $ids_3cx;
            $params['cliente']           = $this->id;
            $params['esconderEfetuadas'] = $cliente['NU_ESCONDER_LIGACOES_EFETUADAS'];
            $params['agrupar']           = $agrupar_numeros;
            $params['totalReal']         = $mostrar_total_real;
            $todas                   = $manager->contarLigacoes($params);

            return [$todas, $todas];
        }

		// Obtém o valor das ligações
		$valor_ligacoes = $this->obter_valores($cliente["NU_PRECO_LIGACAO"]);

		// Obtém o filtro a ser utilizado
		$filtro = Filtro::filtrar_3cx($data, $data_inicial, $data_final);
		$filtro = $this->corrigir_filtro($filtro, $cliente["DT_VONOINICIO"], $cliente["DT_VONOFIM"]);

		// Obtém o nome dos ramais
		$nomes = $this->obter_nomes();

		// Prepara os dados de saída
		$rows = array();
		$rows[] = array();
		$rows[0]['data'] = 0;
		$rows[0]['data2'] = time();
		$rows[0]['ids'] = array();
		$rows[0]['totalgasto'] = "R$ 0,00";
		$total_gasto = 0.0;
		$ligacoes = array();

		// Obtém a lista de ramais
		$exploded = empty($cliente['NU_VONOID']) ? false : explode(',', $cliente['NU_VONOID']);
		$ids_3cx = ($exploded == false) ? array() : $exploded;

		foreach($ids_3cx as $ramal){
			$ramal_tipo = strlen($ramal) >= 8 ? 4 : 2;
			$ramal_valor = $ramal_tipo == 4 ? "%".$ramal."%" : $ramal;

			if($cliente['NU_ESCONDER_LIGACOES_EFETUADAS'] == "0"){
				$dados = $this->bd->executar('SELECT source_caller_id, destination_caller_id, call_id, talking_duration, source_display_name, ringing_duration, answered, start_time FROM cl_get_call_log_win7($1, $2, $3, $4, 0, \'\', 0, 0, NULL, NULL, true)', array($filtro[0],$filtro[1],$ramal_tipo,$ramal_valor), Banco_Dados::FETCH_ALL);
				if(!empty($dados)) $this->adicionar_ligacoes($dados, $ligacoes, $rows, $ramal, $nomes, $total_gasto, $valor_ligacoes, false);
			} else {
				$dados = $this->bd->executar('SELECT source_caller_id, destination_caller_id, call_id, talking_duration, source_display_name, ringing_duration, answered, start_time FROM cl_get_call_log_win7($1, $2, 0, \'\' , $3, $4, 0, 0, NULL, NULL, true)', array($filtro[0],$filtro[1], $ramal_tipo,$ramal_valor), Banco_Dados::FETCH_ALL);
				if(!empty($dados)) $this->adicionar_ligacoes($dados, $ligacoes, $rows, $ramal, $nomes, $total_gasto, $valor_ligacoes, false);
			}
		}

		// $sql = "SELECT ";
		// $rows_total = count($rows);
		// if($rows_total > 1){
		// 	$qtd_consultas = 0;
		// 	for($i = 1; $i < $rows_total;$i++){
		// 		$ligacao = $rows[$i];
		// 		if($qtd_consultas > 0) $sql .= ", ";
		// 		$sql .= "(SELECT count(*) FROM TBL_LEADS WHERE ID_CLIENTE_FK = '".$this->id."' AND NU_TELEFONE1 = '".$ligacao['origem']."' AND TXT_LEADTIPO = 'Win7 Fone') as qtd".$ligacao['id'];
		// 		$qtd_consultas++;
		// 	}
		// 	$resultado_lig = $this->bd_sys->executar($sql, array(), Banco_Dados::FETCH);
		// 	for($i = 1; $i < $rows_total;$i++){
		// 		$ligacao = $rows[$i];
		// 		if($resultado_lig['qtd'.$ligacao['id']] > 0){
		// 			$rows[$i]['adicionado'] = 1;
		// 		}
		// 		else{
		// 			$rows[$i]['adicionado'] = 0;
		// 		}
		// 	}
		// }

		// Formata as datas inicial e final
		$rows[0]['data'] = date('Y-m-d',$rows[0]['data']);
		$rows[0]['data2'] = date('Y-m-d',$rows[0]['data2']);

		// Prepara a lista de ramais para enviá-las por json
		$listaRamais = array();
		foreach($ids_3cx as $ramal){
			$vid = $ramal;
			if(in_array($vid, $rows[0]['ids'])){
				if(!empty($nomes[$vid])) $vid = $nomes[$vid];
				if(!in_array($vid, $listaRamais)) $listaRamais[] = $vid;
			}
		}
		$rows[0]['ids'] = $listaRamais;
		$total_real = count($rows) - 1;
		$rows[0]['totalligacoes'] = $total_real;
		$total_nao_atendidas = 0;
		$total = count($rows);
		for($i = 1;$i < $total;$i++){
				$ligacao = $rows[$i];
				if($ligacao['atendida'] == "Não Atendida"){
						$total_nao_atendidas++;
				}
		}
		$rows[0]['naoatendidas'] = $total_nao_atendidas;

		if($agrupar_numeros == true){
			$total = count($rows);
			$numeros = array();
			for($i = 1;$i < $total;$i++){
				$ligacao = $rows[$i];
				$origem = $ligacao['origem'].$ligacao['fonte'];
				if(array_key_exists($origem, $numeros)){
					$ligacao_mestre = $numeros[$origem][0];
					$data = strtotime($ligacao['data']);
					$data_antiga = strtotime($ligacao_mestre['data']);
					if($data > $data_antiga){
						$numeros[$origem][1][] = $numeros[$origem][0];
						$numeros[$origem][0] = $ligacao;
					}
					else{
						$numeros[$origem][1][] = $ligacao;
					}
				}
				else{
					$numeros[$origem] = array($ligacao, array());
				}
			}
			$dados_rows = $rows[0];
			$rows = array($dados_rows);
			foreach ($numeros as $key => $value) {
				// $value[0]['subligacoes'] = $value[1];
				$rows[] = $value[0];
			}
			if(!$mostrar_total_real){
				$rows[0]['totalligacoes'] = count($rows) - 1;
			}
			// return $rows;
			return array($rows[0]['totalligacoes'], $rows[0]['naoatendidas']);
		}
		else{
			// return $rows;
			return array($rows[0]['totalligacoes'], $rows[0]['naoatendidas']);
		}
	}

    /**
     * @return void
     * @throws \DI\DependencyException
     * @throws \DI\NotFoundException
     * @throws \ReflectionException
     * @throws \Win7\Application\Exception\UserException
     */
    function obter_ligacoes_novo(Sistema $sistema)
    {
        // obtém os dados do cliente e do filtro e seta eles no POST
        $cliente             = $this->bd_sys->executar("SELECT *  FROM TBL_CLIENTE WHERE ID_CLIENTE = :id", [":id" => $this->id], Banco_Dados::FETCH);
        $valor_ligacoes      = $this->obter_valores($cliente["NU_PRECO_LIGACAO"]);
        $nomes               = $this->obter_nomes();
        $exploded            = empty($cliente['NU_VONOID']) ? false : explode(',', $cliente['NU_VONOID']);
        $ids_3cx             = !$exploded ? [] : $exploded;
        $filtro              = Filtro::filtrar_3cx($_POST['data'], $_POST['datainicial'], $_POST['datafinal']);
        $filtro              = $this->corrigir_filtro($filtro, $cliente["DT_VONOINICIO"], $cliente["DT_VONOFIM"]);
        $TXT_URL_BTN_CONTATO = $cliente['TXT_URL_BTN_CONTATO'];

        $_POST['dataInicial']   = substr($filtro[0], 0, -3);
        $_POST['dataFinal']     = substr($filtro[1], 0, -3);
        $_POST['valores']       = $valor_ligacoes;
        $_POST['nomes']         = $nomes;
        $_POST['ramais']        = $ids_3cx;
        $_POST['permitirLeads'] = $sistema->usuario->permissao_leads == Usuario::PERM_ESCRITA;
        $_POST['urlContato']    = $TXT_URL_BTN_CONTATO;
        $_POST['cliente']       = $this->id;
        $_POST['agrupar']       = $sistema->usuario->agrupar_ligacoes;
        $_POST['totalReal']     = $sistema->usuario->mostrar_total_real_ligacoes;

        // Carrega as ligações usando a win7 lib
        $controller = App::getContainer()->get(CallController::class);
        $controller->listar();
    }

    /**
     * @return void
     * @throws \DI\DependencyException
     * @throws \DI\NotFoundException
     * @throws \ReflectionException
     * @throws \Win7\Application\Exception\UserException
     */
    function obter_subligacoes(Sistema $sistema)
    {
        // obtém os dados do cliente e do filtro e seta eles no POST
        $cliente             = $this->bd_sys->executar("SELECT *  FROM TBL_CLIENTE WHERE ID_CLIENTE = :id", [":id" => $this->id], Banco_Dados::FETCH);
        $valor_ligacoes      = $this->obter_valores($cliente["NU_PRECO_LIGACAO"]);
        $nomes               = $this->obter_nomes();
        $exploded            = empty($cliente['NU_VONOID']) ? false : explode(',', $cliente['NU_VONOID']);
        $ids_3cx             = !$exploded ? [] : $exploded;
        $filtro              = Filtro::filtrar_3cx($_POST['data'], $_POST['datainicial'], $_POST['datafinal']);
        $filtro              = $this->corrigir_filtro($filtro, $cliente["DT_VONOINICIO"], $cliente["DT_VONOFIM"]);
        $TXT_URL_BTN_CONTATO = $cliente['TXT_URL_BTN_CONTATO'];

        $_POST['dataInicial']   = substr($filtro[0], 0, -3);
        $_POST['dataFinal']     = substr($filtro[1], 0, -3);
        $_POST['valores']       = $valor_ligacoes;
        $_POST['nomes']         = $nomes;
        $_POST['ramais']        = $ids_3cx;
        $_POST['permitirLeads'] = $sistema->usuario->permissao_leads == Usuario::PERM_ESCRITA;
        $_POST['urlContato']    = $TXT_URL_BTN_CONTATO;
        $_POST['cliente']       = $this->id;
        $_POST['agrupar']       = $sistema->usuario->agrupar_ligacoes;
        $_POST['totalReal']     = $sistema->usuario->mostrar_total_real_ligacoes;

        // Carrega as ligações usando a win7 lib
        $controller = App::getContainer()->get(CallController::class);
        $controller->listarSubligacoes();
    }

    /* Obtém um array com a lista de todas as ligações */
	function obter_ligacoes($data, $data_inicial, $data_final, $grafico, $trans_json = true, $agrupar_numeros = false, $mostrar_total_real = true){
		App::initialize();
        $usarSistemaNovo = App::getConfig()->get('phone.usar_novo');

        if ($usarSistemaNovo) {
            $manager             = App::getContainer()->get(CallManager::class);
            $cliente             = $this->bd_sys->executar("SELECT *  FROM TBL_CLIENTE WHERE ID_CLIENTE = :id", [":id" => $this->id], Banco_Dados::FETCH);
            $valor_ligacoes      = $this->obter_valores($cliente["NU_PRECO_LIGACAO"]);
            $nomes               = $this->obter_nomes();
            $exploded            = empty($cliente['NU_VONOID']) ? false : explode(',', $cliente['NU_VONOID']);
            $ids_3cx             = !$exploded ? [] : $exploded;
            $filtro              = Filtro::filtrar_3cx($_POST['data'], $_POST['datainicial'], $_POST['datafinal']);
            $filtro              = $this->corrigir_filtro($filtro, $cliente["DT_VONOINICIO"], $cliente["DT_VONOFIM"]);
            $TXT_URL_BTN_CONTATO = $cliente['TXT_URL_BTN_CONTATO'];

            $_POST['dataInicial'] = substr($filtro[0], 0, -3);
            $_POST['dataFinal']   = substr($filtro[1], 0, -3);
            $_POST['valores']     = $valor_ligacoes;
            $_POST['nomes']       = $nomes;
            $_POST['ramais']      = $ids_3cx;
            $_POST['urlContato']  = $TXT_URL_BTN_CONTATO;
            $_POST['cliente']     = $this->id;
            $_POST['grafico']     = $grafico;
            $_POST['agrupar']     = $agrupar_numeros;
            $_POST['totalReal']   = $mostrar_total_real;

            if($trans_json == true){
                return json_encode( $manager->obterTodasLigacoes($_POST));
            } else{
                return $manager->obterTodasLigacoes($_POST);
            }
        }

        // Seleciona os dados do cliente no banco
		$cliente = $this->bd_sys->executar("SELECT NU_PRECO_LIGACAO, DT_VONOINICIO, DT_VONOFIM, NU_VONOID, NU_ESCONDER_LIGACOES_EFETUADAS  FROM TBL_CLIENTE WHERE ID_CLIENTE = :id", array(":id" => $this->id), Banco_Dados::FETCH);

		// Obtém o valor das ligações
		$valor_ligacoes = $this->obter_valores($cliente["NU_PRECO_LIGACAO"]);

		// Obtém o filtro a ser utilizado
		$filtro = Filtro::filtrar_3cx($data, $data_inicial, $data_final);
		$filtro = $this->corrigir_filtro($filtro, $cliente["DT_VONOINICIO"], $cliente["DT_VONOFIM"]);

		// Obtém o nome dos ramais
		$nomes = $this->obter_nomes();

		// Prepara os dados de saída
		$rows = array();
		$rows[] = array();
		$rows[0]['data'] = 0;
		$rows[0]['data2'] = time();
		$rows[0]['ids'] = array();
		$rows[0]['totalgasto'] = "R$ 0,00";
		$total_gasto = 0.0;
		$ligacoes = array();

		// Obtém a lista de ramais
		$exploded = empty($cliente['NU_VONOID']) ? false : explode(',', $cliente['NU_VONOID']);
		$ids_3cx = ($exploded == false) ? array() : $exploded;

		foreach($ids_3cx as $ramal){

			// $ramal_tipo, vai ser 4 ou 2, dependendo o lenght do numero da vez, se for >= 8 caracteres, recebe 4, se não, 2;
			$ramal_tipo = strlen($ramal) >= 8 ? 4 : 2;

			// $ramal_valor, vai ser cercado de % (%numeroramal%) se o $ramal_tipo for 4 se não, fica sem os % (numeroramal);
			$ramal_valor = $ramal_tipo == 4 ? "%".$ramal."%" : $ramal;

			if($cliente['NU_ESCONDER_LIGACOES_EFETUADAS'] == "0"){ //Não

				/*
				cl_get_call_log_win7(
					'2021-02-25 00:00:00-03', [period_from]
					'2021-02-25 23:59:59-03', [period_to]
					2 ou 4, [source_type]
					'0014' ou '%0014%', [source_filter]
					0, [destination_type]
					'', [destination_filter]
					0, [calls_type]
					0, [call_time_filter_type]
					NULL, [call_time_filter_from]
					NULL, [call_time_filter_to]
					true [hide_pcalls]
				)
				*/

				$dados = $this->bd->executar('SELECT source_caller_id, destination_caller_id, call_id, talking_duration, source_display_name, ringing_duration, answered, start_time  FROM cl_get_call_log_win7($1, $2, $3, $4, 0, \'\', 0, 0, NULL, NULL, true)', array($filtro[0],$filtro[1],$ramal_tipo,$ramal_valor), Banco_Dados::FETCH_ALL);
				if(!empty($dados)) $this->adicionar_ligacoes($dados, $ligacoes, $rows, $ramal, $nomes, $total_gasto, $valor_ligacoes, $grafico);

			} else { //Sim - se estiver marcada a opção de esconder no sistemawin7, cai aqui.

				/*
				cl_get_call_log_win7(
					'2021-02-25 00:00:00-03', [period_from]
					'2021-02-25 23:59:59-03', [period_to]
					0, [source_type]
					'', [source_filter]
					4 ou 2, [destination_type]
					'%0014%' ou '0014', [destination_filter]
					0, [calls_type]
					0, [call_time_filter_type]
					NULL, [call_time_filter_from]
					NULL, [call_time_filter_to]
					true [hide_pcalls]
				)
				*/

				$dados = $this->bd->executar('SELECT source_caller_id, destination_caller_id, call_id, talking_duration, source_display_name, ringing_duration, answered, start_time FROM cl_get_call_log_win7($1, $2, 0, \'\' , $3, $4, 0, 0, NULL, NULL, true)', array($filtro[0],$filtro[1], $ramal_tipo,$ramal_valor), Banco_Dados::FETCH_ALL);
				if(!empty($dados)) $this->adicionar_ligacoes($dados, $ligacoes, $rows, $ramal, $nomes, $total_gasto, $valor_ligacoes, $grafico);
			}
		}

		$sql = "SELECT ";
		$rows_total = count($rows);
		if($rows_total > 1){
			$qtd_consultas = 0;
			for($i = 1; $i < $rows_total;$i++){
				$ligacao = $rows[$i];
				if($qtd_consultas > 0) $sql .= ", ";
				$sql .= "(SELECT count(*) FROM TBL_LEADS WHERE ID_CLIENTE_FK = '".$this->id."' AND NU_TELEFONE1 = '".$ligacao['origem']."' AND TXT_LEADTIPO = 'Win7 Fone') as qtd".$ligacao['id'];
				$qtd_consultas++;
			}
			$resultado_lig = $this->bd_sys->executar($sql, array(), Banco_Dados::FETCH);
			for($i = 1; $i < $rows_total;$i++){
				$ligacao = $rows[$i];
				if($resultado_lig['qtd'.$ligacao['id']] > 0){
					$rows[$i]['adicionado'] = 1;
				}
				else{
					$rows[$i]['adicionado'] = 0;
				}
			}
		}

		// Formata as datas inicial e final
		$rows[0]['data'] = date('Y-m-d',$rows[0]['data']);
		$rows[0]['data2'] = date('Y-m-d',$rows[0]['data2']);

		// Prepara a lista de ramais para enviá-las por json
		$listaRamais = array();
		foreach($ids_3cx as $ramal){
			$vid = $ramal;
			if(in_array($vid, $rows[0]['ids'])){
				if(!empty($nomes[$vid])) $vid = $nomes[$vid];
				if(!in_array($vid, $listaRamais)) $listaRamais[] = $vid;
			}
		}
		$rows[0]['ids'] = $listaRamais;
		$total_real = count($rows) - 1;
		$rows[0]['totalligacoes'] = $total_real;
		$total_nao_atendidas = 0;
		$total = count($rows);
		for($i = 1;$i < $total;$i++){
				$ligacao = $rows[$i];
				if($ligacao['atendida'] == "Não Atendida"){
						$total_nao_atendidas++;
				}
		}
		$rows[0]['naoatendidas'] = $total_nao_atendidas;

		if($agrupar_numeros == true){
			$total = count($rows);
			$numeros = array();
			for($i = 1;$i < $total;$i++){
				$ligacao = $rows[$i];
				$origem = $ligacao['origem'].$ligacao['fonte'];
				if(array_key_exists($origem, $numeros)){
					$ligacao_mestre = $numeros[$origem][0];
					$data = strtotime($ligacao['data']);
					$data_antiga = strtotime($ligacao_mestre['data']);
					if($data > $data_antiga){
						$numeros[$origem][1][] = $numeros[$origem][0];
						$numeros[$origem][0] = $ligacao;
					}
					else{
						$numeros[$origem][1][] = $ligacao;
					}
				}
				else{
					$numeros[$origem] = array($ligacao, array());
				}
			}
			$dados_rows = $rows[0];
			$rows = array($dados_rows);
			foreach ($numeros as $key => $value) {
				$value[0]['subligacoes'] = $value[1];
				$rows[] = $value[0];
			}
			if(!$mostrar_total_real){
				$rows[0]['totalligacoes'] = count($rows) - 1;
			}
			if($trans_json == true){
				return json_encode($rows);
			}
			else{
				return $rows;
			}
		}
		else{
			if($trans_json == true){
				return json_encode($rows);
			}
			else{
				return $rows;
			}
		}
	}
}
