<?

/**
 * TRIBUNAL REGIONAL FEDERAL DA 4 REGIO
 *
 * 05/04/2024 - criado por sabino.colab
 *
 * Verso do Gerador de Cdigo: 1.43.3
 */

require_once dirname(__FILE__) . '/../../../SEI.php';

class MdIaTopicoChatINT extends InfraINT
{
    public static function criarTopicoChat()
    {
        $objMdIaTopicoChatDTO = new MdIaTopicoChatDTO();
        $objMdIaTopicoChatRN = new MdIaTopicoChatRN();

        $objMdIaTopicoChatDTO->setNumIdUsuario(SessaoSEI::getInstance()->getNumIdUsuario());
        $objMdIaTopicoChatDTO->setNumIdUnidade(SessaoSEI::getInstance()->getNumIdUnidadeAtual());
        $objMdIaTopicoChatDTO->setStrNome(InfraData::getStrDataAtual() . "-" . InfraData::getStrHoraAtual());
        $objMdIaTopicoChatDTO->setStrSinAtivo("S");
        $objMdIaTopicoChatDTO->setDthCadastro(InfraData::getStrDataHoraAtual());
        $topicoCadastrado = $objMdIaTopicoChatRN->cadastrar($objMdIaTopicoChatDTO);
        return $topicoCadastrado->getNumIdMdIaTopicoChat();
    }

    public static function consultarUltimoTopico()
    {
        if (SessaoSEI::getInstance()->isSetAtributo('MD_IA_ID_TOPICO_CHAT_IA')) {
            $topicoCadastrado = self::verificaSessaoTopico();

            if (!empty($topicoCadastrado)) {
                $idTopico = $topicoCadastrado->getNumIdMdIaTopicoChat();
                SessaoSEI::getInstance()->setAtributo('MD_IA_ID_TOPICO_CHAT_IA', $idTopico);
                return $idTopico;
            }
        } else {
            $objMdIaTopicoChatDTO = new MdIaTopicoChatDTO();
            $objMdIaTopicoChatRN = new MdIaTopicoChatRN();

            $objMdIaTopicoChatDTO->retNumIdMdIaTopicoChat();
            $objMdIaTopicoChatDTO->retDthCadastro();
            $objMdIaTopicoChatDTO->setNumIdUsuario(SessaoSEI::getInstance()->getNumIdUsuario());
            $objMdIaTopicoChatDTO->setNumIdUnidade(SessaoSEI::getInstance()->getNumIdUnidadeAtual());
            $objMdIaTopicoChatDTO->setStrSinAtivo("S");
            $objMdIaTopicoChatDTO->setOrdNumIdMdIaTopicoChat(InfraDTO::$TIPO_ORDENACAO_DESC);
            $objMdIaTopicoChatDTO->setNumMaxRegistrosRetorno(1);

            $topicoCadastrado = $objMdIaTopicoChatRN->consultar($objMdIaTopicoChatDTO);

            if (!empty($topicoCadastrado)) {
                $topicoCadastrado->getNumIdMdIaTopicoChat();
                $dataUltimoTopico = $topicoCadastrado->getDthCadastro();
                if (substr($dataUltimoTopico, 0, 10) == InfraData::getStrDataAtual()) {
                    $idTopico = $topicoCadastrado->getNumIdMdIaTopicoChat();
                    SessaoSEI::getInstance()->setAtributo('MD_IA_ID_TOPICO_CHAT_IA', $idTopico);
                    return $idTopico;
                }
            }
        }
    }

    public function adicionarTopico()
    {
        $idTopico = self::criarTopicoChat();
        $dadosMensagem["idTopico"] = $idTopico;
        SessaoSEI::getInstance()->setAtributo('MD_IA_ID_TOPICO_CHAT_IA', $idTopico);
        return $idTopico;
    }

    public static function verificaSessaoTopico()
    {
        $objMdIaTopicoChatDTO = new MdIaTopicoChatDTO();
        $objMdIaTopicoChatRN = new MdIaTopicoChatRN();

        $objMdIaTopicoChatDTO->retNumIdMdIaTopicoChat();
        $objMdIaTopicoChatDTO->setNumIdMdIaTopicoChat(SessaoSEI::getInstance()->getAtributo('MD_IA_ID_TOPICO_CHAT_IA'));
        $objMdIaTopicoChatDTO->setNumIdUsuario(SessaoSEI::getInstance()->getNumIdUsuario());
        $objMdIaTopicoChatDTO->setNumIdUnidade(SessaoSEI::getInstance()->getNumIdUnidadeAtual());
        $objMdIaTopicoChatDTO->setStrSinAtivo("S");

        $topicoCadastrado = $objMdIaTopicoChatRN->consultar($objMdIaTopicoChatDTO);
        if (empty($topicoCadastrado)) {

            SessaoSEI::getInstance()->removerAtributo('MD_IA_ID_TOPICO_CHAT_IA');
            $idTopico = self::consultarUltimoTopico();

            $dadosMensagem["idTopico"] = $idTopico;

            SessaoSEI::getInstance()->setAtributo('MD_IA_ID_TOPICO_CHAT_IA', $idTopico);
        }
        return SessaoSEI::getInstance()->getAtributo('MD_IA_ID_TOPICO_CHAT_IA');
    }

    public static function infraDataAtual()
    {
        return date("d/m/Y");
    }

    public static function infraCalcularDataDias($data, $dias)
    {
        $date = DateTime::createFromFormat("d/m/Y", $data);
        $date->modify("$dias days");
        return $date->format("d/m/Y");
    }

    public static function infraCalcularDataMeses($data, $meses)
    {
        $date = DateTime::createFromFormat("d/m/Y", $data);
        $date->modify("$meses months");
        return $date->format("d/m/Y");
    }

    public static function infraCalcularDataFinalMes($data)
    {
        $date = DateTime::createFromFormat("d/m/Y", $data);
        return $date->format("t/m/Y"); // 't' retorna o ltimo dia do ms
    }

    public static function retornaPeriodos()
    {
        $dataAtual = new DateTime();

        $anoAtual = $dataAtual->format('Y'); // Ano atual

        $dataAtual->modify('-1 month');
        $mesAnterior = $dataAtual->format('m'); // Ms anterior
        $anoMesAnterior = $dataAtual->format('Y'); // Ano anterior

        // Formatar como MM/YYYY
        $mesAnoFormatado = $mesAnterior . '/' . $anoMesAnterior;

        $periodosPossiveis = array();
        // Hoje
        $periodosPossiveis["hoje"] = [
            "data_inicial" => self::infraDataAtual() . " 00:00:00",
            "data_final" => self::infraDataAtual() . " 23:59:59"
        ];

        // Ontem
        $periodosPossiveis["ontem"] = [
            "data_inicial" => self::infraCalcularDataDias(self::infraDataAtual(), "-1") . " 00:00:00",
            "data_final" => self::infraCalcularDataDias(self::infraDataAtual(), "-1") . " 23:59:59"
        ];

        // ltimos 7 dias
        $periodosPossiveis["ultimos7dias"] = [
            "data_inicial" => self::infraCalcularDataDias(self::infraDataAtual(), "-7") . " 00:00:00",
            "data_final" => self::infraDataAtual() . " 23:59:59"
        ];

        // ltimos 30 dias
        $periodosPossiveis["ultimos30dias"] = [
            "data_inicial" => self::infraCalcularDataDias(self::infraDataAtual(), "-30") . " 00:00:00",
            "data_final" => self::infraDataAtual() . " 23:59:59"
        ];

        // ltimo ms
        $periodosPossiveis["ultimoMes"] = [
            "data_inicial" => "01/" . $mesAnoFormatado . " 00:00:00",
            "data_final" => self::infraCalcularDataFinalMes("01/" . $mesAnoFormatado) . " 23:59:59"
        ];

        // Penltimo ms
        $periodosPossiveis["penultimoMes"] = [
            "data_inicial" => self::infraCalcularDataMeses("01/" . $mesAnoFormatado, -1) . " 00:00:00",
            "data_final" => self::infraCalcularDataFinalMes(self::infraCalcularDataMeses("01/" . $mesAnoFormatado, -1)) . " 23:59:59"
        ];

        // Antepenltimo ms
        $periodosPossiveis["antepenultimoMes"] = [
            "data_inicial" => self::infraCalcularDataMeses("01/" . $mesAnoFormatado, -2) . " 00:00:00",
            "data_final" => self::infraCalcularDataFinalMes(self::infraCalcularDataMeses("01/" . $mesAnoFormatado, -2)) . " 23:59:59"
        ];

        // Ano atual
        $periodosPossiveis["anoAtual"] = [
            "data_inicial" => "01/01/" . $anoAtual . " 00:00:00",
            "data_final" => "31/12/" . $anoAtual . " 23:59:59"
        ];

        // ltimo ano
        $periodosPossiveis["ultimoAno"] = [
            "data_inicial" => "01/01/" . ($anoAtual - 1) . " 00:00:00",
            "data_final" => "31/12/" . ($anoAtual - 1) . " 23:59:59"
        ];
        return $periodosPossiveis;
    }

    function converterParaDate($dataString)
    {
        // Converter a string de data para um objeto DateTime
        $dateTime = DateTime::createFromFormat('d/m/Y H:i:s', $dataString);
        return $dateTime;
    }

    public static function definePeriodoTopico($dataBase, $periodos)
    {
        // Converte a data base para um objeto DateTime
        $dataBaseObj = DateTime::createFromFormat('d/m/Y H:i:s', $dataBase);

        // Itera sobre os perodos para verificar se a data base est dentro de algum deles
        foreach ($periodos as $nomePeriodo => $intervalo) {
            $dataInicialObj = DateTime::createFromFormat('d/m/Y H:i:s', $intervalo['data_inicial']);
            $dataFinalObj = DateTime::createFromFormat('d/m/Y H:i:s', $intervalo['data_final']);
            // Verifica se a data base est entre data_inicial e data_final
            if ($dataBaseObj >= $dataInicialObj && $dataBaseObj <= $dataFinalObj) {
                return $nomePeriodo; // Retorna o nome do perodo correspondente
            }
        }
        // Se a data base no estiver em nenhum perodo, retorna "Mais Antigos"
        return "maisAntigos";
    }

    public static function listarTopicos()
    {
        $objMdIaTopicoChatDTO = new MdIaTopicoChatDTO();
        $objMdIaTopicoChatRN = new MdIaTopicoChatRN();
        $objMdIaTopicoChatDTO->retNumIdMdIaTopicoChat();
        $objMdIaTopicoChatDTO->retStrNome();
        $objMdIaTopicoChatDTO->setNumIdUsuario(SessaoSEI::getInstance()->getNumIdUsuario());
        $objMdIaTopicoChatDTO->setNumIdUnidade(SessaoSEI::getInstance()->getNumIdUnidadeAtual());
        $objMdIaTopicoChatDTO->setStrSinAtivo("S");
        $objMdIaTopicoChatDTO->setOrdNumIdMdIaTopicoChat(InfraDTO::$TIPO_ORDENACAO_DESC);

        $listagemTopicos = $objMdIaTopicoChatRN->listar($objMdIaTopicoChatDTO);

        $arrayRetorno["budgetTokens"] = MdIaConfigAssistenteINT::calcularConsumoDiarioToken();

        $periodos = self::retornaPeriodos();
        if (!empty($listagemTopicos)) {
            if (!SessaoSEI::getInstance()->isSetAtributo('MD_IA_ID_TOPICO_CHAT_IA')) {
                $dados["id"] = self::consultarUltimoTopico();
                SessaoSEI::getInstance()->setAtributo('MD_IA_ID_TOPICO_CHAT_IA', $dados["id"]);
            } else {
                $dados["id"] = self::verificaSessaoTopico();
            }

            $arrayItensTopicos = array();
            $arrayTopicos = array();
            foreach ($listagemTopicos as $itemTopico) {
                $objMdIaInteracaoChatDTO = new MdIaInteracaoChatDTO();
                $objMdIaInteracaoChatRN = new MdIaInteracaoChatRN();
                $objMdIaInteracaoChatDTO->retDthCadastro();
                $objMdIaInteracaoChatDTO->setNumIdMdIaTopicoChat($itemTopico->getNumIdMdIaTopicoChat());
                $objMdIaInteracaoChatDTO->setOrdNumIdMdIaInteracaoChat(InfraDTO::$TIPO_ORDENACAO_DESC);
                $objMdIaInteracaoChatDTO->setNumMaxRegistrosRetorno(1);
                $ultimaInteracao = $objMdIaInteracaoChatRN->consultar($objMdIaInteracaoChatDTO);

                $arrayItensTopicos["idTopico"] = $itemTopico->getNumIdMdIaTopicoChat();

                if ($ultimaInteracao) {
                    $arrayItensTopicos["dataUltimaInteracao"] = $ultimaInteracao->getDthCadastro();
                }

                $periodo = self::definePeriodoTopico($arrayItensTopicos["dataUltimaInteracao"], $periodos);
                $arrayItensTopicos["periodo"] = $periodo;

                $arrayItensTopicos["nome"] = mb_convert_encoding($itemTopico->getStrNome(), 'UTF-8', 'ISO-8859-1');
                if ($arrayItensTopicos["idTopico"] != SessaoSEI::getInstance()->getAtributo('MD_IA_ID_TOPICO_CHAT_IA')) {
                    $arrayItensTopicos["ativo"] = false;
                } else {
                    $arrayItensTopicos["ativo"] = true;
                }
                $arrayTopicos[$periodo][] = $arrayItensTopicos;
            }

            // Opcional: Ordenar os tpicos dentro de cada perodo pelo campo 'dataUltimaInteracao'
            foreach ($arrayTopicos as $topicos) {
                usort($topicos, function ($a, $b) {
                    $timestampA = strtotime(str_replace("/", "-", $a['dataUltimaInteracao']));
                    $timestampB = strtotime(str_replace("/", "-", $b['dataUltimaInteracao']));
                    return $timestampB - $timestampA; // Ordenao decrescente
                });
            }
            $arrayRetorno["topicos"] = $arrayTopicos;
        } else {
            $arrayRetorno["topicos"] = false;
        }
        return $arrayRetorno;
    }

    public static function listarProcedimentosPrompt($prompt)
    {
        $documentos = [];
        preg_match_all('/#\S*(?=\s|$|\n)/', $prompt, $matches);
        $possiveisCitacoes = array_unique($matches[0]);
        if (!empty($possiveisCitacoes)) {
            foreach ($possiveisCitacoes as $possivelCitacao) {
                if (strpos($possivelCitacao, '[') !== false) {
                    if (preg_match('/#[0-9]+\[[0-9]+(:[0-9]+)?\]/', $possivelCitacao, $match)) {
                        $documentos[] = $match[0];
                    }
                } else {
                    if (preg_match('/#[0-9]+[^[\s]*?(?=\s|$|\n|[.,;:?!)](?![^.,;:?!)]))/', $possivelCitacao, $match)) {
                        $documentos[] = $match[0];
                    }
                }
            }
        }
        $protocolo["documento"] = $documentos;
        $protocolo["consultaTopico"] = true;
        $citacoes = MdIaConfigAssistenteINT::listaProtocolosUtilizados($protocolo);

        return $citacoes;
    }

    public static function selecionarTopico($dados)
    {
        if ($dados["id"] != "" && !is_null($dados["id"])) {
            SessaoSEI::getInstance()->setAtributo('MD_IA_ID_TOPICO_CHAT_IA', $dados["id"]);
        }
        $objMdIaInteracaoChatDTO = new MdIaInteracaoChatDTO();
        $objMdIaInteracaoChatRN = new MdIaInteracaoChatRN();
        $objMdIaInteracaoChatDTO->retNumIdMessage();
        $objMdIaInteracaoChatDTO->retStrPergunta();
        $objMdIaInteracaoChatDTO->retStrResposta();
        $objMdIaInteracaoChatDTO->retNumFeedback();
        $objMdIaInteracaoChatDTO->retNumIdMdIaInteracaoChat();
        $objMdIaInteracaoChatDTO->retNumStatusRequisicao();
        $objMdIaInteracaoChatDTO->setNumIdMdIaTopicoChat($dados["id"]);
        $objMdIaInteracaoChatDTO->setOrdNumIdMdIaInteracaoChat(InfraDTO::$TIPO_ORDENACAO_ASC);
        $objMdIaInteracaoChatDTO->retDthCadastro();

        $listagemInteracoes = $objMdIaInteracaoChatRN->listar($objMdIaInteracaoChatDTO);

        $arrayItensInteracoes = array();
        $arrayInteracoes = array();
        foreach ($listagemInteracoes as $itemInteracao) {
            $arrayItensInteracoes["favorito"] = false;

            $arrayItensInteracoes["id_mensagem"] = $itemInteracao->getNumIdMessage();
            $arrayItensInteracoes["pergunta"] = mb_convert_encoding($itemInteracao->getStrPergunta(), 'UTF-8', 'ISO-8859-1');

            $arrayProcedimentos = self::listarProcedimentosPrompt($itemInteracao->getStrPergunta());

            $resposta = MdIaConfigAssistenteINT::retornaMensagemAmigavelUsuario($itemInteracao->getNumStatusRequisicao(), $itemInteracao->getStrResposta());

            $arrayItensInteracoes["resposta"] = mb_convert_encoding($resposta["resposta"], 'UTF-8', 'ISO-8859-1');
            $arrayItensInteracoes["tipo_critica"] = $resposta["tipoCritica"];

            $arrayItensInteracoes["feedback"] = $itemInteracao->getNumFeedback();
            $arrayItensInteracoes["dadosCitacoes"] = $arrayProcedimentos;
            $arrayItensInteracoes["id_interacao"] = $itemInteracao->getNumIdMdIaInteracaoChat();
            $arrayItensInteracoes["status_requisicao"] = $itemInteracao->getNumStatusRequisicao();
            $arrayItensInteracoes["dth_cadastro"] = substr($itemInteracao->getDthCadastro(), 0, 19);

            $arrayInteracoes[] = $arrayItensInteracoes;
        }
        return $arrayInteracoes;
    }


    public static function renomearTopico($dados)
    {

        $objMdIaTopicoChatDTO = new MdIaTopicoChatDTO();
        $objMdIaTopicoChatRN = new MdIaTopicoChatRN();

        $objMdIaTopicoChatDTO->setNumIdMdIaTopicoChat($dados["id_topico"]);
        $objMdIaTopicoChatDTO->setStrNome($dados["nome_topico"]);
        $objMdIaTopicoChatRN->alterar($objMdIaTopicoChatDTO);
        return true;
    }

    public static function arquivarTopico($dados)
    {

        $objMdIaTopicoChatDTO = new MdIaTopicoChatDTO();
        $objMdIaTopicoChatRN = new MdIaTopicoChatRN();

        $objMdIaTopicoChatDTO->setNumIdMdIaTopicoChat($dados["id_topico"]);
        $objMdIaTopicoChatDTO->setStrSinAtivo("N");
        $objMdIaTopicoChatRN->alterar($objMdIaTopicoChatDTO);
        SessaoSEI::getInstance()->removerAtributo('MD_IA_ID_TOPICO_CHAT_IA');
        return true;
    }

    public static function desarquivarTopico($dados)
    {

        $objMdIaTopicoChatDTO = new MdIaTopicoChatDTO();
        $objMdIaTopicoChatRN = new MdIaTopicoChatRN();

        $objMdIaTopicoChatDTO->setNumIdMdIaTopicoChat($dados["id_topico"]);
        $objMdIaTopicoChatDTO->setStrSinAtivo("S");
        $objMdIaTopicoChatRN->alterar($objMdIaTopicoChatDTO);
        SessaoSEI::getInstance()->removerAtributo('MD_IA_ID_TOPICO_CHAT_IA');
        return true;
    }
}
