<?php

namespace App\Http\Controllers;

use DB;
use Session;
use Request;
use Route;
use App\Custom\SQLConnection;
use App\Http\Controllers\OpenAiController;
use App\Custom\Misc;
use stdClass;
use Response;
use DateTime;
use DateInterval;
use Illuminate\Support\Facades\File;
use CURLFile;
use App\Models\Edicto;

ini_set('memory_limit', '256M');

class IAController extends Controller
{     
    /**
    * Esta funcion se usa para obtener datos de prompts y listar carpetas en un directorio especifico de edictos
    * y luego retorna una vista con estos datos
    * 
    * @return \Illuminate\Contracts\View\View la vista 'comparador_edictos_json' con los datos obtenidos
    */
    public function comparadorEdictosJson(){
        // Obtener los prompts
        $datos_prompt = SQLConnection::backendStoreProcedure('gestor_prompts', ['seleccionar', null, null, null, null, null, null, null, null]);
        
        // Definir la ruta de los archivos de edictos
        $pathArchivos = env('CARPETA_EDICTOS_TXT');
        $pathExiste = '';         
        
        // Verificar si el directorio existe
        if (is_dir($pathArchivos)) {
            $pathExiste = 1;
            
            // Obtener las carpetas en el directorio de archivos
            $carpetas = File::directories($pathArchivos);

            if(!empty($carpetas)){
                // Obtener solo los nombres de las carpetas
                $nombresCarpetas = array_map(function($carpeta) {
                    return basename($carpeta);
                }, $carpetas);

                // Crear un array asociativo con la ruta completa como clave y el nombre como valor
                $carpetasAssociativas = array_combine($carpetas, $nombresCarpetas);     
            } else {
                $carpetas = [];
                $carpetasAssociativas = [];
            }
        } else {
            $pathExiste = 0;
            $datos_prompt = ''; 
            $carpetas = '';
            $carpetasAssociativas = '';
        }
        
        $pathArchiviosAnalizados = env('CARPETA_EDICTOS_ANALIZADOS');
        $pathExisteAnalizado = '';

        $carpetasAssociativasAnl = [];
        // Verificar si el directorio existe
        if (is_dir($pathArchiviosAnalizados)) {
            $pathExisteAnalizado = 1;
            
            // Obtener las carpetas en el directorio de archivos
            $carpetasAnl = File::directories($pathArchiviosAnalizados);

            if(!empty($carpetasAnl)){
                // Obtener solo los nombres de las carpetas
                $nombresCarpetasAnl = array_map(function($carpeta) {
                    return basename($carpeta);
                }, $carpetasAnl);

                // Crear un array asociativo con la ruta completa como clave y el nombre como valor
                $carpetasAssociativasAnl = array_combine($carpetasAnl, $nombresCarpetasAnl);     
            } else {
                $carpetasAnl = [];
                $carpetasAssociativasAnl = [];
            }
        } else {
            $pathExisteAnalizado = 0;
            $carpetas = '';
            $carpetasAssociativas = '';
        }

        return view('/comparador_edictos_json')->with(compact('datos_prompt', 'carpetas', 'carpetasAssociativas', 'pathExiste', 'carpetasAssociativasAnl'));
    }


    /**
     * Toma una lista de archivos de una carpeta especifica y los devuelve en formato JSON
     *
     * @return \Illuminate\Http\JsonResponse  
     */
    public function obtenerArchivosCarpeta(){
        // Toma la ruta de la carpeta desde la solicitud
        $folderPath = Request::input('folder');

        $files = [];
        // Escanea la carpeta y elimina las referencias a la carpeta actual y la carpeta padre
        $files = array_diff(scandir($folderPath), ['..', '.']);

        // Reindexa el array de archivos para que las claves sean numericas y consecutivas
        $files = array_values($files);        

        $cantEdictos = count($files);

        // Combina la ruta de la carpeta con el nombre de cada archivo para obtener la ruta completa
        foreach ($files as $key => $file) {
            $files[$key] = $folderPath . '/' . $file;
        }

        // Devuelve la lista de archivos en formato JSON
        return response()->json([
            'cantidad' => $cantEdictos,
            'archivos' => $files
        ]);
    }
   
    /**
    * Obtengo el contenido de un archivo especifico y lo devuelve en formato JSON
    *
    * @return \Illuminate\Http\JsonResponse
    *
    */
    public function obtenerContenidoArchivo(){
        // obtengo la ruta del archivo desde la solicitud
        $filePath = Request::input('file');

        $content = '';
        // Lee el contenido del archivo en la ruta especificada
        $content = file_get_contents($filePath);

        // Devuelve el contenido del archivo en formato JSON
        return response()->json(['content' => $content]);
    }

    /**
    * Genera un JSON utilizando la API de OpenAI con el analisis del edicto
    *
    * @return string
    */
    public static function generarJsonEdicto() {        
        $idPrompt = Request::input('opcionPrompt');
        $textoEdicto = Request::input('txtEdicto');
        $id_fide = Request::input('id_fide') ?? 0;
        $fuente = Request::input('fuente') ?? NULL;        
        
        // Obtener el prompt correspondiente
        $promptCorrespondiente = SQLConnection::backendStoreProcedure(
            'gestor_prompts', 
            ['SELECT_ONE', null, null, null, null, null, null, null, $idPrompt]
        );        
        
        if (empty($promptCorrespondiente)) {
            return 'Prompt no encontrado.';
        }

        $prompt = $promptCorrespondiente[0];
        
        $tokens = '';
        $formatear = '';
        // Determinar el numero de tokens
        if ($prompt->id_prompt != 21) {
            $tokens = 5000;
            $formatear = 0;
        } else {
            $tokens = 4000;
            $formatear = 1;
        }
        
        $dataString = OpenAiController::formateoCompletions($prompt->ai_provider,$prompt->system_prompt,$prompt->user_prompt,$textoEdicto,$tokens);
        $respuesta = OpenAiController::completionsEndpoint($dataString);        
        
        self::ProcesarEdictosIndividual($respuesta, $id_fide, $fuente);
    
        $params = [];
        $params[] = 'EDICTO_DATOS';
        $params[] = NULL;
        $params[] = $id_fide;         
        $datos2 = DB::select('EXEC dbo.BackendDirectorioEdictosAI ?, ?, ?', $params);           

        if (isset($respuesta['error'])) {
            return json_encode(['error' => 1, 'data' => 'Error en la respuesta: ' . $respuesta['error']['message']]);
        }

        if (isset($respuesta['choices'][0]['message']['content'])) {
            $respuestaApi = $respuesta['choices'][0]['message']['content'];
            
            $json_string = str_replace(['```json', '```'], '', $respuestaApi);
            $respuestaApi = trim($json_string);           
            
            return json_encode(['formatear' => $formatear, 'data' => $respuestaApi]);
        }

        return 'Respuesta inesperada de la API.';
    }

    public static function generarJsonEdictoV2() {        
        $idPrompt = Request::input('opcionPrompt');
        $textoEdicto = Request::input('txtEdicto');
        $id_fide = Request::input('id_fide') ?? 0;
        $fuente = Request::input('fuente') ?? NULL;   
        $textoEdicto = 'MERLEG SRL - (Art. 10º LGS) Por Resolución del Sr. Director de la Dirección de Inspección de Personas Jurídicas, se ha dispuesto publicar por un día en el Boletín Oficial de la Provincia de Entre Ríos el siguiente edicto: En la localidad de Villa Seguí, departamento Paraná, provincia de Entre Ríos, a los treinta días del mes de Junio del año Dos mil Veintitrés, reunidos los señores MICAELA DE LA MERCED LELL, D.N.I. Nº 37.566.385, CUIT 27- 37566385-1, nacida el 7 de Enero de 1.996, soltera, domiciliada en calle Santa Rosa Nº 51 de la localidad de Seguí, provincia de Entre Ríos, de profesión Licenciada en Comercio Internacional; y MAURO IVAN TERENZIO, D.N.I. Nº 33.595.332, CUIT 20-33595332-1, nacido el 29 de Mayo de 1.988, casado con Leticia María Itatí Podversich, DNI 37.291.823, domiciliado en Entre Ríos Nº 633 de la localidad de Paraná, provincia de Entre Ríos, de profesión músico, resuelven celebrar el siguiente contrato de Sociedad de Responsabilidad Limitada. Primero: La sociedad se denomina “MERLEG S.R.L.”, y tiene su domicilio en calle Santa Rosa Nº 51 de la localidad de Seguí, departamento Paraná, provincia de Entre Ríos. Segundo: Su duración es de cincuenta [50] años, contados a partir de la fecha de inscripción en el Registro Público de Comercio. Tercero: la sociedad tiene por objeto la Fabricación, comercialización, importación, exportación, venta al por mayor y al por menor de toda clase de textiles, hilados, telas, tejidos y productos elaborados para vestir. Cuarto: El capital social se fija en la suma de pesos Tres millones ($ 3.000.000,00), dividido en cien (3000) cuotas de pesos Un mil ($ 1.000,00) valor nominal cada una; de las cuales MICAELA DE LA MERCED LELL suscribe Dos mil ochocientos cincuenta (2.850) cuotas, y MAURO IVAN TERENZIO suscribe Ciento cincuenta (150) cuotas, integrando cada uno de ellos el 100% de su aporte de acuerdo al siguiente detalle: a) MICAELA DE LA MERCED LELL aporta dinero en efectivo por un valor de pesos Cincuenta mil ($ 50.000,00.-), mercaderías por un valor de pesos Dos millones trescientos cincuenta mil ($ 2.350.000,00.-) y una computadora marca Acer por un valor de pesos Cuatrocientos cincuenta mil ($ 450.000,00.-); b) MAURO IVAN TERENZIO aporta mercaderías por un valor de pesos Ciento cincuenta mil ($ 150.000,00.-). Quinto: la administración, representación legal y uso de la firma social estarán a cargo de MICAELA DE LA MERCED LELL, como gerente en forma individual. En tal carácter tiene todas las facultades para realizar los actos y contratos tendientes al cumplimiento del objeto de la sociedad, efectuar trámites bancarios y alquiler de inmuebles. Además, podrá realizar la compraventa de bienes muebles registrables y se requerirá unanimidad para la compraventa de inmuebles y constituir hipotecas. La fiscalización de las operaciones sociales podrá ser efectuada en cualquier momento por cualquiera de los socios pudiendo inspeccionar los libros, cuentas y demás documentos de la sociedad exigiendo, en su caso, la realización de balances parciales y rendiciones de cuentas especiales. Sexto: las resoluciones sociales se adoptarán en la forma dispuesta en el artículo 159, 1ra. parte, párrafo 2° de la ley 19550. Rigen las mayorías previstas en el artículo 160 de la citada ley y cada cuota da derecho a un voto. Toda comunicación o citación a los socios se sujetará a lo dispuesto en el artículo 159, último párrafo de la ley 19550. Séptimo: Las cuotas son libremente transmisibles, rigiendo las disposiciones del artículo 152 de la ley 19550. Octavo: El ejercicio social cierra el 31 de diciembre de cada año, a cuya fecha se realizará el balance general que se pondrá a disposición de los socios con no menos de 15 días de anticipación a su consideración. Noveno: De las utilidades líquidas y realizadas se destinará: a) el 5% al fondo de reserva legal, hasta alcanzar el 20% del capital social; b) el importe que se establezca para retribución del gerente y c) el remanente, previa deducción de cualquier otra reserva que los socios dispusieran constituir, se distribuirá entre los mismos en proporción al capital integrado. Décimo: Disuelta la sociedad por cualquiera de las causales previstas en el artículo 94 de la ley 19550, la liquidación será practicada por el gerente por la persona que designen los socios. En este acto los socios acuerdan: a) establecer la sede social en calle Santa Rosa Nº 51 de la localidad de Seguí, provincia de Entre Ríos; b) autorizar a ROSANA RAQUEL RIOS, D.N.I. Nº 24.585.670, CUIT 27-24585670-4, nacida el 2 de febrero de 1.976, casada en primeras nupcias con Humberto Fabián Ríos (DNI Nº 25.108.468), domiciliada realmente en calle 25 de Mayo y María de Battisti de la ciudad de Seguí, provincia de Entre Ríos, de profesión Contadora Pública Nacional, Matrícula Nº 3226, para tramitar la inscripción del presente contrato en el Registro Público de Comercio con facultades de aceptar las modificaciones que indique la Inspección General de Justicia, otorgando los instrumentos que resulten necesarios, acompañar y desglosar documentación y depositar y retirar los fondos a que se refiere el artículo 149 de la ley 19550. Registro Público – DIPJ – Paraná, 15 de diciembre de 2024 - José María Raiteri, abogado inspector DIPJER. F.C. 04-00052776 1 v./01/07/2024';             
        
        // Obtener el prompt correspondiente
        $promptCorrespondiente = SQLConnection::backendStoreProcedure(
            'gestor_prompts', 
            ['SELECT_ONE', null, null, null, null, null, null, null, 56]
        );        
        
        if (empty($promptCorrespondiente)) {
            return 'Prompt no encontrado.';
        }

        $prompt = $promptCorrespondiente[0];
        
        $tokens = '';
        $formatear = '';
        // Determinar el numero de tokens
        if ($prompt->id_prompt != 21) {
            $tokens = 5000;
            $formatear = 0;
        } else {
            $tokens = 4000;
            $formatear = 1;
        }
        
        $dataString = OpenAiController::formateoCompletions($prompt->ai_provider,$prompt->system_prompt,$prompt->user_prompt,$textoEdicto,$tokens);
        $respuesta = OpenAiController::completionsEndpoint($dataString);                               

        if (isset($respuesta['error'])) {
            return json_encode(['error' => 1, 'data' => 'Error en la respuesta: ' . $respuesta['error']['message']]);
        }

        if (isset($respuesta['choices'][0]['message']['content'])) {              
            
            self::ProcesarEdictosIndividual($respuesta, $id_fide, $fuente); 
        
            $params = [];
            $params[] = 'EDICTO_DATOS';
            $params[] = NULL;
            $params[] = $id_fide;         
            $datos2 = DB::select('EXEC dbo.BackendDirectorioEdictosAI ?, ?, ?', $params);
            
            return json_encode(['edictoData' => $datos2,]);
        }

        return 'Respuesta inesperada de la API.';
    }

    public static function generarJsonEdictoTest() {
        
        $idPrompt = 23;
        $textoEdicto = 'AGROPECUARIA LA ESPERANZA SA  DESIGNACION DE AUTORIDADES  Conforme Expte N 138 del anio 2024 que tramita ante el Registro Publico de Rafaela Santa Fe se hace saber:  Los accionistas de Agropecuaria La Esperanza SA por Acta de Asamblea y Acta de Directorio ambas de fecha 05/02/2024 designacion a los miembros del Organo de Administracion:  Director Titular Presidente: Sr Fernando Antonio Birchner Nocco apellido materno Nocco nacido el 09 de julio de 1969 titular del DNI N 20667360 CUIT N 20206673606 argentino casado comerciante domiciliado en Armando Diaz N 1137 de la ciudad de Rafaela provincia de Santa Fe; y como Directora Suplente: Sra Sara Maria Lencina apellido materno Padula nacida el 12 de agosto de 1971 titular del DNI N 22026597 CUIT N 27220265973 argentina casada empleada domiciliada en Armando Diaz N 1137 de la ciudad de Rafaela provincia de Santa Fe  $ 50 517147 Mar 27  ';        
        // Obtener el prompt correspondiente
        $promptCorrespondiente = SQLConnection::backendStoreProcedure(
            'gestor_prompts', 
            ['SELECT_ONE', null, null, null, null, null, null, null, $idPrompt]
        );
        
        if (empty($promptCorrespondiente)) {
            return 'Prompt no encontrado.';
        }

        $prompt = $promptCorrespondiente[0];
        
        $tokens = '';
        $formatear = '';
        // Determinar el numero de tokens
        if ($prompt->id_prompt != 21) {
            $tokens = 5000;
            $formatear = 0;
        } else {
            $tokens = 4000;
            $formatear = 1;
        }
        
        $dataString = OpenAiController::formateoCompletions($prompt->ai_provider,$prompt->system_prompt,$prompt->user_prompt,$textoEdicto,$tokens);
        $respuesta = OpenAiController::completionsEndpoint($dataString);                            

        if (isset($respuesta['error'])) {
            return json_encode(['error' => 1, 'data' => 'Error en la respuesta: ' . $respuesta['error']['message']]);
        }

        self::ProcesarEdictosIndividual($respuesta,"1312897","BORA");            

        
        if (isset($respuesta['choices'][0]['message']['content'])) {
            $respuestaApi = $respuesta['choices'][0]['message']['content'];
            
            $json_string = str_replace(['```json', '```'], '', $respuestaApi);
            $respuestaApi = trim($json_string);
            
            return json_encode(['formatear' => $formatear, 'data' => $respuestaApi]);
        }

        return 'Respuesta inesperada de la API.';
    }

    public static function ProcesarEdictosIndividual($contenido, $id_fide, $fuente){
        /* 
        $contenido = [
            "id" => "chatcmpl-BPCIehAsY3wxVsOU9cCrHa3sv3G5P",
            "object" => "chat.completion",
            "created" => 1745345180,
            "model" => "ft:gpt-4o-mini-2024-07-18:etixenfide::A1yJDzEy",
            "choices" => [
                [
                    "index" => 0,
                    "message" => [
                        "role" => "assistant",
                        "content" => '{
                            "Datos_Empresa": {
                                "nombre_actual": "AGROPECUARIA LA ESPERANZA SA",
                                "empresa_tipo": "SA"
                            },
                            "Relacion_Personas": [
                                {
                                    "apellido_nombre": "Fernando Antonio Birchner Nocco",
                                    "persona_DNI": "20667360",
                                    "persona_cuit": "20-20667360-6",
                                    "persona_estado_civil": "casado",
                                    "persona_domicilio": "Armando Diaz N 1137, Rafaela, Santa Fe",
                                    "Persona_Cargo": [
                                        {"p_rol": "Director Titular"},
                                        {"p_rol": "Presidente"}
                                    ],
                                    "permanece_en_cargo?": "Sí"
                                },
                                {
                                    "apellido_nombre": "Sara Maria Lencina Padula",
                                    "persona_DNI": "22026597",
                                    "persona_cuit": "27-22026597-3",
                                    "persona_estado_civil": "casada",
                                    "persona_domicilio": "Armando Diaz N 1137, Rafaela, Santa Fe",
                                    "Persona_Cargo": [{"p_rol": "Directora Suplente"}],
                                    "permanece_en_cargo?": "Sí"
                                }
                            ],
                            "Datos_Generales": {
                                "tipo_edicto": "Designación de autoridades",
                                "fecha_asamblea": "05-02-2024"
                            }
                        }',
                        "refusal" => null,
                        "annotations" => []
                    ],
                    "logprobs" => null,
                    "finish_reason" => "stop"
                ]
            ],
            "usage" => [
                "prompt_tokens" => 1050,
                "completion_tokens" => 329,
                "total_tokens" => 1379,
                "prompt_tokens_details" => ["cached_tokens" => 0, "audio_tokens" => 0],
                "completion_tokens_details" => [
                    "reasoning_tokens" => 0,
                    "audio_tokens" => 0,
                    "accepted_prediction_tokens" => 0,
                    "rejected_prediction_tokens" => 0
                ]
            ],
            "service_tier" => "default",
            "system_fingerprint" => "fp_6403b7eef2"
        ];        
        */
        
        $content = $contenido['choices'][0]['message']['content'];
        $txt_json = $content;         
        $file_editable = json_decode($content, true);                
        $arch = "";         
        $custom_id = ''; 

        $params = [];
        $params[] = $id_fide;
        $params[] = 'control_ya_procesado';            
        $control_ya_procesado = DB::select('EXEC dbo.openai_insert_sociedades_constituciones ?,?', $params);                

        /* ----- */
        $Datos_Empresa     = new stdClass();
        $Datos_Generales   = new stdClass();
        $Relacion_Personas = [];
        $Relacion_Empresas = [];
        $Datos_Empresa     = $file_editable['Datos_Empresa'] ?? null;
        $Datos_Generales   = $file_editable['Datos_Generales'] ?? null;
        
        if (isset($file_editable['Relacion_Personas']) && is_array($file_editable['Relacion_Personas'])){
            $Relacion_Personas = $file_editable['Relacion_Personas'];
        }
        
        if (isset($file_editable['Relacion_Personas']) && !is_array($file_editable['Relacion_Personas'])){
            $Relacion_Personas[] = $file_editable['Relacion_Personas']; 
        }

        if (isset($file_editable['Relacion_Empresas']) && is_array($file_editable['Relacion_Empresas'])){
            $Relacion_Empresas = $file_editable['Relacion_Empresas'];
        }
        
        if (isset($file_editable['Relacion_Empresas']) && !is_array($file_editable['Relacion_Empresas'])){
            $Relacion_Empresas[] = $file_editable['Relacion_Empresas']; 
        }   
        
        $nombre_actual = new stdClass(); 
        $nombre_actual = null;
        if (isset($Datos_Empresa['nombre_actual']) && is_array($Datos_Empresa['nombre_actual'])){
            $nombre_actual = implode(";",$Datos_Empresa['nombre_actual']);
        }
        
        if (isset($Datos_Empresa['nombre_actual']) && !is_array($Datos_Empresa['nombre_actual'])){
            $nombre_actual = $Datos_Empresa['nombre_actual'];
        }
        
        $nombre_anterior = new stdClass(); 
        $nombre_anterior = null;
        if (isset($Datos_Empresa['nombre_anterior']) && is_array($Datos_Empresa['nombre_anterior'])){
            $nombre_anterior = implode(";",$Datos_Empresa['nombre_anterior']);
        }

        // Nombre anterior
        $nombre_anterior = '';
        if (isset($Datos_Empresa['nombre_anterior']) && !is_array($Datos_Empresa['nombre_anterior'])) {
            $nombre_anterior = $Datos_Empresa['nombre_anterior'];
        }

        // CUIT empresa
        $cuit_empresa = null;
        if (isset($Datos_Empresa['cuit_empresa'])) {
            if (is_array($Datos_Empresa['cuit_empresa'])) {
                $cuit_empresa = implode(";", $Datos_Empresa['cuit_empresa']);
            } else {
                $cuit_empresa = $Datos_Empresa['cuit_empresa'];
            }
        }

        // Domicilio actual
        $domicilio_actual = null;
        if (isset($Datos_Empresa['domicilio_actual'])) {
            if (is_array($Datos_Empresa['domicilio_actual'])) {
                $domicilio_actual = implode(";", $Datos_Empresa['domicilio_actual']);
            } else {
                $domicilio_actual = $Datos_Empresa['domicilio_actual'];
            }
        }

        // Domicilio anterior
        $domicilio_anterior = null;
        if (isset($Datos_Empresa['domicilio_anterior'])) {
            if (is_array($Datos_Empresa['domicilio_anterior'])) {
                $domicilio_anterior = implode(";", $Datos_Empresa['domicilio_anterior']);
            } else {
                $domicilio_anterior = $Datos_Empresa['domicilio_anterior'];
            }
        }

        // Tipo de empresa
        $empresa_tipo = null;
        if (isset($Datos_Empresa['empresa_tipo'])) {
            if (is_array($Datos_Empresa['empresa_tipo'])) {
                $empresa_tipo = implode(";", $Datos_Empresa['empresa_tipo']);
            } else {
                $empresa_tipo = $Datos_Empresa['empresa_tipo'];
            }
        }

        // Tipo de edicto
        $tipo_edicto = null;
        if (isset($Datos_Generales['tipo_edicto'])) {
            if (is_array($Datos_Generales['tipo_edicto'])) {
                $tipo_edicto = implode(";", $Datos_Generales['tipo_edicto']);
            } else {
                $tipo_edicto = $Datos_Generales['tipo_edicto'];
            }
        }

        // Fecha de asamblea
        $fecha_asamblea = null;
        if (isset($Datos_Generales['fecha_asamblea'])) {
            if (is_array($Datos_Generales['fecha_asamblea'])) {
                $fecha_asamblea = implode(";", $Datos_Generales['fecha_asamblea']);
            } else {
                $fecha_asamblea = $Datos_Generales['fecha_asamblea'];
            }
        }

           
        $params = [];
        $params[] = $id_fide;
        $params[] = 'update';
        $params[] = Session::get('usuario')->user_id ?? '0';
        $params[] = $nombre_actual ?? null;
        $params[] = $nombre_anterior ?? null;
        $params[] = $cuit_empresa ?? null;
        $params[] = $domicilio_actual ?? null;
        $params[] = $domicilio_anterior ?? null;
        $params[] = $empresa_tipo ?? null;
        $params[] = $tipo_edicto ?? null;
        $params[] = $arch ?? null;
        $params[] = $fuente ?? null;

        // Update en sociedades_constituciones de los Datos_Empresa y Datos_Generales, si algun dato le falta
        $sociedades = DB::select('EXEC dbo.openai_insert_sociedades_constituciones ?,?,?,?,?,?,?,?,?,?,?,?', $params);
                         
        $paramsJson = [];
        $paramsJson[] = 'insert';
        $paramsJson[] = $id_fide ?? '0'; 
        $paramsJson[] = $tipo_edicto ?? null;
        $paramsJson[] = $arch ?? null;
        $paramsJson[] = $custom_id ?? null;
        $paramsJson[] = $txt_json; 
        $paramsJson[] = Session::get('usuario')->user_id ?? '0';
        $txt_json = DB::select('EXEC dbo.openai_insert_json ?,?,?,?,?,?,?', $paramsJson);           
        
        foreach ($Relacion_Personas as $valueRP) {
            $cargos = [];
        
            if (isset($valueRP['Persona_Cargo'])) {
                if (is_array($valueRP['Persona_Cargo'])) {
                    $cargos = $valueRP['Persona_Cargo'];
                } else {
                    $cargos[] = $valueRP['Persona_Cargo'];
                }
            } elseif (isset($valueRP['p_rol'])) {
                if (is_array($valueRP['p_rol'])) {
                    $cargos = $valueRP['p_rol'];
                } else {
                    $cargos[] = $valueRP['p_rol'];
                }
            }
        
            if (count($cargos) === 0) {
                $paramsRP = [
                    'insert',
                    $id_fide ?? '0',
                    $valueRP['apellido_nombre'] ?? null,
                    $valueRP['persona_DNI'] ?? null,
                    $valueRP['persona_cuit'] ?? null,
                    $valueRP['persona_domicilio'] ?? null,
                    $valueRP['persona_estado_civil'] ?? null,
                    $valueRP['persona_conyuge'] ?? null,
                    null,
                    $valueRP['permanece_en_cargo'] ?? null,
                    Session::get('usuario')['user_id'] ?? '0'
                ];

                DB::select('EXEC dbo.openai_insert_personas ?,?,?,?,?,?,?,?,?,?,?', $paramsRP);
            } else {
                foreach ($cargos as $valueRP2) {
                    $paramsRP = [
                        'insert',
                        $id_fide ?? '0',
                        $valueRP['apellido_nombre'] ?? null,
                        $valueRP['persona_DNI'] ?? null,
                        $valueRP['persona_cuit'] ?? null,
                        $valueRP['persona_domicilio'] ?? null,
                        $valueRP['persona_estado_civil'] ?? null,
                        $valueRP['persona_conyuge'] ?? null,
                        is_array($valueRP2) ? ($valueRP2['p_rol'] ?? null) : $valueRP2,
                        $valueRP['permanece_en_cargo'] ?? null,
                        Session::get('usuario')->user_id ?? '0'
                    ];
        
                    DB::select('EXEC dbo.openai_insert_personas ?,?,?,?,?,?,?,?,?,?,?', $paramsRP);
                }
            }
        }

        foreach ($Relacion_Empresas as $RE => $valueRE) {
            
            $vinculos = []; 
            if (isset($valueRE['Vinculada_vinculo']) && is_array($valueRE['Vinculada_vinculo'])){
                $vinculos = $valueRE['Vinculada_vinculo'];
            }else if (isset($valueRE['Vinculada_vinculo']) && !is_array($valueRE['Vinculada_vinculo'])){
                $vinculos[] = $valueRE['Vinculada_vinculo'];
            }

            if (count($vinculos) == 0){
                $paramsRE = [];
                $paramsRE[] = 'insert';
                $paramsRE[] = $id_fide ?? '0'; 
                $paramsRE[] = $valueRE['Vinculada_nombre'] ?? null;
                $paramsRE[] = $valueRE['Vinculada_cuit'] ?? null;
                $paramsRE[] = $valueRE['Vinculada_Pais'] ?? null;
                $paramsRE[] = $valueRE['Vinculada_domicilio'] ?? null;
                $paramsRE[] = null;
                $paramsRE[] = Session::get('usuario')->user_id ?? '0';

                // Insert en [sociedades_constituciones_relaciones_vinculadas]
                $vinculadas = DB::select('EXEC dbo.openai_insert_vinculadas ?,?,?,?,?,?,?,?,?', $paramsRE);
            }else {
                foreach ($vinculos as $RE2 => $valueRE2) {
                    $paramsRE = [];
                    $paramsRE[] = 'insert';
                    $paramsRE[] = $id_fide ?? '0'; 
                    $paramsRE[] = $valueRE['Vinculada_nombre'] ?? null;
                    $paramsRE[] = $valueRE['Vinculada_cuit'] ?? null;
                    $paramsRE[] = $valueRE['Vinculada_Pais'] ?? null;
                    $paramsRE[] = $valueRE['Vinculada_domicilio'] ?? null;
                    $paramsRE[] = $valueRE2['e_rol'] ?? ($valueRE2 ?? null);
                    $paramsRE[] = Session::get('usuario')->user_id ?? '0';
                    // Insert en [sociedades_constituciones_relaciones_vinculadas]
                    $vinculadas = DB::select('EXEC dbo.openai_insert_vinculadas ?,?,?,?,?,?,?,?,?', $paramsRE);
                }
            }
        }        
    }

    /**
    * Guarda un archivo JSON y un archivo de texto, y mueve el archivo de texto original a una carpeta
    *
    * @return \Illuminate\Http\JsonResponse   
    */
    public function guardarJson() { 
        $txtPath = Request::input('nombreTxt');
        $json = Request::input('json');        
        $valoracionJson = Request::input('valoracionJson');        
        $contenidoTxtPantalla = Request::input('contenidoTxt');        
        $carpetaEdictosAnalizados = env('CARPETA_EDICTOS_ANALIZADOS');
        $carpeta = Request::input('carpeta');

        // Obtener solo el nombre del archivo
        $nombreArchivoTxt = basename($txtPath);
        // Le ponemos el mismo nombre al txt que figura en la pantalla de analisis
        $nombreArchivoTxtPantalla = $nombreArchivoTxt;         
        
        // Cambia la extensión del archivo
        $nombreArchivoJson = str_replace(".txt", ".txt.json", $nombreArchivoTxt);

        // Obtengo el nombre de la provincia
        $nombreProvincia = explode('_', $nombreArchivoTxt);
        $nombreProvincia = $nombreProvincia[0];

        // Crea las carpetas necesarias si no existen
        if (!is_dir($carpetaEdictosAnalizados)) {
            mkdir($carpetaEdictosAnalizados, 0777, true);
        }

        if (!is_dir($carpetaEdictosAnalizados.'/'.$nombreProvincia)) {
            mkdir($carpetaEdictosAnalizados.'/'.$nombreProvincia, 0777, true);
        }

        if (!is_dir($carpetaEdictosAnalizados.'/'.$nombreProvincia.'/'.'originales')) {
            mkdir($carpetaEdictosAnalizados.'/'.$nombreProvincia.'/'.'originales', 0777, true);
        }
        
        // Define la carpeta de valoracion segun el estado del JSON
        $carpetaValoracion = '';
        if ($valoracionJson == 0) {
            $carpetaValoracion = 'aprobado';
        } elseif ($valoracionJson == 1) {
            $carpetaValoracion = 'editado';
        } elseif ($valoracionJson == 2) {
            $carpetaValoracion = 'rechazado';
        } else {
            // Manejo de caso si no tiene valoracion
        }
        
        if (!is_dir($carpetaEdictosAnalizados.'/'.$nombreProvincia.'/'.$carpetaValoracion)) {
            mkdir($carpetaEdictosAnalizados.'/'.$nombreProvincia.'/'.$carpetaValoracion, 0777, true);
        }
        
        // Guarda el archivo JSON
        $archivoJson = fopen($carpetaEdictosAnalizados.'/'.$nombreProvincia.'/'.$carpetaValoracion.'/'.$nombreArchivoJson, "w");
        fwrite($archivoJson, $json);
        fclose($archivoJson);

        // Guarda el archivo de texto para pantalla
        $archivoTxtPantalla = fopen($carpetaEdictosAnalizados.'/'.$nombreProvincia.'/'.$carpetaValoracion.'/'.$nombreArchivoTxtPantalla, "w");        
        fwrite($archivoTxtPantalla, $contenidoTxtPantalla);
        fclose($archivoTxtPantalla);

        // Mueve el archivo de texto original
        if (file_exists($txtPath)) {
            rename($txtPath, $carpetaEdictosAnalizados.'/'.$nombreProvincia.'/'.'originales/'.$nombreArchivoTxt);
        }

        // Reviso la carpeta y obtengo la lista de archivos
        $files = array_diff(scandir($carpeta), ['..', '.']);            
        $files = array_values($files);
        $cantEdictos = count($files);

        $archivosRutas = [];  // Array para almacenar las rutas completas de los archivos

        foreach ($files as $file) {
            $archivosRutas[] = $carpeta . '/' . $file;  // Agrega la ruta completa al array
        }
                                    
        return response()->json([
            'cantidad' => $cantEdictos,
            'archivos' => $archivosRutas
        ]);
    }

    /**
    * Guarda archivos de texto subidos en una carpeta especifica de la provincia
    * Si un archivo ya existe en la carpeta de destino, no se sobrescribe de lo contrario, lo escribe
    *
    * @return int Retorna 1 si los archivos han sido procesados, de lo contrario retorna 0
    */
    public function guardarArchivosTxt(){
        // Verifica si se subieron archivos
        if (isset($_FILES['archivosTxtProvincia'])){
            // Obtiene los nombres de los archivos subidos
            $archivos = $_FILES['archivosTxtProvincia']['name'];
            // Obtiene el nombre de la carpeta de la provincia desde la solicitud
            $carpetaProvincia = Request::input('carpetasProvincias');
            
            $provinciaReferencia = basename($carpetaProvincia);
            $archivosGrabados = [];
            $archivosNoGrabados = [];

            foreach ($archivos as $key => $archivo) {
                $provinciaArchivo = self::obtenerProvincia($archivo);                
                if ($provinciaArchivo == $provinciaReferencia) {
                    // Se arma la ruta completa del archivo para guardarse en la carpeta de la provincia
                    $pathArchivo = $carpetaProvincia . '/' . $archivo;                                    
                    $rutaTemporal = $_FILES['archivosTxtProvincia']['tmp_name'][$key];
                    
                    // Verifica si el archivo ya existe en la carpeta de destino
                    if (!file_exists($pathArchivo)) {
                        move_uploaded_file($rutaTemporal, $pathArchivo);
                    }
                    array_push($archivosGrabados, $archivo);
                }else {
                    array_push($archivosNoGrabados, $archivo);
                }
               
            }            
            // Retorna 1 si los archivos fueron procesados
            //return 1;
            return response()->json([
                'exito' => 1,
                'archivosNoGrabados' => $archivosNoGrabados
            ]);
        } else {
            // Retorna 0 si los archivos no fueron procesados
            //return 0;
            return response()->json([
                'exito' => 0,
                'archivosNoGrabados' => ''
            ]);
        }
    }

    /**
    * Obtiene el nombre de la provincia a partir del nombre de un archivo
    *
    * @param string $nombreArchivo El nombre del archivo del cual se extrae la provincia
    * @return string El nombre de la provincia
    */
    public static function obtenerProvincia($nombreArchivo) {
        // Dividir el nombre del archivo en partes usando el guion bajo como separador
        $partes = explode('_', $nombreArchivo);
        return $partes[0]; // Devuelve la primera parte que se asume como el nombre de la provincia
    }

    /**
    * Obtiene la lista de archivos analizados en una carpeta especifica
    *
    * Esta funcion toma la ruta de una carpeta para obtener 
    * los archivos, y devuelve una lista de archivos que tienen una version .txt y .txt.json
    *
    * @return \Illuminate\Http\JsonResponse respuesta en formato JSON con la cantidad de archivos y la lista de archivos encontrados
    */
    public static function obtenerArchivosAnalizados() {
        $valoracionCarpeta = Request::input('valoracionCarpeta');

        $carpeta = Request::input('carpeta');
        $carpeta = $carpeta . '/' . $valoracionCarpeta;                        

        // Escanea la carpeta y elimina las referencias a la carpeta actual y la carpeta padre
        $archivos = array_diff(scandir($carpeta), ['..', '.']);

        // Reindexa el array de archivos para que las claves sean numericas y consecutivas
        $archivos = array_values($archivos);

        // Obtiene la cantidad de archivos
        $cantEdictos = count($archivos);

        // Combina la ruta de la carpeta con el nombre de cada archivo para obtener la ruta completa
        foreach ($archivos as $key => $archivo) {
            $archivos[$key] = $carpeta . '/' . $archivo;
        }               

        // Clasifica los archivos en arrays de .txt y .txt.json
        $arrayTxt = [];
        $arrayJson = [];
        foreach ($archivos as $archivo) {
            if (strpos($archivo, '.txt.json') !== false) {
                $arrayJson[] = $archivo;
            } elseif (strpos($archivo, '.txt') !== false) {
                $arrayTxt[] = $archivo;
            }
        }

        // Empareja los archivos .txt con sus correspondientes .txt.json
        $archivosMatch = [];
        foreach ($arrayTxt as $txt) {
            $nombreTxt = basename($txt, ".txt");
            foreach ($arrayJson as $json) {
                $nombreJson = basename($json, ".txt.json");
                if ($nombreTxt === $nombreJson) {
                    $archivosMatch[] = [
                        'txt' => $txt,
                        'json' => $json
                    ];
                }
            }
        }

        $cantEdictos = floatval($cantEdictos) / 2;
        
        return response()->json([
            'cantidad' => $cantEdictos,
            'archivos' => $archivosMatch
        ]);
    }

    /**
    * Guarda la comparacion entre archivos JSON y TXT, moviendolos a una carpeta correspondiente dependiendo su valoracion
    *
    * Esta función recibe las rutas de los archivos, el estado de la valoración y otros datos
    * Despues mueve los archivos a una carpeta basada en su valoracion y devuelve una lista de archivos en la carpeta
    *
    * @return \Illuminate\Http\JsonResponse Respuesta en formato JSON con la cantidad de archivos y la lista de archivos encontrados
    */
    public function guardarComparacionJsonTxt() {
        
        $pathCarpetaPadre = Request::input('archivosAnalisisComp');
        $valoracion = Request::input('estado_valoracion');
        $txtPath = Request::input('nombreTxt');
        $jsonPath = Request::input('nombreJson');
        $valoracion_nueva = Request::input('valoracionJson');
        $carpeta = Request::input('carpetaPrincipal');
                                
        if ($valoracion_nueva == 1) {
            $contenidoNuevoTxt = Request::input('contenidoTxt');
            $contenidonuevoJson = Request::input('contenidoJson');

            if (file_get_contents($txtPath) != $contenidoNuevoTxt) {
                file_put_contents($txtPath, $contenidoNuevoTxt);
            }

            if (file_get_contents($jsonPath) != $contenidonuevoJson) {
                file_put_contents($jsonPath, $contenidonuevoJson);                
            }                        
        }              
                
        // Asigna un string a la nueva valoracion
        switch ($valoracion_nueva) {
            case 0:
                $valoracion_nueva = 'aprobado';
                break;
            case 1:
                $valoracion_nueva = 'editado';
                break;
            case 2:
                $valoracion_nueva = 'rechazado';
                break;
            default:
                $valoracion_nueva = 'desconocido';
        }
    
        // Validación de entradas
        if (!$pathCarpetaPadre || !$valoracion || !$txtPath || !$jsonPath) {
            return response()->json(['error' => 'Datos incompletos'], 400);
        }
    
        // Determina el path de destino
        $archivoPathNuevo = $pathCarpetaPadre;
        if ($valoracion_nueva !== 'desconocido') {
            $archivoPathNuevo .= '/' . $valoracion_nueva;
        }
    
        // Crear la carpeta si no existe
        if (!is_dir($archivoPathNuevo)) {
            if (!mkdir($archivoPathNuevo, 0777, true)) {
                return response()->json(['error' => 'No se pudo crear la carpeta destino'], 500);
            }
        }
    
        // Obtener solo el nombre del archivo
        $nombreArchivoTxt = basename($txtPath);
        $nombreArchivoJson = basename($jsonPath);
        $nuevoArchivoPathJson = $archivoPathNuevo . '/' . $nombreArchivoJson;  
        $nuevoArchivoPathTxt = $archivoPathNuevo . '/' . $nombreArchivoTxt;
        
        // Mover los archivos a la nueva ubicación
        if (!rename($txtPath, $nuevoArchivoPathTxt)) {
            return response()->json(['error' => 'No se pudo mover el archivo TXT'], 500);
        }
        if (!rename($jsonPath, $nuevoArchivoPathJson)) {
            return response()->json(['error' => 'No se pudo mover el archivo JSON'], 500);
        }
        
        // Revisa la carpeta y obtiene la lista de archivos
        $carpeta = $carpeta . '/' . $valoracion;
        $files = array_diff(scandir($carpeta), ['..', '.']);            
        $files = array_values($files);
        $cantEdictos = count($files);
        
        // Almacena las rutas completas de los archivos
        $archivosRutas = [];
        foreach ($files as $file) {
            $archivosRutas[] = $carpeta . '/' . $file;
        }
        
        // Clasifica los archivos en arrays de .txt y .txt.json
        $arrayTxt = [];
        $arrayJson = [];
        foreach ($files as $archivo) {
            if (strpos($archivo, '.txt.json') !== false) {
                $arrayJson[] = $carpeta . '/' . $archivo;
            } elseif (strpos($archivo, '.txt') !== false) {
                $arrayTxt[] = $carpeta . '/' . $archivo;
            }
        }
        
        // Empareja los archivos .txt con sus correspondientes .txt.json
        $archivosMatch = [];
        foreach ($arrayTxt as $txt) {
            $nombreTxt = basename($txt, ".txt");
            foreach ($arrayJson as $json) {
                $nombreJson = basename($json, ".txt.json");
                if ($nombreTxt === $nombreJson) {
                    $archivosMatch[] = [
                        'txt' => $txt,
                        'json' => $json
                    ];
                }
            }
        }
             
        if(count($archivosMatch) > 1){
            // Buscar el indice del elemento       
            $index = array_search($jsonPath, array_column($archivosMatch, 'json'));

            // Si el elemento se encuentra, moverlo al final del array
            if ($index !== false) {
                $element = $archivosMatch[$index]; // Guardar el elemento encontrado
                unset($archivosMatch[$index]); // Eliminar el elemento del array
                $archivosMatch[] = $element; // Agregar el elemento al final del array
                $archivosMatch = array_values($archivosMatch); // Reindexar el array
            }
        }
       
        
        $cantEdictos = floatval($cantEdictos) / 2;                        
        
        return response()->json([
            'cantidad' => $cantEdictos,
            'archivos' => $archivosMatch
        ]);               
    }   
          

    public static function ProcesarEdictosANTERIOR()
    {
        
        /*
        Estructura de json con todos los nodos para la devolución de Editos
        {
            "Datos_Empresa": {
                "nombre_actual": "",
                "nombre_anterior": "",
                "cuit_empresa": "",
                "domicilio_actual": "",
                "domicilio_anterior": "",
                "empresa_tipo": ""
            },
            "Relacion_Personas":  [
                {
                    "apellido_nombre": "",
                    "persona_DNI": "",
                    "persona_cuit": "",
                    "persona_domicilio": "",
                    "persona_estado_civil": "",
                    "persona_conyuge": "",
                    "Persona_Cargo": [
                        {
                            "p_rol": ""
                        }
                    ],
                    "permanece_en_cargo?": ""
                }
            ],
            "Relacion_Empresas":  [
                {
                    "Vinculada_nombre": "",
                    "Vinculada_cuit": "",
                    "Vinculada_Pais": "",
                    "Vinculada_domicilio": "",
                    "Vinculada_vinculo": [
                        {
                            "e_rol": ""
                        }
                    ]
                }
            ],
            "Datos_Generales": {
                "tipo_edicto": "",
                "fecha_asamblea": ""
            }
        }*/

        $fuente = null;

        $ruta = env('PATH_COMPARTIDO');
        $arch = '/openAIBatch/batch_output.jsonl'; 
        $file = $ruta . $arch; 
        $archinput = '/openAIBatch/batchinput.jsonl'; 
        $fileinput = $ruta .$archinput; 

        if (!file_exists($file)){   
            return json_encode('fallo file output'); 
        } 
        if (!file_exists($fileinput)){   
            return json_encode('fallo file input'); 
        }    
        
        $archivo = file($file);
        $archivoinput = file($fileinput);

        
        foreach ($archivo as $key => $linea) {
            $linea = str_replace('permanece_en_cargo?','permanece_en_cargo',$linea);
            $file_editable = json_decode($linea,false); 
            $custom_id = $file_editable->custom_id; 
            $partes = explode('_', $custom_id);
            $id_fide = $partes[2] ?? 0; 
            if ($id_fide !== '4379569')
            {
                continue;
            }
            
            echo('<br><br>-----------------------------------------------');
            echo('<br>id_fide: ' . $id_fide); 
            
            //var_dump('custom_id: ');
            //var_dump($custom_id);   
            //var_dump('id_fide: ');   
            //var_dump($id_fide); die(); 
            
            // Buscamos el texto del edicto en el archivo input 
            $texto_edicto = new stdClass; 
            $texto_edicto = null;
            //No hace falta porque ya lo tenemos en la tabla sociedades_constituciones 
            //foreach ($archivoinput as $keyinput => $lineainput) {
                //$file_editable_input = json_decode($lineainput,false); 
                //if ($file_editable_input->custom_id == $custom_id)
                //{
                    //$texto_edicto = ($file_editable_input->body->messages[2]->content);
                    //break; 
                //}
            //}

            $datos = $file_editable->response->body->choices;
            foreach($datos as $key2 => $value)
                {

                try {

                    $txt_json = new stdClass();
                    $txt_json = $value->message->content; 
                    $txt_json = str_replace(['```json', '```'], '', $txt_json);
                    $datos2 = json_decode($txt_json);  
                    /*
                    "Datos_Empresa": {
                        "nombre_actual": "",
                        "nombre_anterior": "",
                        "cuit_empresa": "",
                        "domicilio_actual": "",
                        "domicilio_anterior": "",
                        "empresa_tipo": ""
                    },
                    "Datos_Generales": {
                        "tipo_edicto": "",
                        "fecha_asamblea": ""
                    }
                    */

                    $Datos_Empresa     = new stdClass();
                    $Datos_Generales   = new stdClass();
                    $Relacion_Personas = [];
                    $Relacion_Empresas = [];
                    $Datos_Empresa     = $datos2->Datos_Empresa ?? null;
                    $Relacion_Personas = $datos2->Relacion_Personas ?? [];
                    $Relacion_Empresas = $datos2->Relacion_Empresas ?? [];
                    $Datos_Generales   = $datos2->Datos_Generales ?? null;
                    /*
                    var_dump("\n\nDatos_Empresa:\n");
                    var_dump($Datos_Empresa);  
                    var_dump("Relacion_Personas:\n");
                    */
                    //dd($Relacion_Personas);  
                    /*
                    var_dump("Relacion_Empresas:\n");
                    var_dump($Relacion_Empresas);   
                    var_dump("Datos_Generales:\n");
                    var_dump($Datos_Generales);  
                    */
                    $nombre_actual = new stdClass(); 
                    $nombre_actual = null;
                    if (isset($Datos_Empresa->nombre_actual) && is_array($Datos_Empresa->nombre_actual))
                        {
                        $nombre_actual = implode(";",$Datos_Empresa->nombre_actual);
                        }

                    if (isset($Datos_Empresa->nombre_actual) && !is_array($Datos_Empresa->nombre_actual))
                        {
                        $nombre_actual = $Datos_Empresa->nombre_actual;
                        }

                    $nombre_anterior = new stdClass(); 
                    $nombre_anterior = null;
                    if (isset($Datos_Empresa->nombre_anterior) && is_array($Datos_Empresa->nombre_anterior))
                        {
                        $nombre_anterior = implode(";",$Datos_Empresa->nombre_anterior);
                        }

                    if (isset($Datos_Empresa->nombre_anterior) && !is_array($Datos_Empresa->nombre_anterior))
                        {
                        $nombre_anterior = $Datos_Empresa->nombre_anterior;
                        }

                    $cuit_empresa = new stdClass(); 
                    $cuit_empresa = null;
                    if (isset($Datos_Empresa->cuit_empresa) && is_array($Datos_Empresa->cuit_empresa))
                        {
                        $cuit_empresa = implode(";",$Datos_Empresa->cuit_empresa);
                        }

                    if (isset($Datos_Empresa->cuit_empresa) && !is_array($Datos_Empresa->cuit_empresa))
                        {
                        $cuit_empresa = $Datos_Empresa->cuit_empresa;
                        }

                    $domicilio_actual = new stdClass(); 
                    $domicilio_actual = null;
                    if (isset($Datos_Empresa->domicilio_actual) && is_array($Datos_Empresa->domicilio_actual))
                        {
                        $domicilio_actual = implode(";",$Datos_Empresa->domicilio_actual);
                        }

                    if (isset($Datos_Empresa->domicilio_actual) && !is_array($Datos_Empresa->domicilio_actual))
                        {
                        $domicilio_actual = $Datos_Empresa->domicilio_actual;
                        }

                    $domicilio_anterior = new stdClass(); 
                    $domicilio_anterior = null;
                    if (isset($Datos_Empresa->domicilio_anterior) && is_array($Datos_Empresa->domicilio_anterior))
                        {
                        $domicilio_anterior = implode(";",$Datos_Empresa->domicilio_anterior);
                        }

                    if (isset($Datos_Empresa->domicilio_anterior) && !is_array($Datos_Empresa->domicilio_anterior))
                        {
                        $domicilio_anterior = $Datos_Empresa->domicilio_anterior;
                        }

                    $empresa_tipo = new stdClass(); 
                    $empresa_tipo = null;
                    if (isset($Datos_Empresa->empresa_tipo) && is_array($Datos_Empresa->empresa_tipo))
                        {
                        $empresa_tipo = implode(";",$Datos_Empresa->empresa_tipo);
                        }

                    if (isset($Datos_Empresa->empresa_tipo) && !is_array($Datos_Empresa->empresa_tipo))
                        {
                        $empresa_tipo = $Datos_Empresa->empresa_tipo;
                        }

                    $tipo_edicto = new stdClass(); 
                    $tipo_edicto = null;
                    if (isset($Datos_Generales->tipo_edicto) && is_array($Datos_Generales->tipo_edicto))
                        {
                        $tipo_edicto = implode(";",$Datos_Generales->tipo_edicto);
                        }

                    if (isset($Datos_Generales->tipo_edicto) && !is_array($Datos_Generales->tipo_edicto))
                        {
                        $tipo_edicto = $Datos_Generales->tipo_edicto;
                        }

                    $fecha_asamblea = new stdClass(); 
                    $fecha_asamblea = null;
                    if (isset($Datos_Generales->fecha_asamblea) && is_array($Datos_Generales->fecha_asamblea))
                        {
                        $fecha_asamblea = implode(";",$Datos_Generales->fecha_asamblea);
                        }

                    if (isset($Datos_Generales->fecha_asamblea) && !is_array($Datos_Generales->fecha_asamblea))
                        {
                        $fecha_asamblea = $Datos_Generales->fecha_asamblea;
                        }
                       
                    $params = [];
                    $params[] = $id_fide;
                    $params[] = 'update';
                    $params[] = Session::get('usuario')->user_id ?? '0';
                    $params[] = $nombre_actual ?? null;
                    $params[] = $nombre_anterior ?? null;
                    $params[] = $cuit_empresa ?? null;
                    $params[] = $domicilio_actual ?? null;
                    $params[] = $domicilio_anterior ?? null;
                    $params[] = $empresa_tipo ?? null;
                    $params[] = $tipo_edicto ?? null;
                    $params[] = $arch ?? null;
                    $params[] = $fuente ?? null;

                    // Update en sociedades_constituciones de los Datos_Empresa y Datos_Generales, si algun dato le falta
                    $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');

                } catch (\Throwable $th) {
                    $params = [];
                    $params[] = $id_fide;
                    $params[] = 'error_2';
                    $params[] = Session::get('usuario')->user_id ?? '0';
                    $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
                }

                try {        
                    echo('<br>Procesando registro : ' . $key . ' - custon_id = ' . $custom_id);
                    echo('<br>Fecha: ' . ($fecha_asamblea ?? '') . '<br>');
                    //echo(var_dump($datos2));
                    echo('<br>Datos Empresa: ' . ($nombre_actual ?? '') . ' - id = ' . ($id_fide ?? '0'));
                    $paramsJson = [];
                    $paramsJson[] = 'insert';
                    $paramsJson[] = $id_fide ?? '0'; 
                    $paramsJson[] = $arch ?? null;
                    $paramsJson[] = $custom_id ?? null;
                    $paramsJson[] = $txt_json; 
                    $paramsJson[] = Session::get('usuario')->user_id ?? '0';
                    $txt_json = SQLConnection::backendStoreProcedure('dbo.openai_insert_json', $paramsJson, 'selectOne'); 
                    echo('<br>Text Json: - id = ' . ($txt_json->id ?? '0'));
                } catch (\Throwable $th) {
                    $params = [];
                    $params[] = $id_fide;
                    $params[] = 'error_3';
                    $params[] = Session::get('usuario')->user_id ?? '0';
                    $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
                }            

                    /*
                    Relacion_Personas":  [
                                    {
                                        "apellido_nombre": "",
                                        "persona_DNI": "",
                                        "persona_cuit": "",
                                        "persona_domicilio": "",
                                        "persona_estado_civil": "",
                                        "persona_conyuge": "",
                                        "Persona_Cargo": [
                                            {
                                                "p_rol": ""
                                            }
                                        ],
                                        "permanece_en_cargo?": ""
                                    }
                                ],
                    */
                    foreach ($Relacion_Personas as $RP => $valueRP) 
                    {
                                dd($valueRP); 

                    try {
                        $cargos = []; 
                        $cargos = $valueRP->Persona_Cargo ?? ($valueRP->p_rol ?? []);

                        if (isset($valueRP->Persona_Cargo) && is_array($valueRP->Persona_Cargo))
                        {
                            $cargos = $valueRP->Persona_Cargo;
                        }
                        elseif (isset($valueRP->Persona_Cargo) && is_array($valueRP->Persona_Cargo))
                        {
                            $cargos[] = $valueRP->Persona_Cargo;
                        }
                        elseif (isset($valueRP->p_rol) && is_array($valueRP->p_rol))
                        {
                            $cargos = $valueRP->p_rol;
                        }
                        elseif (isset($valueRP->p_rol) && !is_array($valueRP->p_rol))
                        {
                            $cargos[] = $valueRP->p_rol;
                        }

                        if (count($cargos) == 0)
                        {
                            $paramsRP = [];
                            $paramsRP[] = 'insert';
                            $paramsRP[] = $id_fide ?? '0'; 
                            $paramsRP[] = $valueRP->apellido_nombre ?? null;
                            $paramsRP[] = $valueRP->persona_DNI ?? null;
                            $paramsRP[] = $valueRP->persona_cuit ?? null;
                            $paramsRP[] = $valueRP->persona_domicilio ?? null;
                            $paramsRP[] = $valueRP->persona_estado_civil ?? null;
                            $paramsRP[] = $valueRP->persona_conyuge ?? null;
                            $paramsRP[] = null;
                            $paramsRP[] = $valueRP->permanece_en_cargo ?? null;
                            $paramsRP[] = Session::get('usuario')->user_id ?? '0';
                            $personas = SQLConnection::backendStoreProcedure('dbo.openai_insert_personas', $paramsRP, 'selectOne'); 
                            echo('<br>1 - Relacion_Personas: ' . ($valueRP->apellido_nombre ?? '') . ' - id = ' . ($personas->id ?? '0'));
                        }
                        else 
                        {
                            foreach ($cargos as $RP2 => $valueRP2) {
                                $paramsRP = [];
                                $paramsRP[] = 'insert';
                                $paramsRP[] = $id_fide ?? '0'; 
                                $paramsRP[] = $valueRP->apellido_nombre ?? null;
                                $paramsRP[] = $valueRP->persona_DNI ?? null;
                                $paramsRP[] = $valueRP->persona_cuit ?? null;
                                $paramsRP[] = $valueRP->persona_domicilio ?? null;
                                $paramsRP[] = $valueRP->persona_estado_civil ?? null;
                                $paramsRP[] = $valueRP->persona_conyuge ?? null;
                                $paramsRP[] = $valueRP2->p_rol ?? null;
                                $paramsRP[] = $valueRP->permanece_en_cargo ?? null;
                                $paramsRP[] = Session::get('usuario')->user_id ?? '0';

                                // Insert en [sociedades_constituciones_relaciones_personas]
                                $personas = SQLConnection::backendStoreProcedure('dbo.openai_insert_personas', $paramsRP, 'selectOne'); 
                                echo('<br>2 - Relacion_Personas: ' . ($valueRP->apellido_nombre ?? '') . ' - cargo = ' . ($valueRP2->p_rol ?? '')); 
                                echo(' - Permanece en cargo = ' . ($valueRP->permanece_en_cargo ?? ''). ' - id = ' . ($personas->id ?? '0'));
                            }
                        }
                    } catch (\Throwable $th) {
                    $params = [];
                    $params[] = $id_fide;
                    $params[] = 'error_4';
                    $params[] = Session::get('usuario')->user_id ?? '0';
                    $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
                    }

                    }

                    /*
                     "Relacion_Empresas":  [
                        {
                            "Vinculada_nombre": "",
                            "Vinculada_cuit": "",
                            "Vinculada_Pais": "",
                            "Vinculada_domicilio": "",
                            "Vinculada_vinculo": [
                                {
                                    "e_rol": ""
                                }
                            ]
                        }
                    ],
                    */
                    foreach ($Relacion_Empresas as $RE => $valueRE) {
                    try {
                        $vinculos = []; 
                        if (isset($valueRE->Vinculada_vinculo) && is_array($valueRE->Vinculada_vinculo))
                        {
                            $vinculos = $valueRE->Vinculada_vinculo;
                        }
                        else 
                        if (isset($valueRE->Vinculada_vinculo) && !is_array($valueRE->Vinculada_vinculo))
                        {
                            $vinculos[] = $valueRE->Vinculada_vinculo;
                        }
                        if (count($vinculos) == 0)
                        {
                            $paramsRE = [];
                            $paramsRE[] = 'insert';
                            $paramsRE[] = $id_fide ?? '0'; 
                            $paramsRE[] = $valueRE->Vinculada_nombre ?? null;
                            $paramsRE[] = $valueRE->Vinculada_cuit ?? null;
                            $paramsRE[] = $valueRE->Vinculada_Pais ?? null;
                            $paramsRE[] = $valueRE->Vinculada_domicilio ?? null;
                            $paramsRE[] = null;
                            $paramsRE[] = Session::get('usuario')->user_id ?? '0';

                            // Insert en [sociedades_constituciones_relaciones_vinculadas]
                            $vinculadas = SQLConnection::backendStoreProcedure('dbo.openai_insert_vinculadas', $paramsRE, 'selectOne'); 
                            echo('<br>1 - Relacion_Empresas: ' . ($valueRE->Vinculada_nombre ?? '') . ' - id = ' . ($vinculadas->id ?? '0'));
                        }
                        else 
                        {
                            foreach ($vinculos as $RE2 => $valueRE2) {
                                $paramsRE = [];
                                $paramsRE[] = 'insert';
                                $paramsRE[] = $id_fide ?? '0'; 
                                $paramsRE[] = $valueRE->Vinculada_nombre ?? null;
                                $paramsRE[] = $valueRE->Vinculada_cuit ?? null;
                                $paramsRE[] = $valueRE->Vinculada_Pais ?? null;
                                $paramsRE[] = $valueRE->Vinculada_domicilio ?? null;
                                $paramsRE[] = $valueRE2->e_rol ?? null;
                                $paramsRE[] = Session::get('usuario')->user_id ?? '0';

                                // Insert en [sociedades_constituciones_relaciones_vinculadas]
                                $vinculadas = SQLConnection::backendStoreProcedure('dbo.openai_insert_vinculadas', $paramsRE, 'selectOne'); 
                                echo('<br>2 - Relacion_Empresas: ' . ($valueRE->Vinculada_nombre ?? '') . ' - id = ' . ($vinculadas->id ?? '0'));
                            }
                        }

                    } catch (\Throwable $th) {
                    $params = [];
                    $params[] = $id_fide;
                    $params[] = 'error_5';
                    $params[] = Session::get('usuario')->user_id ?? '0';
                    $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
                    }

                    }

                }


        }

     
        
    }

    public static function ProcesarEdictosDB(){
        $path = env('BATCH_PATH_OUTPUT');

        if (is_dir($path)) {
            $files = array_diff(scandir($path), array('.', '..'));

            if (!empty($files)) {
                foreach ($files as $file) {
                    $fullPath = $path . DIRECTORY_SEPARATOR . $file;
                    if (is_file($fullPath)) {
                        self::ProcesarEdictoAutomatico($fullPath);

                        // Mover archivo a la carpeta "procesado"
                        $destino = env('BATCH_PATH_OUTPUT_PROCESADO');

                        // Crear el directorio de destino si no existe
                        if (!is_dir($destino)) {
                            if (!mkdir($destino, 0777, true)) {
                                echo "Error: No se pudo crear el directorio de destino ($destino).\n";
                                return;
                            }
                        }
                        // Agregar el nombre del archivo al destino
                        $destinoFinal = $destino . DIRECTORY_SEPARATOR . $file;

                        if (rename($fullPath, $destinoFinal)) {
                            echo "El archivo $file ha sido procesado y movido a 'procesado'.\n";
                        } else {
                            echo "Error al mover el archivo $file.\n";
                        }
                    }
                }
            } else {
                echo "El directorio no contiene archivos.\n";
            }
        } else {
            echo "El directorio no existe.\n";
        }
    }

    public static function ProcesarEdictoAutomatico($path){
        
        $fechaHoy = Misc::obtenerDiaDeHoy();        
        $fuente = null;
        $ruta = env('PATH_COMPARTIDO');         
        $arch = $path;  
        $file = $path;
       
        if (!file_exists($file)){   
            return json_encode('No se encontro un archivo para procesar'); 
        }        
        
        $archivo = file($file);        

        
        foreach ($archivo as $key => $linea) {
            $linea = str_replace('permanece_en_cargo?','permanece_en_cargo',$linea);
            $file_editable = json_decode($linea,false); 
            $custom_id = $file_editable->custom_id; 
            $partes = explode('_', $custom_id);
            $id_fide = $partes[2] ?? 0; 
                      
            echo('<br><br>-----------------------------------------------');
            echo('<br>id_fide: ' . $id_fide); 
            
            /* Si ya fue procesado lo salteo, si se quiere volver a procesar sacar esto */
            $params = [];
            $params[] = $id_fide;
            $params[] = 'control_ya_procesado';            
            $control_ya_procesado = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
            if ($control_ya_procesado->procesado == 1)
            {
                echo(' -- YA ESTABA PROCESADO --'); 
                continue;
            }          
            
            // Buscamos el texto del edicto en el archivo input 
            $texto_edicto = new stdClass; 
            $texto_edicto = null;                     

            $datos = $file_editable->response->body->choices;
            foreach($datos as $key2 => $value){

                try {

                    $txt_json = new stdClass();
                    $txt_json = $value->message->content; 
                    $txt_json = str_replace(['```json', '```'], '', $txt_json);
                    $datos2 = json_decode($txt_json,false);                    

                    $Datos_Empresa     = new stdClass();
                    $Datos_Generales   = new stdClass();
                    $Relacion_Personas = [];
                    $Relacion_Empresas = [];
                    $Datos_Empresa     = $datos2->Datos_Empresa ?? null;
                    $Datos_Generales   = $datos2->Datos_Generales ?? null;

                    if (isset($datos2->Relacion_Personas) && is_array($datos2->Relacion_Personas))
                        {
                        $Relacion_Personas = $datos2->Relacion_Personas;
                        }
                    if (isset($datos2->Relacion_Personas) && !is_array($datos2->Relacion_Personas))
                        {
                        $Relacion_Personas[] = $datos2->Relacion_Personas; 
                        }

                     if (isset($datos2->Relacion_Empresas) && is_array($datos2->Relacion_Empresas))
                        {
                        $Relacion_Empresas = $datos2->Relacion_Empresas;
                        }
                    if (isset($datos2->Relacion_Empresas) && !is_array($datos2->Relacion_Empresas))
                        {
                        $Relacion_Empresas[] = $datos2->Relacion_Empresas; 
                        }
                       
                    
                    $nombre_actual = new stdClass(); 
                    $nombre_actual = null;
                    if (isset($Datos_Empresa->nombre_actual) && is_array($Datos_Empresa->nombre_actual))
                        {
                        $nombre_actual = implode(";",$Datos_Empresa->nombre_actual);
                        }

                    if (isset($Datos_Empresa->nombre_actual) && !is_array($Datos_Empresa->nombre_actual))
                        {
                        $nombre_actual = $Datos_Empresa->nombre_actual;
                        }

                    $nombre_anterior = new stdClass(); 
                    $nombre_anterior = null;
                    if (isset($Datos_Empresa->nombre_anterior) && is_array($Datos_Empresa->nombre_anterior))
                        {
                        $nombre_anterior = implode(";",$Datos_Empresa->nombre_anterior);
                        }

                    if (isset($Datos_Empresa->nombre_anterior) && !is_array($Datos_Empresa->nombre_anterior))
                        {
                        $nombre_anterior = $Datos_Empresa->nombre_anterior;
                        }

                    $cuit_empresa = new stdClass(); 
                    $cuit_empresa = null;
                    if (isset($Datos_Empresa->cuit_empresa) && is_array($Datos_Empresa->cuit_empresa))
                        {
                        $cuit_empresa = implode(";",$Datos_Empresa->cuit_empresa);
                        }

                    if (isset($Datos_Empresa->cuit_empresa) && !is_array($Datos_Empresa->cuit_empresa))
                        {
                        $cuit_empresa = $Datos_Empresa->cuit_empresa;
                        }

                    $domicilio_actual = new stdClass(); 
                    $domicilio_actual = null;
                    if (isset($Datos_Empresa->domicilio_actual) && is_array($Datos_Empresa->domicilio_actual))
                        {
                        $domicilio_actual = implode(";",$Datos_Empresa->domicilio_actual);
                        }

                    if (isset($Datos_Empresa->domicilio_actual) && !is_array($Datos_Empresa->domicilio_actual))
                        {
                        $domicilio_actual = $Datos_Empresa->domicilio_actual;
                        }

                    $domicilio_anterior = new stdClass(); 
                    $domicilio_anterior = null;
                    if (isset($Datos_Empresa->domicilio_anterior) && is_array($Datos_Empresa->domicilio_anterior))
                        {
                        $domicilio_anterior = implode(";",$Datos_Empresa->domicilio_anterior);
                        }

                    if (isset($Datos_Empresa->domicilio_anterior) && !is_array($Datos_Empresa->domicilio_anterior))
                        {
                        $domicilio_anterior = $Datos_Empresa->domicilio_anterior;
                        }

                    $empresa_tipo = new stdClass(); 
                    $empresa_tipo = null;
                    if (isset($Datos_Empresa->empresa_tipo) && is_array($Datos_Empresa->empresa_tipo))
                        {
                        $empresa_tipo = implode(";",$Datos_Empresa->empresa_tipo);
                        }

                    if (isset($Datos_Empresa->empresa_tipo) && !is_array($Datos_Empresa->empresa_tipo))
                        {
                        $empresa_tipo = $Datos_Empresa->empresa_tipo;
                        }

                    $tipo_edicto = new stdClass(); 
                    $tipo_edicto = null;
                    if (isset($Datos_Generales->tipo_edicto) && is_array($Datos_Generales->tipo_edicto))
                        {
                        $tipo_edicto = implode(";",$Datos_Generales->tipo_edicto);
                        }

                    if (isset($Datos_Generales->tipo_edicto) && !is_array($Datos_Generales->tipo_edicto))
                        {
                        $tipo_edicto = $Datos_Generales->tipo_edicto;
                        }

                    $fecha_asamblea = new stdClass(); 
                    $fecha_asamblea = null;
                    if (isset($Datos_Generales->fecha_asamblea) && is_array($Datos_Generales->fecha_asamblea))
                        {
                        $fecha_asamblea = implode(";",$Datos_Generales->fecha_asamblea);
                        }

                    if (isset($Datos_Generales->fecha_asamblea) && !is_array($Datos_Generales->fecha_asamblea))
                        {
                        $fecha_asamblea = $Datos_Generales->fecha_asamblea;
                        }
                       
                    $params = [];
                    $params[] = $id_fide;
                    $params[] = 'update';
                    $params[] = Session::get('usuario')->user_id ?? '0';
                    $params[] = $nombre_actual ?? null;
                    $params[] = $nombre_anterior ?? null;
                    $params[] = $cuit_empresa ?? null;
                    $params[] = $domicilio_actual ?? null;
                    $params[] = $domicilio_anterior ?? null;
                    $params[] = $empresa_tipo ?? null;
                    $params[] = $tipo_edicto ?? null;
                    $params[] = $arch ?? null;
                    $params[] = $fuente ?? null;

                    // Update en sociedades_constituciones de los Datos_Empresa y Datos_Generales, si algun dato le falta
                    $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');

                } catch (\Throwable $th) {
                    $params = [];
                    $params[] = $id_fide;
                    $params[] = 'error_2';
                    $params[] = Session::get('usuario')->user_id ?? '0';
                    $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
                }

                try {        
                    echo('<br>Procesando registro : ' . $key . ' - custon_id = ' . $custom_id);
                    echo('<br>Fecha: ' . ($fecha_asamblea ?? '') . '<br>');
                    //echo(var_dump($datos2));
                    echo('<br>Datos Empresa: ' . ($nombre_actual ?? '') . ' - id = ' . ($id_fide ?? '0'));
                    $paramsJson = [];
                    $paramsJson[] = 'insert';
                    $paramsJson[] = $id_fide ?? '0'; 
                    $paramsJson[] = $tipo_edicto ?? null;
                    $paramsJson[] = $arch ?? null;
                    $paramsJson[] = $custom_id ?? null;
                    $paramsJson[] = $txt_json; 
                    $paramsJson[] = Session::get('usuario')->user_id ?? '0';
                    $txt_json = SQLConnection::backendStoreProcedure('dbo.openai_insert_json', $paramsJson, 'selectOne');                     
                    echo('<br>Text Json: - id = ' . ($txt_json->id ?? '0'));
                } catch (\Throwable $th) {
                    $params = [];
                    $params[] = $id_fide;
                    $params[] = 'error_3';
                    $params[] = Session::get('usuario')->user_id ?? '0';
                    $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
                }            


                foreach ($Relacion_Personas as $RP => $valueRP) {
                    try {
                        $cargos = []; 
                        $cargos = $valueRP->Persona_Cargo ?? ($valueRP->p_rol ?? []);

                        if (isset($valueRP->Persona_Cargo) && is_array($valueRP->Persona_Cargo))
                        {
                            $cargos = $valueRP->Persona_Cargo;
                        }
                        elseif (isset($valueRP->Persona_Cargo) && is_array($valueRP->Persona_Cargo))
                        {
                            $cargos[] = $valueRP->Persona_Cargo;
                        }
                        elseif (isset($valueRP->p_rol) && is_array($valueRP->p_rol))
                        {
                            $cargos = $valueRP->p_rol;
                        }
                        elseif (isset($valueRP->p_rol) && !is_array($valueRP->p_rol))
                        {
                            $cargos[] = $valueRP->p_rol;
                        }
                        if (count($cargos) == 0)
                        {
                            $paramsRP = [];
                            $paramsRP[] = 'insert';
                            $paramsRP[] = $id_fide ?? '0'; 
                            $paramsRP[] = $valueRP->apellido_nombre ?? null;
                            $paramsRP[] = $valueRP->persona_DNI ?? null;
                            $paramsRP[] = $valueRP->persona_cuit ?? null;
                            $paramsRP[] = $valueRP->persona_domicilio ?? null;
                            $paramsRP[] = $valueRP->persona_estado_civil ?? null;
                            $paramsRP[] = $valueRP->persona_conyuge ?? null;
                            $paramsRP[] = null;
                            $paramsRP[] = $valueRP->permanece_en_cargo ?? null;
                            $paramsRP[] = Session::get('usuario')->user_id ?? '0';
                            $personas = SQLConnection::backendStoreProcedure('dbo.openai_insert_personas', $paramsRP, 'selectOne'); 
                            echo('<br>1 - Relacion_Personas: ' . ($valueRP->apellido_nombre ?? '') . ' - id = ' . ($personas->id ?? '0'));
                        }
                        else 
                        {
                            foreach ($cargos as $RP2 => $valueRP2) {
                                $paramsRP = [];
                                $paramsRP[] = 'insert';
                                $paramsRP[] = $id_fide ?? '0'; 
                                $paramsRP[] = $valueRP->apellido_nombre ?? null;
                                $paramsRP[] = $valueRP->persona_DNI ?? null;
                                $paramsRP[] = $valueRP->persona_cuit ?? null;
                                $paramsRP[] = $valueRP->persona_domicilio ?? null;
                                $paramsRP[] = $valueRP->persona_estado_civil ?? null;
                                $paramsRP[] = $valueRP->persona_conyuge ?? null;
                                $paramsRP[] = $valueRP2->p_rol ?? null;
                                // $paramsRP[] = $valueRP->permanece_en_cargo ?? null;
                                $paramsRP[] = $valueRP2->permanece_en_cargo ?? $valueRP->permanece_en_cargo ?? null;
                                $paramsRP[] = Session::get('usuario')->user_id ?? '0';

                                // Insert en [sociedades_constituciones_relaciones_personas]
                                $personas = SQLConnection::backendStoreProcedure('dbo.openai_insert_personas', $paramsRP, 'selectOne'); 
                                echo('<br>2 - Relacion_Personas: ' . ($valueRP->apellido_nombre ?? '') . ' - cargo = ' . ($valueRP2->p_rol ?? '')); 
                                echo(' - Permanece en cargo = ' . ($valueRP->permanece_en_cargo ?? ''). ' - id = ' . ($personas->id ?? '0'));
                            }
                        }
                    } catch (\Throwable $th) {
                        $params = [];
                        $params[] = $id_fide;
                        $params[] = 'error_4';
                        $params[] = Session::get('usuario')->user_id ?? '0';
                        $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
                    }
                }

                   
                    
                foreach ($Relacion_Empresas as $RE => $valueRE) {
                    try {
                        $vinculos = []; 
                        if (isset($valueRE->Vinculada_vinculo) && is_array($valueRE->Vinculada_vinculo))
                        {
                            $vinculos = $valueRE->Vinculada_vinculo;
                        }
                        else 
                        if (isset($valueRE->Vinculada_vinculo) && !is_array($valueRE->Vinculada_vinculo))
                        {
                            $vinculos[] = $valueRE->Vinculada_vinculo;
                        }
                        if (count($vinculos) == 0)
                        {
                            $paramsRE = [];
                            $paramsRE[] = 'insert';
                            $paramsRE[] = $id_fide ?? '0'; 
                            $paramsRE[] = $valueRE->Vinculada_nombre ?? null;
                            $paramsRE[] = $valueRE->Vinculada_cuit ?? null;
                            $paramsRE[] = $valueRE->Vinculada_Pais ?? null;
                            $paramsRE[] = $valueRE->Vinculada_domicilio ?? null;
                            $paramsRE[] = null;
                            $paramsRE[] = Session::get('usuario')->user_id ?? '0';

                            // Insert en [sociedades_constituciones_relaciones_vinculadas]
                            $vinculadas = SQLConnection::backendStoreProcedure('dbo.openai_insert_vinculadas', $paramsRE, 'selectOne'); 
                            echo('<br>1 - Relacion_Empresas: ' . ($valueRE->Vinculada_nombre ?? '') . ' - id = ' . ($vinculadas->id ?? '0'));
                        }
                        else 
                        {
                            foreach ($vinculos as $RE2 => $valueRE2) {
                                $paramsRE = [];
                                $paramsRE[] = 'insert';
                                $paramsRE[] = $id_fide ?? '0'; 
                                $paramsRE[] = $valueRE->Vinculada_nombre ?? null;
                                $paramsRE[] = $valueRE->Vinculada_cuit ?? null;
                                $paramsRE[] = $valueRE->Vinculada_Pais ?? null;
                                $paramsRE[] = $valueRE->Vinculada_domicilio ?? null;
                                $paramsRE[] = $valueRE2->e_rol ?? ($valueRE2 ?? null);
                                $paramsRE[] = Session::get('usuario')->user_id ?? '0';
                                // Insert en [sociedades_constituciones_relaciones_vinculadas]
                                $vinculadas = SQLConnection::backendStoreProcedure('dbo.openai_insert_vinculadas', $paramsRE, 'selectOne'); 
                                echo('<br>2 - Relacion_Empresas: ' . ($valueRE->Vinculada_nombre ?? '') . ' - id = ' . ($vinculadas->id ?? '0'));
                            }
                        }

                    } catch (\Throwable $th) {
                    $params = [];
                    $params[] = $id_fide;
                    $params[] = 'error_5';
                    $params[] = Session::get('usuario')->user_id ?? '0';
                    $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
                    }
                }
            }
        }     
    }

    public static function ProcesarEdictos(){
        
        /*
            Estructura de json con todos los nodos para la devolución de Editos
            {
                "Datos_Empresa": {
                    "nombre_actual": "",
                    "nombre_anterior": "",
                    "cuit_empresa": "",
                    "domicilio_actual": "",
                    "domicilio_anterior": "",
                    "empresa_tipo": ""
                },
                "Relacion_Personas":  [
                    {
                        "apellido_nombre": "",
                        "persona_DNI": "",
                        "persona_cuit": "",
                        "persona_domicilio": "",
                        "persona_estado_civil": "",
                        "persona_conyuge": "",
                        "Persona_Cargo": [
                            {
                                "p_rol": ""
                            }
                        ],
                        "permanece_en_cargo?": ""
                    }
                ],
                "Relacion_Empresas":  [
                    {
                        "Vinculada_nombre": "",
                        "Vinculada_cuit": "",
                        "Vinculada_Pais": "",
                        "Vinculada_domicilio": "",
                        "Vinculada_vinculo": [
                            {
                                "e_rol": ""
                            }
                        ]
                    }
                ],
                "Datos_Generales": {
                    "tipo_edicto": "",
                    "fecha_asamblea": ""
                }
            }
        */

        $fechaHoy = Misc::obtenerDiaDeHoy();        
        $fuente = null;
        $ruta = env('PATH_COMPARTIDO');         
        $arch = "/openAIBatch/batchDiario/$fechaHoy/batch_output.jsonl";  
        $file = $ruta . $arch;
       // dd($)
        if (!file_exists($file)){   
            return json_encode('No se encontro un archivo para procesar'); 
        }        
        
        $archivo = file($file);        

        
        foreach ($archivo as $key => $linea) {
            $linea = str_replace('permanece_en_cargo?','permanece_en_cargo',$linea);
            $file_editable = json_decode($linea,false); 
            $custom_id = $file_editable->custom_id; 
            $partes = explode('_', $custom_id);
            $id_fide = $partes[2] ?? 0; 
                      
            echo('<br><br>-----------------------------------------------');
            echo('<br>id_fide: ' . $id_fide); 
            
            /* Si ya fue procesado lo salteo, si se quiere volver a procesar sacar esto */
            $params = [];
            $params[] = $id_fide;
            $params[] = 'control_ya_procesado';            
            $control_ya_procesado = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
            if ($control_ya_procesado->procesado == 1)
            {
                echo(' -- YA ESTABA PROCESADO --'); 
                continue;
            }          
            
            // Buscamos el texto del edicto en el archivo input 
            $texto_edicto = new stdClass; 
            $texto_edicto = null;                     

            $datos = $file_editable->response->body->choices;
            foreach($datos as $key2 => $value){

                try {

                    $txt_json = new stdClass();
                    $txt_json = $value->message->content; 
                    $txt_json = str_replace(['```json', '```'], '', $txt_json);
                    $datos2 = json_decode($txt_json,false);                    

                    $Datos_Empresa     = new stdClass();
                    $Datos_Generales   = new stdClass();
                    $Relacion_Personas = [];
                    $Relacion_Empresas = [];
                    $Datos_Empresa     = $datos2->Datos_Empresa ?? null;
                    $Datos_Generales   = $datos2->Datos_Generales ?? null;

                    if (isset($datos2->Relacion_Personas) && is_array($datos2->Relacion_Personas))
                        {
                        $Relacion_Personas = $datos2->Relacion_Personas;
                        }
                    if (isset($datos2->Relacion_Personas) && !is_array($datos2->Relacion_Personas))
                        {
                        $Relacion_Personas[] = $datos2->Relacion_Personas; 
                        }

                     if (isset($datos2->Relacion_Empresas) && is_array($datos2->Relacion_Empresas))
                        {
                        $Relacion_Empresas = $datos2->Relacion_Empresas;
                        }
                    if (isset($datos2->Relacion_Empresas) && !is_array($datos2->Relacion_Empresas))
                        {
                        $Relacion_Empresas[] = $datos2->Relacion_Empresas; 
                        }
                       
                    
                    $nombre_actual = new stdClass(); 
                    $nombre_actual = null;
                    if (isset($Datos_Empresa->nombre_actual) && is_array($Datos_Empresa->nombre_actual))
                        {
                        $nombre_actual = implode(";",$Datos_Empresa->nombre_actual);
                        }

                    if (isset($Datos_Empresa->nombre_actual) && !is_array($Datos_Empresa->nombre_actual))
                        {
                        $nombre_actual = $Datos_Empresa->nombre_actual;
                        }

                    $nombre_anterior = new stdClass(); 
                    $nombre_anterior = null;
                    if (isset($Datos_Empresa->nombre_anterior) && is_array($Datos_Empresa->nombre_anterior))
                        {
                        $nombre_anterior = implode(";",$Datos_Empresa->nombre_anterior);
                        }

                    if (isset($Datos_Empresa->nombre_anterior) && !is_array($Datos_Empresa->nombre_anterior))
                        {
                        $nombre_anterior = $Datos_Empresa->nombre_anterior;
                        }

                    $cuit_empresa = new stdClass(); 
                    $cuit_empresa = null;
                    if (isset($Datos_Empresa->cuit_empresa) && is_array($Datos_Empresa->cuit_empresa))
                        {
                        $cuit_empresa = implode(";",$Datos_Empresa->cuit_empresa);
                        }

                    if (isset($Datos_Empresa->cuit_empresa) && !is_array($Datos_Empresa->cuit_empresa))
                        {
                        $cuit_empresa = $Datos_Empresa->cuit_empresa;
                        }

                    $domicilio_actual = new stdClass(); 
                    $domicilio_actual = null;
                    if (isset($Datos_Empresa->domicilio_actual) && is_array($Datos_Empresa->domicilio_actual))
                        {
                        $domicilio_actual = implode(";",$Datos_Empresa->domicilio_actual);
                        }

                    if (isset($Datos_Empresa->domicilio_actual) && !is_array($Datos_Empresa->domicilio_actual))
                        {
                        $domicilio_actual = $Datos_Empresa->domicilio_actual;
                        }

                    $domicilio_anterior = new stdClass(); 
                    $domicilio_anterior = null;
                    if (isset($Datos_Empresa->domicilio_anterior) && is_array($Datos_Empresa->domicilio_anterior))
                        {
                        $domicilio_anterior = implode(";",$Datos_Empresa->domicilio_anterior);
                        }

                    if (isset($Datos_Empresa->domicilio_anterior) && !is_array($Datos_Empresa->domicilio_anterior))
                        {
                        $domicilio_anterior = $Datos_Empresa->domicilio_anterior;
                        }

                    $empresa_tipo = new stdClass(); 
                    $empresa_tipo = null;
                    if (isset($Datos_Empresa->empresa_tipo) && is_array($Datos_Empresa->empresa_tipo))
                        {
                        $empresa_tipo = implode(";",$Datos_Empresa->empresa_tipo);
                        }

                    if (isset($Datos_Empresa->empresa_tipo) && !is_array($Datos_Empresa->empresa_tipo))
                        {
                        $empresa_tipo = $Datos_Empresa->empresa_tipo;
                        }

                    $tipo_edicto = new stdClass(); 
                    $tipo_edicto = null;
                    if (isset($Datos_Generales->tipo_edicto) && is_array($Datos_Generales->tipo_edicto))
                        {
                        $tipo_edicto = implode(";",$Datos_Generales->tipo_edicto);
                        }

                    if (isset($Datos_Generales->tipo_edicto) && !is_array($Datos_Generales->tipo_edicto))
                        {
                        $tipo_edicto = $Datos_Generales->tipo_edicto;
                        }

                    $fecha_asamblea = new stdClass(); 
                    $fecha_asamblea = null;
                    if (isset($Datos_Generales->fecha_asamblea) && is_array($Datos_Generales->fecha_asamblea))
                        {
                        $fecha_asamblea = implode(";",$Datos_Generales->fecha_asamblea);
                        }

                    if (isset($Datos_Generales->fecha_asamblea) && !is_array($Datos_Generales->fecha_asamblea))
                        {
                        $fecha_asamblea = $Datos_Generales->fecha_asamblea;
                        }
                       
                    $params = [];
                    $params[] = $id_fide;
                    $params[] = 'update';
                    $params[] = Session::get('usuario')->user_id ?? '0';
                    $params[] = $nombre_actual ?? null;
                    $params[] = $nombre_anterior ?? null;
                    $params[] = $cuit_empresa ?? null;
                    $params[] = $domicilio_actual ?? null;
                    $params[] = $domicilio_anterior ?? null;
                    $params[] = $empresa_tipo ?? null;
                    $params[] = $tipo_edicto ?? null;
                    $params[] = $arch ?? null;
                    $params[] = $fuente ?? null;

                    // Update en sociedades_constituciones de los Datos_Empresa y Datos_Generales, si algun dato le falta
                    $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');

                } catch (\Throwable $th) {
                    $params = [];
                    $params[] = $id_fide;
                    $params[] = 'error_2';
                    $params[] = Session::get('usuario')->user_id ?? '0';
                    $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
                }

                try {        
                    echo('<br>Procesando registro : ' . $key . ' - custon_id = ' . $custom_id);
                    echo('<br>Fecha: ' . ($fecha_asamblea ?? '') . '<br>');
                    //echo(var_dump($datos2));
                    echo('<br>Datos Empresa: ' . ($nombre_actual ?? '') . ' - id = ' . ($id_fide ?? '0'));
                    $paramsJson = [];
                    $paramsJson[] = 'insert';
                    $paramsJson[] = $id_fide ?? '0'; 
                    $paramsJson[] = $tipo_edicto ?? null;
                    $paramsJson[] = $arch ?? null;
                    $paramsJson[] = $custom_id ?? null;
                    $paramsJson[] = $txt_json; 
                    $paramsJson[] = Session::get('usuario')->user_id ?? '0';
                    $txt_json = SQLConnection::backendStoreProcedure('dbo.openai_insert_json', $paramsJson, 'selectOne');                     
                    echo('<br>Text Json: - id = ' . ($txt_json->id ?? '0'));
                } catch (\Throwable $th) {
                    $params = [];
                    $params[] = $id_fide;
                    $params[] = 'error_3';
                    $params[] = Session::get('usuario')->user_id ?? '0';
                    $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
                }            

                    /*
                        Relacion_Personas":  [
                            {
                                "apellido_nombre": "",
                                "persona_DNI": "",
                                "persona_cuit": "",
                                "persona_domicilio": "",
                                "persona_estado_civil": "",
                                "persona_conyuge": "",
                                "Persona_Cargo": [
                                    {
                                        "p_rol": "",
                                        permanece_en_cargo?": ""
                                    }
                                ],
                                
                            }
                        ],
                    */

                    foreach ($Relacion_Personas as $RP => $valueRP) {
                        try {
                            $cargos = []; 
                            $cargos = $valueRP->Persona_Cargo ?? ($valueRP->p_rol ?? []);

                            if (isset($valueRP->Persona_Cargo) && is_array($valueRP->Persona_Cargo))
                            {
                                $cargos = $valueRP->Persona_Cargo;
                            }
                            elseif (isset($valueRP->Persona_Cargo) && is_array($valueRP->Persona_Cargo))
                            {
                                $cargos[] = $valueRP->Persona_Cargo;
                            }
                            elseif (isset($valueRP->p_rol) && is_array($valueRP->p_rol))
                            {
                                $cargos = $valueRP->p_rol;
                            }
                            elseif (isset($valueRP->p_rol) && !is_array($valueRP->p_rol))
                            {
                                $cargos[] = $valueRP->p_rol;
                            }
                            if (count($cargos) == 0)
                            {
                                $paramsRP = [];
                                $paramsRP[] = 'insert';
                                $paramsRP[] = $id_fide ?? '0'; 
                                $paramsRP[] = $valueRP->apellido_nombre ?? null;
                                $paramsRP[] = $valueRP->persona_DNI ?? null;
                                $paramsRP[] = $valueRP->persona_cuit ?? null;
                                $paramsRP[] = $valueRP->persona_domicilio ?? null;
                                $paramsRP[] = $valueRP->persona_estado_civil ?? null;
                                $paramsRP[] = $valueRP->persona_conyuge ?? null;
                                $paramsRP[] = null;
                                $paramsRP[] = $valueRP->permanece_en_cargo ?? null;
                                $paramsRP[] = Session::get('usuario')->user_id ?? '0';
                                $personas = SQLConnection::backendStoreProcedure('dbo.openai_insert_personas', $paramsRP, 'selectOne'); 
                                echo('<br>1 - Relacion_Personas: ' . ($valueRP->apellido_nombre ?? '') . ' - id = ' . ($personas->id ?? '0'));
                            }
                            else 
                            {
                                foreach ($cargos as $RP2 => $valueRP2) {
                                    $paramsRP = [];
                                    $paramsRP[] = 'insert';
                                    $paramsRP[] = $id_fide ?? '0'; 
                                    $paramsRP[] = $valueRP->apellido_nombre ?? null;
                                    $paramsRP[] = $valueRP->persona_DNI ?? null;
                                    $paramsRP[] = $valueRP->persona_cuit ?? null;
                                    $paramsRP[] = $valueRP->persona_domicilio ?? null;
                                    $paramsRP[] = $valueRP->persona_estado_civil ?? null;
                                    $paramsRP[] = $valueRP->persona_conyuge ?? null;
                                    $paramsRP[] = $valueRP2->p_rol ?? null;
                                    // $paramsRP[] = $valueRP->permanece_en_cargo ?? null;
                                    $paramsRP[] = $valueRP2->permanece_en_cargo ?? $valueRP->permanece_en_cargo ?? null;
                                    $paramsRP[] = Session::get('usuario')->user_id ?? '0';

                                    // Insert en [sociedades_constituciones_relaciones_personas]
                                    $personas = SQLConnection::backendStoreProcedure('dbo.openai_insert_personas', $paramsRP, 'selectOne'); 
                                    echo('<br>2 - Relacion_Personas: ' . ($valueRP->apellido_nombre ?? '') . ' - cargo = ' . ($valueRP2->p_rol ?? '')); 
                                    echo(' - Permanece en cargo = ' . ($valueRP->permanece_en_cargo ?? ''). ' - id = ' . ($personas->id ?? '0'));
                                }
                            }
                        } catch (\Throwable $th) {
                            $params = [];
                            $params[] = $id_fide;
                            $params[] = 'error_4';
                            $params[] = Session::get('usuario')->user_id ?? '0';
                            $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
                        }
                    }

                    /*
                     "Relacion_Empresas":  [
                        {
                            "Vinculada_nombre": "",
                            "Vinculada_cuit": "",
                            "Vinculada_Pais": "",
                            "Vinculada_domicilio": "",
                            "Vinculada_vinculo": [
                                {
                                    "e_rol": ""
                                }
                            ]
                        }
                    ],
                    */
                    
                    foreach ($Relacion_Empresas as $RE => $valueRE) {
                    try {
                        $vinculos = []; 
                        if (isset($valueRE->Vinculada_vinculo) && is_array($valueRE->Vinculada_vinculo))
                        {
                            $vinculos = $valueRE->Vinculada_vinculo;
                        }
                        else 
                        if (isset($valueRE->Vinculada_vinculo) && !is_array($valueRE->Vinculada_vinculo))
                        {
                            $vinculos[] = $valueRE->Vinculada_vinculo;
                        }
                        if (count($vinculos) == 0)
                        {
                            $paramsRE = [];
                            $paramsRE[] = 'insert';
                            $paramsRE[] = $id_fide ?? '0'; 
                            $paramsRE[] = $valueRE->Vinculada_nombre ?? null;
                            $paramsRE[] = $valueRE->Vinculada_cuit ?? null;
                            $paramsRE[] = $valueRE->Vinculada_Pais ?? null;
                            $paramsRE[] = $valueRE->Vinculada_domicilio ?? null;
                            $paramsRE[] = null;
                            $paramsRE[] = Session::get('usuario')->user_id ?? '0';

                            // Insert en [sociedades_constituciones_relaciones_vinculadas]
                            $vinculadas = SQLConnection::backendStoreProcedure('dbo.openai_insert_vinculadas', $paramsRE, 'selectOne'); 
                            echo('<br>1 - Relacion_Empresas: ' . ($valueRE->Vinculada_nombre ?? '') . ' - id = ' . ($vinculadas->id ?? '0'));
                        }
                        else 
                        {
                            foreach ($vinculos as $RE2 => $valueRE2) {
                                $paramsRE = [];
                                $paramsRE[] = 'insert';
                                $paramsRE[] = $id_fide ?? '0'; 
                                $paramsRE[] = $valueRE->Vinculada_nombre ?? null;
                                $paramsRE[] = $valueRE->Vinculada_cuit ?? null;
                                $paramsRE[] = $valueRE->Vinculada_Pais ?? null;
                                $paramsRE[] = $valueRE->Vinculada_domicilio ?? null;
                                $paramsRE[] = $valueRE2->e_rol ?? ($valueRE2 ?? null);
                                $paramsRE[] = Session::get('usuario')->user_id ?? '0';
                                // Insert en [sociedades_constituciones_relaciones_vinculadas]
                                $vinculadas = SQLConnection::backendStoreProcedure('dbo.openai_insert_vinculadas', $paramsRE, 'selectOne'); 
                                echo('<br>2 - Relacion_Empresas: ' . ($valueRE->Vinculada_nombre ?? '') . ' - id = ' . ($vinculadas->id ?? '0'));
                            }
                        }

                    } catch (\Throwable $th) {
                    $params = [];
                    $params[] = $id_fide;
                    $params[] = 'error_5';
                    $params[] = Session::get('usuario')->user_id ?? '0';
                    $sociedades = SQLConnection::backendStoreProcedure('dbo.openai_insert_sociedades_constituciones', $params, 'selectOne');
                    }
                }
            }
        }     
    }

    public static function ProcesarEdictosBaseInterna(){
                
        $fechaHoy = Misc::obtenerDiaDeHoy();        
        $fuente = null;
        $ruta = env('PATH_COMPARTIDO');        
        $arch = "/openAIBatch/batchDiario/$fechaHoy/batch_output.jsonl"; 

        $file = $ruta . $arch;
        
        if (!file_exists($file)){   
            return json_encode('No se encontro un archivo para procesar'); 
        }        
        
        $archivo = file($file);

        
        foreach ($archivo as $key => $linea) {
            $linea = str_replace('permanece_en_cargo?','permanece_en_cargo',$linea);
            $file_editable = json_decode($linea,false); 
            $custom_id = $file_editable->custom_id; 
            $partes = explode('_', $custom_id);
            $id_fide = $partes[2] ?? 0; 
                      
            echo('<br><br>-----------------------------------------------');
            echo('<br>id_fide: ' . $id_fide); 
            
            /* Si ya fue procesado lo salteo, si se quiere volver a procesar sacar esto */
            $params = [];
            $params[] = $id_fide;
            $params[] = 'control_ya_procesado';  

            $control_ya_procesado = DB::select('EXEC dbo.openai_insert_sociedades_constituciones ?,?', $params);            
            if ($control_ya_procesado[0]->procesado == 1){
                echo(' -- YA ESTABA PROCESADO --'); 
                continue;
            }          
            
            // Buscamos el texto del edicto en el archivo input 
            $texto_edicto = new stdClass; 
            $texto_edicto = null;                     

            $datos = $file_editable->response->body->choices;
            foreach($datos as $key2 => $value){
                try {
                    // Limpiar y decodificar JSON
                    $txt_json = str_replace(['```json', '```'], '', $value->message->content);                    
                    $datos2 = json_decode($txt_json, false);
                
                    // Inicializar datos
                    $Datos_Empresa     = $datos2->Datos_Empresa ?? new stdClass();
                    $Datos_Generales   = $datos2->Datos_Generales ?? new stdClass();
                    $Relacion_Personas = (array) ($datos2->Relacion_Personas ?? []);
                    $Relacion_Empresas = (array) ($datos2->Relacion_Empresas ?? []);
                
                    // Asegurar que siempre sean arrays (por si vino como objeto simple)
                    $Relacion_Personas = is_array($Relacion_Personas) ? $Relacion_Personas : [$Relacion_Personas];
                    $Relacion_Empresas = is_array($Relacion_Empresas) ? $Relacion_Empresas : [$Relacion_Empresas];
                
                    // Funcion auxiliar para manejar campos multiples
                    $procesarCampo = function ($obj, $campo) {
                        if (!isset($obj->$campo)) {
                            return null;
                        }
                        
                        return is_array($obj->$campo)
                            ? implode(";", $obj->$campo)
                            : $obj->$campo;
                    };
                
                    // Extraer campos procesados
                    $nombre_actual      = $procesarCampo($Datos_Empresa, 'nombre_actual');
                    $nombre_anterior    = $procesarCampo($Datos_Empresa, 'nombre_anterior');
                    $cuit_empresa       = $procesarCampo($Datos_Empresa, 'cuit_empresa');
                    $domicilio_actual   = $procesarCampo($Datos_Empresa, 'domicilio_actual');
                    $domicilio_anterior = $procesarCampo($Datos_Empresa, 'domicilio_anterior');
                    $empresa_tipo       = $procesarCampo($Datos_Empresa, 'empresa_tipo');
                    $tipo_edicto        = $procesarCampo($Datos_Generales, 'tipo_edicto');
                    $fecha_asamblea     = $procesarCampo($Datos_Generales, 'fecha_asamblea');
                
                    // Preparar parámetros
                    $params = [
                        $id_fide,
                        'update',
                        Session::get('usuario')->user_id ?? '0',
                        $nombre_actual,
                        $nombre_anterior,
                        $cuit_empresa,
                        $domicilio_actual,
                        $domicilio_anterior,
                        $empresa_tipo,
                        $tipo_edicto,
                        $arch ?? null,
                        $fuente ?? null
                    ];
                
                    $sociedades = DB::select('EXEC dbo.openai_insert_sociedades_constituciones ?,?,?,?,?,?,?,?,?,?,?', $params);
                } catch (\Throwable $th) {
                    $params = [
                        $id_fide,
                        'error_2',
                        Session::get('usuario')->user_id ?? '0'
                    ];
                
                    $sociedades = DB::select('EXEC dbo.openai_insert_sociedades_constituciones ?,?,?', $params);
                }
                

                try {
                    echo "<br>Procesando registro: {$key} - custom_id = {$custom_id}";
                    echo "<br>Fecha: " . ($fecha_asamblea ?? '') . "<br>";
                    echo "<br>Datos Empresa: " . ($nombre_actual ?? '') . " - id = " . ($id_fide ?? '0');
                
                    $paramsJson = [
                        'insert',
                        $id_fide ?? '0',
                        $tipo_edicto ?? null,
                        $arch ?? null,
                        $custom_id ?? null,
                        $txt_json,
                        Session::get('usuario')->user_id ?? '0'
                    ];
                                    
                    $resultadoJson = DB::select('EXEC dbo.openai_insert_json ?,?,?,?,?,?,?', $paramsJson);

                
                    // Por si viene como array de resultados
                    $jsonInsertResult = is_array($resultadoJson) ? $resultadoJson[0] ?? null : $resultadoJson;
                
                    echo '<br>Text Json: - id = ' . ($jsonInsertResult->id ?? '0');
                
                } catch (\Throwable $th) {
                    $params = [
                        $id_fide ?? '0',
                        'error_3',
                        Session::get('usuario')->user_id ?? '0'
                    ];
                
                    $sociedades = DB::select('EXEC dbo.openai_insert_sociedades_constituciones ?,?,?', $params);
                }
                

                foreach ($Relacion_Personas as $valueRP) {
                    try {
                        // Normalizar cargos
                        $cargos = [];
                
                        if (isset($valueRP->Persona_Cargo)) {
                            $cargos = is_array($valueRP->Persona_Cargo) ? $valueRP->Persona_Cargo : [$valueRP->Persona_Cargo];
                        } elseif (isset($valueRP->p_rol)) {
                            $cargos = is_array($valueRP->p_rol) ? $valueRP->p_rol : [ (object) ['p_rol' => $valueRP->p_rol] ];
                        }
                
                        // Si no hay cargos, insertamos sin rol
                        if (count($cargos) === 0) {
                            $paramsRP = [
                                'insert',
                                $id_fide ?? '0',
                                $valueRP->apellido_nombre ?? null,
                                $valueRP->persona_DNI ?? null,
                                $valueRP->persona_cuit ?? null,
                                $valueRP->persona_domicilio ?? null,
                                $valueRP->persona_estado_civil ?? null,
                                $valueRP->persona_conyuge ?? null,
                                null,
                                $valueRP->permanece_en_cargo ?? null,
                                Session::get('usuario')->user_id ?? '0'
                            ];
                
                            $personas = DB::select('EXEC dbo.openai_insert_personas ?,?,?,?,?,?,?,?,?,?,?', $paramsRP);
                            echo "<br>1 - Relacion_Personas: {$valueRP->apellido_nombre} - id = " . ($personas->id ?? '0');
                
                        } else {
                            // Insert con cargos
                            foreach ($cargos as $cargo) {
                                $rol = is_object($cargo) ? ($cargo->p_rol ?? null) : $cargo;
                
                                $paramsRP = [
                                    'insert',
                                    $id_fide ?? '0',
                                    $valueRP->apellido_nombre ?? null,
                                    $valueRP->persona_DNI ?? null,
                                    $valueRP->persona_cuit ?? null,
                                    $valueRP->persona_domicilio ?? null,
                                    $valueRP->persona_estado_civil ?? null,
                                    $valueRP->persona_conyuge ?? null,
                                    $rol,
                                    $valueRP->permanece_en_cargo ?? null,
                                    Session::get('usuario')->user_id ?? '0'
                                ];
                
                                $personas = DB::select('EXEC dbo.openai_insert_personas ?,?,?,?,?,?,?,?,?,?,?', $paramsRP);
                
                                echo "<br>2 - Relacion_Personas: {$valueRP->apellido_nombre} - cargo = {$rol}";
                                echo " - Permanece en cargo = " . ($valueRP->permanece_en_cargo ?? '') . " - id = " . ($personas->id ?? '0');
                            }
                        }
                    } catch (\Throwable $th) {
                        $params = [
                            $id_fide ?? '0',
                            'error_4',
                            Session::get('usuario')->user_id ?? '0'
                        ];
                        DB::select('EXEC dbo.openai_insert_sociedades_constituciones ?,?,?', $params);
                    }
                }
                
                   
                    
                foreach ($Relacion_Empresas as $valueRE) {
                    try {
                        // Normalizar vinculos
                        $vinculos = [];
                
                        if (isset($valueRE->Vinculada_vinculo)) {
                            $vinculos = is_array($valueRE->Vinculada_vinculo)
                                ? $valueRE->Vinculada_vinculo
                                : [ $valueRE->Vinculada_vinculo ];
                        }
                
                        // Si no hay vinculos, insert sin rol
                        if (count($vinculos) === 0) {
                            $paramsRE = [
                                'insert',
                                $id_fide ?? '0',
                                $valueRE->Vinculada_nombre ?? null,
                                $valueRE->Vinculada_cuit ?? null,
                                $valueRE->Vinculada_Pais ?? null,
                                $valueRE->Vinculada_domicilio ?? null,
                                null,
                                Session::get('usuario')->user_id ?? '0',
                            ];
                
                            $vinculadas = DB::select('EXEC dbo.openai_insert_vinculadas ?,?,?,?,?,?,?,?', $paramsRE);
                            echo "<br>1 - Relacion_Empresas: {$valueRE->Vinculada_nombre} - id = " . ($vinculadas->id ?? '0');
                
                        } else {
                            // Insert con vinculos
                            foreach ($vinculos as $vinculo) {
                                $rol = is_object($vinculo) ? ($vinculo->e_rol ?? null) : $vinculo;
                
                                $paramsRE = [
                                    'insert',
                                    $id_fide ?? '0',
                                    $valueRE->Vinculada_nombre ?? null,
                                    $valueRE->Vinculada_cuit ?? null,
                                    $valueRE->Vinculada_Pais ?? null,
                                    $valueRE->Vinculada_domicilio ?? null,
                                    $rol,
                                    Session::get('usuario')->user_id ?? '0',
                                ];
                
                                $vinculadas = DB::select('EXEC dbo.openai_insert_vinculadas ?,?,?,?,?,?,?,?', $paramsRE);
                                echo "<br>2 - Relacion_Empresas: {$valueRE->Vinculada_nombre} - rol = {$rol} - id = " . ($vinculadas->id ?? '0');
                            }
                        }
                    } catch (\Throwable $th) {
                        $params = [
                            $id_fide ?? '0',
                            'error_5',
                            Session::get('usuario')->user_id ?? '0'
                        ];
                        DB::select('EXEC dbo.openai_insert_sociedades_constituciones ?,?,?', $params);
                    }
                }                
            }
        }     
    }

    public static function administradorIA(){
        return view('/administrador_ia/panel_admin_ai');
    }

    public static function administradorIABatch(){        
        $promptsFiltrados = SQLConnection::backendStoreProcedure('gestor_prompts', ['PROMPTS_TYPE', null, null, null, null, null, null, null, null, null, 'edicto']);
       
        $estadoPrompt = '1';
        $promptsFiltrados = array_filter($promptsFiltrados, function ($prompt) use ($estadoPrompt) {
            return isset($prompt->active) && $prompt->active == $estadoPrompt;
        });

        $tablaProcesos = SQLConnection::backendStoreProcedure('sp_ProcessBatchAi',['SELECT_ALL_BATCH', NULL]);           
        
        return view('/administrador_ia/administrador_batch')->with(compact('promptsFiltrados','tablaProcesos'));
    }

    public static function generarFileBatchIA(){
        $fechaConsulta = Request::input('fechaBatch');
        $id_prompt = Request::input('modeloGpt');
        $user_id = Session::get('usuario')->user_id;

        $fecha = DateTime::createFromFormat('m/d/Y', $fechaConsulta);
        $fechaFormateada = $fecha->format('Y-m-d');

        $prompt_data = SQLConnection::backendStoreProcedure('gestor_prompts', array('SELECT_ONE', null, null, null, null, null, null, null, $id_prompt));                
        $prompt_data = $prompt_data[0];
        
        
        $modelosAi = SQLConnection::backendStoreProcedure('gestor_ai_model', ['ALL_AI_MODELS']);
        $model = $prompt_data->ai_provider;
        $matchedModelId = null;

        foreach ($modelosAi as $modelo) {
            if ($modelo->model_version === $model) {
                $matchedModelId = $modelo->id_model;
                break;
            }
        }
                
        $model = $prompt_data->ai_provider;        
        $contentSystem = $prompt_data->system_prompt;
        $contentUser = $prompt_data->user_prompt;

        $directorio = '/var/www/html/compartido/openAIBatch/';
        $pathDirectorioResultado = '/var/www/html/compartido/openAIBatch/';
        
        if (!is_dir($directorio)) {
            mkdir($directorio, 0775, true);
        } else {
            $archivos = glob($directorio . '/*'); 
        
            foreach ($archivos as $archivo) {
                if (is_file($archivo)) {
                    unlink($archivo); 
                } elseif (is_dir($archivo)) {
                    $it = new RecursiveDirectoryIterator($archivo, RecursiveDirectoryIterator::SKIP_DOTS);
                    $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
                    foreach ($files as $file) {
                        if ($file->isDir()) {
                            rmdir($file->getRealPath());
                        } else {
                            unlink($file->getRealPath());
                        }
                    }
                    rmdir($archivo);
                }
            }
        }       
        
        // Contenido del batch, ahora es un array de solicitudes       
        $edictos = SQLConnection::backendStoreProcedure('openai_edictos_dia', [$fechaFormateada]);                        
        $tokens = 1000; 

        $batchContenido = []; 
        foreach ($edictos as $i => $edicto) {
            $fechaEdicto = isset($edicto->fecha_publicacion) ? str_replace('-', '', $edicto->fecha_publicacion) : '';
            $idFide = $edicto->id_fide ?? '';
            $fuente = $edicto->fuente ?? '';

            $batchFormateo = OpenAiController::formateoBatch($fechaEdicto,$idFide,$fuente,$model,$contentSystem,$contentUser,$edicto->contenido_archivo,$tokens);          

            // Agregar el contenido formateado al array del batch
            $batchContenido[] = $batchFormateo;
        }        
        
        // Guarda el contenido en un archivo json
        $batchFile = $directorio . 'batchinput.jsonl';
        foreach ($batchContenido as $request) {
            if (file_put_contents($batchFile, json_encode($request) . PHP_EOL, FILE_APPEND) === false) {
                return response()->json(['error' => 'Error escribiendo el archivo.'], 500);
            } 
        }     
    
        $respuesta = OpenAiController::openAiFileEndpoit($batchFile);
        $idBatch = $respuesta['id'];         
        $procesarBatch = OpenAiController::procesarBatchAI($idBatch,$matchedModelId, $id_prompt,$user_id, $fechaFormateada);
        
        $respuestaBatch = [
            'id' => $procesarBatch['id'],
            'status' => $procesarBatch['status'],
            'cantidad_edictos' => $procesarBatch['request_counts']['total'],
            'completados' => $procesarBatch['request_counts']['completed'],
            'fallidos' => $procesarBatch['request_counts']['failed']
        ];       

        return $respuestaBatch;
    }

    /* 
        Funcion para armar y enviar el batch de edictos diarios, masivos y por cliente (Menos Sabados y Domingos)
        Notas:
            - El tipo de batch 1 es el diario, el 2 es por cliente y el 3 es el masivo
    */
    public static function generarFileBatchIADiario($fechaFormateada, $id_prompt,$user_id, $tipoBatch){               
        $prompt_data = SQLConnection::backendStoreProcedure('gestor_prompts', array('SELECT_ONE', null, null, null, null, null, null, null, $id_prompt));                        
        $prompt_data = $prompt_data[0];                
        
        $modelosAi = SQLConnection::backendStoreProcedure('gestor_ai_model', ['ALL_AI_MODELS']);
        
        $model = $prompt_data->ai_provider;        
        $matchedModelId = null;

        foreach ($modelosAi as $modelo) {
            if ($modelo->model_version === $model) {
                $matchedModelId = $modelo->id_model;
                break;
            }
        }        
        
        //Misc::escribirLogbatch('Seleccionando el prompt: ' . $prompt_data->prompt_name);
        //echo 'Seleccionando el prompt: ' . $prompt_data->prompt_name . '</br>';  
        
        $model = $prompt_data->ai_provider;
        $contentSystem = $prompt_data->system_prompt;
        $contentUser = $prompt_data->user_prompt;             
        
        //echo 'Seleccionando modelo de AI: ' . $model . '</br>';
        //Misc::escribirLogbatch('Seleccionando modelo de AI: ' . $model);

        
        // Contenido del batch, ahora es un array de solicitudes       
        // El nuevo store pide como parametro dos fechas de boletin para establecer un rango
        // Luego se manda un user_id y por ultimo la cantidad de edictos que vamos a devolver
        
        $edictos = [];
        if ($tipoBatch == 1) {
            //2025-04-28
            $edictos = SQLConnection::backendStoreProcedure('openai_edictos_dia', ['BUSQUEDA_CRON', $fechaFormateada, NULL, 11]);                        
        }elseif ($tipoBatch == 3) {
            $edictos = SQLConnection::backendStoreProcedure('openai_edictos_dia', ['BUSQUEDA_VACIOS', NULL, NULL, 11,NULL,20000]);
        }
        
        if (empty($edictos)) {
            //echo 'No se encontraron edictos ingresados el dia ' . $fechaFormateada . '</br>';
            //Misc::escribirLogbatch('No se encontraron edictos ingresados el dia ' . $fechaFormateada);

            return "No se encontraron edictos ingresados el dia $fechaFormateada";
        }

        $provinciasProcesadas = [];
        $contadorProvincias = [];

        foreach ($edictos as $item) {
            $provincia = $item->fuente;
            
            // Si la provincia ya está en el array, incrementamos el contador
            if (array_key_exists($provincia, $contadorProvincias)) {
                $contadorProvincias[$provincia]++;
            } else {
                // Si no está, la añadimos al array con un contador de 1
                $contadorProvincias[$provincia] = 1;
            }
            
            // Esto es para mantener el array de provincias procesadas (opcional)
            if (!in_array($provincia, $provinciasProcesadas)) {
                $provinciasProcesadas[] = $provincia;
            }
        }
                
        
        foreach ($provinciasProcesadas as $provincia) {
            //Cantidad de edictos procesados de la provincia
            $value = '';
            foreach ($contadorProvincias as $key => $val) {
                if ($key === $provincia) {
                    $value = $val;
                    break;
                }
            }

            // Aca obtengo el id de la fuente
            $provinciaId = Edicto::obtenerIdPorNombre($provincia);

            // Enviamos a escribir el log del proceso
            //Misc::logFuentes($fechaFormateada, $provincia, 'Se inicio el proceso de creacion de batch, cantidad de edictos: ' . $value, $provinciaId);         
        }        
        //El de arriba esta para revisar si dejarlo o no - TBB
        //Misc::escribirLogbatch('Se inicio el proceso de creacion de batch, cantidad de edictos: ' . count($edictos));
          
        if ($tipoBatch == 1) {
            $directorio = '/var/www/html/compartido/openAIBatch/batchDiario/';
        }elseif ($tipoBatch == 3) {
            $directorio = '/var/www/html/compartido/openAIBatch/batchSinRZ/';
        }  
        //$pathDirectorioResultado = '/var/www/html/compartido/openAIBatch/';      
        //echo 'Generando directorios para los archivos</br>';

        $fecha_actual = date('Y-m-d');

        // Crear la ruta completa de la nueva carpeta
        $directorio = $directorio . $fecha_actual . '/';
        
        // Verificar si la carpeta ya existe
        if (!file_exists($directorio)) {
            // Crear la carpeta
            if (mkdir($directorio, 0777, true)) {
                echo "Carpeta creada exitosamente: $directorio";
                //Misc::escribirLogbatch("Carpeta creada exitosamente: $directorio");
            } else {
                return "Error al crear la carpeta: $directorio";
            }
        } else {
            //echo "La carpeta ya existe: $directorio";
            Misc::escribirLogbatch("La carpeta ya existe: $directorio");
        }
        
        // Verificamos si el directorio no existe
        if (!is_dir($directorio)) {
            // Si no existe, lo creamos con permisos 0775 y permitimos la creacion de directorios padres
            mkdir($directorio, 0775, true);
        } else {
            // Si el directorio ya existe, obtenemos todos los archivos y subdirectorios dentro 
            $archivos = glob($directorio . '/*'); 

            // Iteramos sobre cada archivo o subdirectorio encontrado
            foreach ($archivos as $archivo) {
                // Verificamos si es un archivo
                if (is_file($archivo)) {
                    // Si es un archivo, lo eliminamos
                    unlink($archivo); 
                } elseif (is_dir($archivo)) {
                    // Si es un directorio, creamos un iterador recursivo para acceder a su contenido
                    $it = new RecursiveDirectoryIterator($archivo, RecursiveDirectoryIterator::SKIP_DOTS);
                    // Creamos un iterador que nos permite recorrer todos los archivos y directorios
                    $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
                    // Iteramos sobre cada archivo y directorio
                    foreach ($files as $file) {
                        // Si es un directorio, lo eliminamos
                        if ($file->isDir()) {
                            rmdir($file->getRealPath());
                        } else {
                            // Si es un archivo, lo eliminamos
                            unlink($file->getRealPath());
                        }
                    }
                    // Finalmente, eliminamos el directorio vacio
                    rmdir($archivo);
                }
            }
        }  
                
        
        $tokens = 1000;         
        $batchContenido = []; 
        foreach ($edictos as $i => $edicto) {
            $fechaEdicto = isset($edicto->fecha_publicacion) ? str_replace('-', '', $edicto->fecha_publicacion) : '';
            $idFide = $edicto->id_fide ?? '';
            $fuente = $edicto->fuente ?? '';
            $batchFormateo = OpenAiController::formateoBatch($fechaEdicto,$idFide,$fuente,$model,$contentSystem,$contentUser,$edicto->contenido_archivo,$tokens);          

            // Agregar el contenido formateado al array del batch
            $batchContenido[] = $batchFormateo;
        }       

        //echo 'Guardando archivo Jsonl</br>';
        //Misc::escribirLogbatch('Guardando archivo Jsonl');
        
        // Guarda el contenido en un archivo json
        $batchFile = $directorio . 'batchinput.jsonl';        
        foreach ($batchContenido as $request) {
            if (file_put_contents($batchFile, json_encode($request) . PHP_EOL, FILE_APPEND) === false) {
                return response()->json(['error' => 'Error escribiendo el archivo.'], 500);
            } 
        }     
        
        //echo 'Enviando batch al endpoint de OpenAI</br>';
        Misc::escribirLogbatch('Enviando batch al endpoint de OpenAI');

        $respuesta = OpenAiController::openAiFileEndpoit($batchFile);
        
        $idBatch = $respuesta['id'];

        $tipoDebatch = NULL;
        if ($tipoBatch == 1) {
            $tipoDebatch = 'BD';            
        }elseif ($tipoBatch == 3) {
            $tipoDebatch = 'BSRZ';        
        }                 
        
        $procesarBatch = OpenAiController::procesarBatchAI($idBatch,$matchedModelId, $id_prompt,$user_id, $fechaFormateada,$tipoDebatch);
        
        //echo 'Obteniendo respuesta...</br>';
        
        $respuestaBatch = [
            'id' => $procesarBatch['id'],
            'status' => $procesarBatch['status'],
            'cantidad_edictos' => $procesarBatch['request_counts']['total'],
            'completados' => $procesarBatch['request_counts']['completed'],
            'fallidos' => $procesarBatch['request_counts']['failed']
        ];
        
        Misc::escribirLogbatch('Datos de batch: ' . $procesarBatch['id'] . '|' . $procesarBatch['status'] . '|' . $procesarBatch['request_counts']['total'] . '|' . $procesarBatch['request_counts']['completed']);

        return json_encode($respuestaBatch,JSON_PRETTY_PRINT);
        //return $respuestaBatch;
    }

    /**
    * Esta funcion sirve para consultar el estado de un batch
    * enviado a procesar
    */
    public static function actualizarEstadoBatch(){        
        $batch_id = Request::input('id_batch'); 

        $resultado = OpenAiController::verificarEstadoBatch($batch_id);
        
        $respuestaBatch = [
            'id' => $resultado['id'],
            'status' => $resultado['status'],
            'cantidad_edictos' => $resultado['request_counts']['total'],
            'completados' => $resultado['request_counts']['completed'],
            'fallidos' => $resultado['request_counts']['failed']
        ];         

        return $resultado;
    }

    public static function administradorIAModel(){
        $modelosAi = SQLConnection::backendStoreProcedure('gestor_ai_model', ['ALL_AI_MODELS']);

        return view('/administrador_ia/administrador_model')->with(compact('modelosAi'));;
    }
    
    public static function altaModelosAi(){
        $nombreInternoModelo = Request::input('internal_model_name');
        $modelVersion = Request::input('model_version');
        $descripcionModelo = Request::input('model_description');
        $proveedorAi = Request::input('ai_provider');
        $userID = Session::get('usuario')->user_id;
        $activo = 1;

        $modelosAi = SQLConnection::backendStoreProcedure('gestor_ai_model', ['ALL_AI_MODELS']);
        
        $exists = false; 

        foreach ($modelosAi as $modelos) {
            if ($modelVersion == $modelos->model_version) {
                $exists = true; 
                break; 
            }
        }

        if ($exists) {
            dd('el prompt ya existe');
        } else {
            SQLConnection::backendStoreProcedure('gestor_ai_model', ['INSERT_AI_MODEL', NULL, $nombreInternoModelo, $modelVersion, $descripcionModelo, $proveedorAi, $userID, $activo]);
            dd('alta con exito');
        }
    }

    public static function modalModificarModeloAi(){
        /*  
            IF (@accion = 'EDIT_AI_MODEL')
            BEGIN
                UPDATE ai_model SET 
                internal_model_name = @internal_model_name, 
                model_version = @model_version, 
                model_description = @model_description,
                ai_provider= @ai_provider, 
                created_by = @user_id        
                WHERE id_model = @id_model
            END 
        */
        //$modelosAi = SQLConnection::backendStoreProcedure('gestor_ai_model', ['EDIT_AI_MODEL', $internal_model_name,$model_version,$model_description,$ai_provider,$created_by]);

    }

    public static function batchTipoEdicto(){
        // Se obtiene los datos de los prompts 
        $datos_prompt = SQLConnection::backendStoreProcedure('gestor_prompts', array('seleccionar', null, null, null, null, null, null, null, null));
        dd($datos_prompt);
    }

    public static function generarFileBatchSinRZ($fechaFormateada, $id_prompt,$user_id){    
        $prompt_data = SQLConnection::backendStoreProcedure('gestor_prompts', array('SELECT_ONE', null, null, null, null, null, null, null, $id_prompt));                        
        $prompt_data = $prompt_data[0];                
        
        $modelosAi = SQLConnection::backendStoreProcedure('gestor_ai_model', ['ALL_AI_MODELS']);
        $model = $prompt_data->ai_provider;
        $matchedModelId = null;

        foreach ($modelosAi as $modelo) {
            if ($modelo->model_version === $model) {
                $matchedModelId = $modelo->id_model;
                break;
            }
        }
        echo 'Seleccionando el prompt: ' . $prompt_data->prompt_name . '</br>';  
        
        $model = $prompt_data->ai_provider;
        $contentSystem = $prompt_data->system_prompt;
        $contentUser = $prompt_data->user_prompt;
        
        echo 'Seleccionando modelo de AI: ' . $model . '</br>';
            
        // La carpeta donde se guarden los batch de los clientes se va a llamar /openAIBatch/batchSinRZ
        $edictos = SQLConnection::backendStoreProcedure('openai_edictos_dia', ['BUSQUEDA_VACIOS', NULL, NULL, 11,NULL,20000]);
        
          
        if (empty($edictos)) {
            echo 'No se encontraron edictos ingresados el dia ' . $fechaFormateada . '</br>';

            return 'Abortando proceso';
        }        

        $provinciasProcesadas = [];
        $contadorProvincias = [];

        foreach ($edictos as $item) {
            $provincia = $item->fuente;
            
            // Si la provincia ya está en el array, incrementamos el contador
            if (array_key_exists($provincia, $contadorProvincias)) {
                $contadorProvincias[$provincia]++;
            } else {
                // Si no está, la añadimos al array con un contador de 1
                $contadorProvincias[$provincia] = 1;
            }
            
            // Esto es para mantener el array de provincias procesadas (opcional)
            if (!in_array($provincia, $provinciasProcesadas)) {
                $provinciasProcesadas[] = $provincia;
            }
        }
                
        
        foreach ($provinciasProcesadas as $provincia) {
            //Cantidad de edictos procesados de la provincia
            $value = '';
            foreach ($contadorProvincias as $key => $val) {
                if ($key === $provincia) {
                    $value = $val;
                    break;
                }
            }

            // Aca obtengo el id de la fuente
            $provinciaId = Edicto::obtenerIdPorNombre($provincia);

            // Enviamos a escribir el log del proceso
            Misc::logFuentes($fechaFormateada, $provincia, 'Se inicio el proceso de creacion de batch, cantidad de edictos: ' . $value, $provinciaId);
        }        
                      
        $directorio = '/var/www/html/compartido/openAIBatch/batchSinRZ/';

        echo 'Generando directorios para los archivos</br>';

        $fecha_actual = date('Y-m-d');

        // Crear la ruta completa de la nueva carpeta
        $directorio = $directorio . $fecha_actual . '/';

        // Verificar si la carpeta ya existe
        if (!file_exists($directorio)) {
            // Crear la carpeta
            if (mkdir($directorio, 0777, true)) {
                echo "Carpeta creada exitosamente: $directorio";
            } else {
                return "Error al crear la carpeta: $directorio";
            }
        } else {
            echo "La carpeta ya existe: $directorio";
        }
        
        // Verificamos si el directorio no existe
        if (!is_dir($directorio)) {
            // Si no existe, lo creamos con permisos 0775 y permitimos la creacion de directorios padres
            mkdir($directorio, 0775, true);
        } else {
            // Si el directorio ya existe, obtenemos todos los archivos y subdirectorios dentro 
            $archivos = glob($directorio . '/*'); 

            // Iteramos sobre cada archivo o subdirectorio encontrado
            foreach ($archivos as $archivo) {
                // Verificamos si es un archivo
                if (is_file($archivo)) {
                    // Si es un archivo, lo eliminamos
                    unlink($archivo); 
                } elseif (is_dir($archivo)) {
                    // Si es un directorio, creamos un iterador recursivo para acceder a su contenido
                    $it = new RecursiveDirectoryIterator($archivo, RecursiveDirectoryIterator::SKIP_DOTS);
                    // Creamos un iterador que nos permite recorrer todos los archivos y directorios
                    $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
                    // Iteramos sobre cada archivo y directorio
                    foreach ($files as $file) {
                        // Si es un directorio, lo eliminamos
                        if ($file->isDir()) {
                            rmdir($file->getRealPath());
                        } else {
                            // Si es un archivo, lo eliminamos
                            unlink($file->getRealPath());
                        }
                    }
                    // Finalmente, eliminamos el directorio vacio
                    rmdir($archivo);
                }
            }
        }  
                
        
        $tokens = 1000;         
        $batchContenido = []; 
        foreach ($edictos as $i => $edicto) {
            $fechaEdicto = isset($edicto->fecha_publicacion) ? str_replace('-', '', $edicto->fecha_publicacion) : '';
            $idFide = $edicto->id_fide ?? '';
            $fuente = $edicto->fuente ?? '';

            $batchFormateo = OpenAiController::formateoBatch($fechaEdicto,$idFide,$fuente,$model,$contentSystem,$contentUser,$edicto->contenido_archivo,$tokens);          

            // Agregar el contenido formateado al array del batch
            $batchContenido[] = $batchFormateo;
        }       

        echo 'Guardando archivo Jsonl</br>';

        // Guarda el contenido en un archivo json
        $batchFile = $directorio . 'batchinput.jsonl';
        foreach ($batchContenido as $request) {
            if (file_put_contents($batchFile, json_encode($request) . PHP_EOL, FILE_APPEND) === false) {
                return response()->json(['error' => 'Error escribiendo el archivo.'], 500);
            } 
        }     
        
        echo 'Enviando batch al endpoint de OpenAI</br>';

        $respuesta = OpenAiController::openAiFileEndpoit($batchFile);
        $idBatch = $respuesta['id'];
        $procesarBatch = OpenAiController::procesarBatchAI($idBatch,$matchedModelId, $id_prompt,$user_id, $fechaFormateada,$batchType);
        
        echo 'Obteniendo respuesta...</br>';
        
        $respuestaBatch = [
            'id' => $procesarBatch['id'],
            'status' => $procesarBatch['status'],
            'cantidad_edictos' => $procesarBatch['request_counts']['total'],
            'completados' => $procesarBatch['request_counts']['completed'],
            'fallidos' => $procesarBatch['request_counts']['failed']
        ];       
        
        return $respuestaBatch;
    }

    public static function apiEdictosAI(){
        $system = Request::input('system');
        $user = Request::input('user');
        $assistant = Request::input('assistant');
        $apiKeyGemini = Request::input('apikeyGemini') ?? NULL;
        $apiKeyGpt = Request::input('apikeyGpt') ?? NULL;
        $proveedorAi = Request::input('proveedorAi');
        $proveedorAi = strtoupper(trim($proveedorAi ?? ''));      

        if ( empty($system) || empty($user) || empty($assistant) ) {
            return response()->json([
                'error' => 'Falta parametros de user, system o assistant',
                'detalle' => 'Campos obligatorios sin completar'
            ], 422);
        }

        if (empty($proveedorAi) || is_null($proveedorAi) ) {
            return response()->json([
                'error' => 'Falta proveedor',
                'detalle' => 'El parametro de proveedor es obligatiro'
            ], 422);
        }

        $proveedorAi = strtoupper($proveedorAi);
        
        if ($proveedorAi == 'GEMINI') {
           
            $apiKey = $apiKeyGemini; 

            if (empty($apiKey)) {
                return response()->json([
                    'error' => 'Falta apikey',
                    'detalle' => 'El apikeyGemini es un campo obligatorio'
                ], 422);
            }

            $respuesta = self::gemminiAiEndpoint($system,$user,$assistant,$apiKey);

            return $respuesta;
            
        }elseif ($proveedorAi == 'GPT') {
            if ($apiKeyGpt == NULL) {
                $apiKey = ENV('apiKey_chatgpt');
            }else {
                $apiKey = $apiKeyGpt;
            }

            $model = 'gpt-4o-mini';

            $dataString = OpenAiController::formateoCompletions($model,$system,$assistant,$user,1000);
            $respuesta = OpenAiController::completionsEndpoint($dataString); 
            
            $json = $respuesta['choices'][0]['message']['content'];

            $array = json_decode($json, true);
            
            if (json_last_error() === JSON_ERROR_NONE) {
                // Éxito, podés usar $array como un array asociativo
                echo json_encode($array, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
            } else {
                echo "Error al parsear JSON: " . json_last_error_msg();
            }

            //dd($json);
            //return response()->json($json);
        }
    }

    public static function gemminiAiEndpoint($system,$user,$assistant,$apiKey){                

        $respuesta = self::generarContenidoGemini($apiKey, $system, $user, $assistant);        

        try {
            $texto = $respuesta['candidates'][0]['content']['parts'][0]['text'] ?? null;
    
            if (!$texto) {
                return response()->json(['error' => 'Texto no encontrado en la respuesta.'], 400);
            }
    
            $limpio = trim(preg_replace('/```(?:json)?|```/', '', $texto));
            $json = json_decode($limpio, true);
    
            if (json_last_error() !== JSON_ERROR_NONE) {
                return response()->json([
                    'error' => 'Error al parsear JSON',
                    'detalle' => json_last_error_msg()
                ], 400);
            }
            
            return response()->json($json);
    
        } catch (\Throwable $e) {
            return response()->json([
                'error' => 'Error inesperado',
                'mensaje' => $e->getMessage()
            ], 500);
        }  
    }

    public static function generarContenidoGemini($apiKey, $systemMessage, $userPrompt, $assistant = null){

        $url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=" . urlencode($apiKey);

        $contents = [];

        // Mensaje del sistema
        if (!empty($systemMessage)) {
            $contents[] = [
                "role" => "user",
                "parts" => [
                    ["text" => $systemMessage]
                ]
            ];
        }

        // Mensaje anterior del asistente (si hay)
        if (!empty($assistant)) {
            $contents[] = [
                "role" => "assistant",
                "parts" => [
                    ["text" => $assistant]
                ]
            ];
        }

        // Prompt del usuario
        $contents[] = [
            "role" => "user",
            "parts" => [
                ["text" => $userPrompt]
            ]
        ];

        $data = [
            "contents" => $contents
        ];

        $payload = json_encode($data);

        $ch = curl_init($url);

        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => [
                "Content-Type: application/json"
            ],
            CURLOPT_POSTFIELDS => $payload
        ]);

        $response = curl_exec($ch);
        $error = curl_error($ch);

        curl_close($ch);

        if ($error) {
            return "Error en la solicitud cURL: " . $error;
        }
        
        return json_decode($response, true);
    }
}


    