<?php
/**
 * Clase para integración con FirmaEC - Servicio de Firma Digital de Ecuador
 * Permite firmar documentos PDF electrónicamente con validez legal
 */
class FirmaEC
{
    private $apiUrl;
    private $token;
    private $timeout = 30;

    /**
     * Constructor
     * @param string $token Token de autenticación de FirmaEC
     * @param string $environment 'produccion' o 'pruebas'
     */
    public function __construct($token = null, $environment = 'produccion')
    {
        if ($environment == 'produccion') {
            $this->apiUrl = 'https://firmadigital.gob.ec/api/v1/';
        } else {
            $this->apiUrl = 'https://firmadigital-test.gob.ec/api/v1/';
        }
        $this->token = $token;
    }

    /**
     * Firmar un documento PDF
     * @param string $pdfPath Ruta al archivo PDF a firmar
     * @param string $certificadoPath Ruta al certificado .p12
     * @param string $password Contraseña del certificado
     * @param array $opciones Opciones adicionales de firma
     * @return string Contenido del PDF firmado
     */
    public function firmarDocumento($pdfPath, $certificadoPath, $password, $opciones = [])
    {
        try {
            // Validar que los archivos existan
            if (!file_exists($pdfPath)) {
                throw new Exception("El archivo PDF no existe: " . $pdfPath);
            }
            if (!file_exists($certificadoPath)) {
                throw new Exception("El certificado no existe: " . $certificadoPath);
            }

            // Leer y codificar PDF
            $pdfContent = file_get_contents($pdfPath);
            $pdfBase64 = base64_encode($pdfContent);

            // Leer y codificar certificado
            $certificado = file_get_contents($certificadoPath);
            $certBase64 = base64_encode($certificado);

            // Preparar datos para la petición
            $data = [
                'documento' => $pdfBase64,
                'certificado' => $certBase64,
                'password' => $password,
                'razon' => isset($opciones['razon']) ? $opciones['razon'] : 'Receta Médica',
                'ubicacion' => isset($opciones['ubicacion']) ? $opciones['ubicacion'] : 'Ecuador',
                'formato' => 'PDF',
                'estampar' => isset($opciones['estampar']) ? $opciones['estampar'] : true,
                'posicion' => isset($opciones['posicion']) ? $opciones['posicion'] : [
                    'x' => 400,
                    'y' => 700,
                    'ancho' => 150,
                    'alto' => 50
                ]
            ];

            // Realizar petición a FirmaEC
            $response = $this->realizarPeticion('firmar', $data);

            if (isset($response['documentoFirmado'])) {
                $pdfFirmado = base64_decode($response['documentoFirmado']);
                return $pdfFirmado;
            } else {
                throw new Exception('Error en respuesta de FirmaEC: ' . json_encode($response));
            }

        } catch (Exception $e) {
            error_log("Error en FirmaEC::firmarDocumento - " . $e->getMessage());
            throw $e;
        }
    }

    /**
     * Verificar la firma de un documento
     * @param string $pdfPath Ruta al PDF firmado
     * @return array Información de la verificación
     */
    public function verificarFirma($pdfPath)
    {
        try {
            if (!file_exists($pdfPath)) {
                throw new Exception("El archivo PDF no existe");
            }

            $pdfContent = file_get_contents($pdfPath);
            $pdfBase64 = base64_encode($pdfContent);

            $data = ['documento' => $pdfBase64];

            $response = $this->realizarPeticion('verificar', $data);

            return $response;

        } catch (Exception $e) {
            error_log("Error en FirmaEC::verificarFirma - " . $e->getMessage());
            throw $e;
        }
    }

    /**
     * Realizar petición HTTP a la API de FirmaEC
     * @param string $endpoint Endpoint de la API
     * @param array $data Datos a enviar
     * @return array Respuesta decodificada
     */
    private function realizarPeticion($endpoint, $data)
    {
        $url = $this->apiUrl . $endpoint;

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $this->token
        ]);

        // Deshabilitar verificación SSL solo en desarrollo
        // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            throw new Exception("Error en cURL: " . $error);
        }

        if ($httpCode != 200) {
            throw new Exception("Error HTTP " . $httpCode . ": " . $response);
        }

        $result = json_decode($response, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception("Error al decodificar JSON: " . json_last_error_msg());
        }

        return $result;
    }

    /**
     * Generar hash SHA256 de un archivo
     * @param string $filePath Ruta al archivo
     * @return string Hash SHA256
     */
    public function generarHash($filePath)
    {
        if (!file_exists($filePath)) {
            throw new Exception("El archivo no existe");
        }
        return hash_file('sha256', $filePath);
    }
}
?>