<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\File;
use App\Custom\SQLConnection;
use App\Custom\Misc;
use stdClass;
use Response;
use CURLFile;
use Session;
use Request;
use Route;
use DB;


class OpenAiController extends Controller{     
     
    // Endopoint que sirve para cargar los archivos(batch) a OpenAI
    public static function openAiFileEndpoit($batchFile){
        $apiKey = env("apiKey_chatgpt"); 
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "https://api.openai.com/v1/files");
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "Authorization: Bearer $apiKey",
            "Content-Type: multipart/form-data"
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, [
            'purpose' => 'batch',
            'file' => new CURLFile(realpath($batchFile))
        ]);
    
        $response = curl_exec($ch);
        if (curl_errno($ch)) {
            return response()->json(['error' => 'cURL error: ' . curl_error($ch)], 500);
        }
    
        curl_close($ch);
        
        $respuesta = json_decode($response, true);
        
        return $respuesta;
    }   

    public static function entrEnd($batchFile){
        $apiKey = ENV('apiKey_chatgpt');

        $filePath = '/var/www/html/compartido/batchinput.jsonl';        

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, 'https://api.openai.com/v1/files');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);

        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "Authorization: Bearer $apiKey"
        ]);

        curl_setopt($ch, CURLOPT_POSTFIELDS, [
            'purpose' => 'fine-tune',
            'file' => new CURLFile($filePath)
        ]);

        $response = curl_exec($ch);
        curl_close($ch);

        $respuesta = json_decode($response, true);
        
        return $respuesta;
    }

    // Esta funcion lista todos los batch que se realizaron 
    public static function listarBatchProcesos(){
        $apiKey = env("apiKey_chatgpt");
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, "https://api.openai.com/v1/batches?limit=20");

        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "Authorization: Bearer $apiKey",
            "Content-Type: application/json"
        ]);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        $response = curl_exec($ch);
        if (curl_errno($ch)) {
            return response()->json(['error' => 'cURL error: ' . curl_error($ch)], 500);
        }
    
        curl_close($ch);
        $respuesta = json_decode($response, true);
        
        return $respuesta;
    }

    /**
    * Con esta funcion obtenemos la respuesta de un batch procesado
    * el resultado se guarda en un json en la carpeta de compartido
    */
    public static function obtenerResultadoBatch(){
        $apiKey = env("apiKey_chatgpt"); 

        $batchIdOutput = 'file-test';
        $url = "https://api.openai.com/v1/files/$batchIdOutput/content";
        $pathGuardarResultado = '/var/www/html/compartido/openAIBatch/';

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "Authorization: Bearer $apiKey"
        ]);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        $response = curl_exec($ch);
        if (curl_errno($ch)) {
            return 'Error: ' . curl_error($ch);
        } else {
            file_put_contents($pathGuardarResultado . 'batch_output.jsonl', $response);
            return "El archivo se genero con exito como batch_output.jsonl";
        }

        curl_close($ch);        
    }

    public static function obtenerResultadoBatchDiario($outputFileId, $carpeta){
        $apiKey = env("apiKey_chatgpt"); 

        //$batchIdOutput = 'file-test';
     
        
        $url = "https://api.openai.com/v1/files/$outputFileId/content";
        //$pathGuardarResultado = '/var/www/html/compartido/openAIBatch/batchDiario/';
        $pathGuardarResultado = '/var/www/html/compartido/openAIBatch/';
        
              
        if (!is_null($carpeta)) {
            $pathGuardarResultado = '/var/www/html/compartido/openAIBatch/' . $carpeta . '/';            
        }
         
        $fecha_actual = date('Y-m-d');

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

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "Authorization: Bearer $apiKey"
        ]);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        $response = curl_exec($ch);

        if (curl_errno($ch)) {
            return 'Error: ' . curl_error($ch);
        } else {
            file_put_contents($pathGuardarResultado . 'batch_output.jsonl', $response);
            return "El archivo se genero con exito como batch_output.jsonl";
        }

        curl_close($ch);        
    }

    // Esta funcion procesa el batch generado 
    public static function procesarBatchAI($idBatch,$matchedModelId, $id_prompt,$user_id, $fechaFormateada,$batchType){
        $apiKey = env("apiKey_chatgpt"); 
        // Inicializa cURL
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, "https://api.openai.com/v1/batches");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "Authorization: Bearer $apiKey",
            "Content-Type: application/json"
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
            "input_file_id" => $idBatch,
            "endpoint" => "/v1/chat/completions",
            "completion_window" => "24h"
        ]));

        $response = curl_exec($ch);
        if (curl_errno($ch)) {
            return response()->json(['error' => 'cURL error: ' . curl_error($ch)], 500);
        }
    
        curl_close($ch);
        $respuesta = json_decode($response, true);
        $respuestaApi = json_encode($respuesta, true);

        SQLConnection::backendStoreProcedure('sp_ProcessBatchAi', ['INSERT_BATCH', $respuesta['id'], $respuestaApi, $matchedModelId, $id_prompt, $respuesta['status'], $user_id, $fechaFormateada,NULL, $batchType]);             
        
        return $respuesta;
    }

    // Funcion para verifica el estado de un batch 
    public static function verificarEstadoBatch($batch_id){
        $apiKey = env("apiKey_chatgpt"); 

        $url = "https://api.openai.com/v1/batches/$batch_id";
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ]);

        $response = curl_exec($ch);
        if ($response === false) {
            $error = curl_error($ch);
            curl_close($ch);
            die("Error en la solicitud cURL: $error");
        }

        curl_close($ch);
        
        $resultado = json_decode($response, true);
        $respuestaApi = json_encode($response, true);

        SQLConnection::backendStoreProcedure('sp_ProcessBatchAi', ['EDIT_BATCH', $batch_id, $respuestaApi, null, null, $resultado['status'], null]);
        
        return $resultado;
    }

    public static function completionsEndpoint($dataString){
        // URL y cabeceras de la API
        $url = 'https://api.openai.com/v1/chat/completions';
        $headers = [
            "Content-Type: application/json",
            "OpenAI-Organization: " . env("Organization_CHATkey"),
            "Authorization: Bearer " . env("apiKey_chatgpt")
        ];

        // Inicializar cURL
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $dataString,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_RETURNTRANSFER => true
        ]);

        // Realizar la solicitud
        $response = curl_exec($ch);
        
        // Manejo de errores cURL
        if (curl_errno($ch)) {
            curl_close($ch);
            return 'Error en la solicitud: ' . curl_error($ch);
        }

        curl_close($ch);

        $respuesta = json_decode($response, true);

        return $respuesta;
    }

    // Formateo del batch para enviar a OpenAI 
    public static function formateoBatch($fechaEdicto,$idFide,$fuente,$model,$contentSystem,$contentUser,$contenido_archivo,$tokens){
        // Crear el UUID formateado para el edicto
        $uuid = uniqid("{$fuente}_{$fechaEdicto}_{$idFide}_", true);

        $batchFormateo = [
            "custom_id" => $uuid,
            "method" => "POST",
            "url" => "/v1/chat/completions",                
            "body" => [
                "model" => $model,
                "messages" => [
                    ["role" => "system", "content" => $contentSystem],
                    ['role' => 'user', 'content' => $contentUser],
                    ["role" => "assistant", "content" => $contenido_archivo] 
                ],
                "temperature" => 0,
                "max_completion_tokens" => $tokens
            ]
        ];
        
        return $batchFormateo;
    }

    public static function formateoCompletions($ai_provider,$system_prompt,$user_prompt,$textoDatos,$tokens){        
        // Preparar los datos para la solicitud
        $requestData = [
            'model' => $ai_provider,
            'messages' => [
                ['role' => 'system', 'content' => $system_prompt],
                ['role' => 'user', 'content' => $user_prompt],
                ['role' => 'assistant', 'content' => $textoDatos]
            ],
            'temperature' => 0,
            'max_completion_tokens' => $tokens
        ];

        $dataString = json_encode($requestData);
        
        return $dataString;
    }    

    public static function erroresArchivo(){
        $apiKey = 'TU_API_KEY'; // Sustituye con tu clave API de OpenAI
        $errorFileId = 'file-FzYCLUUmk5xHVCDKXjoqjP'; // ID del archivo de errores
        $outputFile = 'error_details.jsonl'; // Nombre del archivo donde se guardarán los errores

        // Configuración de la URL y los encabezados
        $url = "https://api.openai.com/v1/files/$errorFileId/content";
        $headers = [
            "Content-Type: application/json",
            "OpenAI-Organization: " . env("Organization_CHATkey"),
            "Authorization: Bearer " . env("apiKey_chatgpt")
        ];

        // Inicializar cURL
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        // Ejecutar la solicitud y obtener el contenido
        $response = curl_exec($ch);        

        // Verificar si hubo un error
        if (curl_errno($ch)) {
            echo 'Error en cURL: ' . curl_error($ch);
        } else {
            // Guardar el contenido del archivo de errores
            file_put_contents($outputFile, $response);
            echo "Archivo de errores guardado en '$outputFile'.\n";
        }

        // Cerrar la sesión cURL
        curl_close($ch);
    }


    /**
    * Obtiene la lista de modelos disponibles desde la API de OpenAI
    *
    * Esta funcion hace una solicitud a la API de OpenAI para obtener la lista de modelos disponibles 
    *
    * @return array La lista de modelos disponibles desde la API de OpenAI
    */
    public static function obtenerModelosGpt()
    {
        // URL de la API de OpenAI para obtener modelos
        $url = 'https://api.openai.com/v1/models';

        $apiKey = env("apiKey_chatgpt");

        // Inicializa una session cURL
        $ch = curl_init($url);

        // Configura las opciones de cURL
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $apiKey
        ]);

        // Ejecuta la solicitud cURL y obtiene la respuesta
        $response = curl_exec($ch);

        // Cierra la session cURL
        curl_close($ch);

        $models = json_decode($response, true);

        return $models['data'];
    }

    public static function listarArchivosOpenAI(): array{
        $apiKey = env("apiKey_chatgpt");
        $curl = curl_init();
        curl_setopt_array($curl, [
            CURLOPT_URL => "https://api.openai.com/v1/fine_tuning/jobs",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => [
                "Authorization: Bearer {$apiKey}",
                "Content-Type: application/json",
            ],
        ]);

        $response = curl_exec($curl);

        if (curl_errno($curl)) {
            throw new Exception('Error en cURL: ' . curl_error($curl));
        }

        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);

        if ($httpCode !== 200) {
            throw new Exception("Error en la respuesta HTTP: Código $httpCode");
        }

        $data = json_decode($response, true);

        if (!isset($data['data'])) {
            throw new Exception("Estructura inesperada en la respuesta: " . $response);
        }

        return $data['data'];
    }

    public static function dataJsonStructure(){
       $apiKey = env('apiKey_chatgpt');

        $functionSchema = [
            "name" => "completar_datos_edictos",
            "description" => "Completa la estructura JSON de datos societarios",
            "parameters" => [ // Aquí va el JSON Schema
                "type" => "object",
                "properties" => [
                    "Datos_Empresa" => [
                        "type" => "object",
                        "properties" => [
                            "nombre_actual" => ["type" => "string"],
                            "nombre_anterior" => ["type" => "string"],
                            "cuit_empresa" => ["type" => "string"],
                            "domicilio_actual" => ["type" => "string"],
                            "domicilio_anterior" => ["type" => "string"],
                            "empresa_tipo" => ["type" => "string"]
                        ],
                        "required" => ["nombre_actual", "cuit_empresa"]
                    ],
                    "Relacion_Personas" => [
                        "type" => "array",
                        "items" => [
                            "type" => "object",
                            "properties" => [
                                "apellido_nombre" => ["type" => "string"],
                                "persona_DNI" => ["type" => "string"],
                                "persona_cuit" => ["type" => "string"],
                                "persona_domicilio" => ["type" => "string"],
                                "persona_estado_civil" => ["type" => "string"],
                                "persona_conyuge_nombre" => ["type" => "string"],
                                "persona_conyuge_DNI" => ["type" => "string"],
                                "Persona_Cargo" => [
                                    "type" => "array",
                                    "items" => ["type" => "object", "properties" => ["p_rol" => ["type" => "string"]]]
                                ],
                                "permanece_en_cargo?" => ["type" => "string"]
                            ]
                        ]
                    ],
                    "Relacion_Empresas" => [
                        "type" => "array",
                        "items" => [
                            "type" => "object",
                            "properties" => [
                                "Vinculada_nombre" => ["type" => "string"],
                                "Vinculada_cuit" => ["type" => "string"],
                                "Vinculada_Pais" => ["type" => "string"],
                                "Vinculada_domicilio" => ["type" => "string"],
                                "Vinculada_vinculo" => [
                                    "type" => "array",
                                    "items" => ["type" => "object", "properties" => ["e_rol" => ["type" => "string"]]]
                                ]
                            ]
                        ]
                    ],
                    "Datos_Generales" => [
                        "type" => "object",
                        "properties" => [
                            "tipo_edicto" => ["type" => "string"],
                            "fecha_asamblea" => ["type" => "array", "items" => ["type" => "string"]]
                        ]
                    ]
                ],
                "required" => ["Datos_Empresa", "Relacion_Personas", "Relacion_Empresas", "Datos_Generales"]
            ]
        ];

        $texto = <<<TEXT
            GRAS AUTOMOTORES SA DESIGNACION DE AUTORIDADES Por disposicion del Sr Juez a cargo del Registro Publico de la ciudad de Santa Fe en autos caratulados GRAS AUTOMOTORES SA S/ DESIGNACION DE AUTORIDADES CUIJ N 21052151624 se ha ordenado la siguiente publicacion correspondiente a la designacion de autoridades de GRAS AUTOMOTORES SA segun acta de Asamblea Ordinaria de fecha 20 de agosto de 2024  Director titularPresidente el Sr GRAS Sebastian DNI N  32184725 CUIT N 20321847251 nacido en fecha 09081987 soltero comerciante domiciliado en calle 27 N 2755 de la ciudad de San Justo Provincia de Santa Fe y como Director Suplente el Sr GRAS Alejandro DNI N  33111689 CUIT N  20331116891 nacido en fecha 01031986 divorciado comerciante domiciliado en Bv Pellegrini N 2723 de la ciudad de San Justo Provincia de Santa Fe  Santa Fe 10 de Diciembre de 2024 Fdo Dra Liliana G Piana Secretaria
        TEXT;



        $data = [
            "model" => "gpt-4o",
            "messages" => [
                [
                    "role" => "user",
                    //"content" => "Completá los datos del siguiente edicto sin modificar su estructura."
                    "content" => "Analiza el siguiente edicto y completá la estructura:\n\n" . $texto
                ]
            ],
            "tools" => [
                [
                    "type" => "function",
                    "function" => $functionSchema
                ]
            ],
            "tool_choice" => [
                "type" => "function",
                "function" => [
                    "name" => "completar_datos_edictos"
                ]
            ]
        ];

        $ch = curl_init('https://api.openai.com/v1/chat/completions');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $apiKey,
            'Content-Type: application/json'
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

        $response = curl_exec($ch);
        if (curl_errno($ch)) {
            echo 'Error: ' . curl_error($ch);
        }
        curl_close($ch);
        $response = json_decode($response, true);
        $json = $response['choices'][0]['message']['tool_calls'][0]['function']['arguments'];
        dd(json_decode($json, true));
        echo json_encode(json_decode($response, true), JSON_PRETTY_PRINT);
    }

}