<?php
require_once 'models/PseModel.php';
class PseController
{

    public function enviarFactura(int $id_venta): array
    {
        $apiUrl = 'https://facturalahoy.com/api/facturalaya/factura';
        $dataModel = new PseModel();
        $data = $dataModel->getDataComprobante($id_venta);

        // Empresa (RUC y modo)
        $empresa = $dataModel->getDataEmpresa();
        if (!$empresa || empty($empresa['ruc'])) {
            return ['ok' => false, 'error' => 'No se encontró la empresa o falta RUC'];
        }
        $ambiente = ((int) $empresa['modo'] === 1) ? 'produccion' : 'beta';

        // === RUTAS DE DESTINO ===
        // Base de filesystem: subimos desde /facturacion/controllers a /facturacion
        $baseFacturacion = realpath(dirname(__DIR__)); // .../facturacion
        if ($baseFacturacion === false) {
            // Fallback por si realpath falla (p.ej. permisos o symlinks)
            $baseFacturacion = dirname(__DIR__);
        }

        // Carpeta donde se guardarán los ZIP (filesystem)
        $dir_entorno = rtrim($baseFacturacion, '/\\')
            . "/UBL21/archivos_xml_sunat/cpe_xml/{$ambiente}/{$data['cliente_numerodocumento']}/";

        // URL pública opcional para servir esos archivos (si tienes constante URL)
        // Ej: https://tusitio.com/pale/restaurantepro/facturacion/UBL21/archivos_xml_sunat/cpe_xml/{ambiente}/{ruc}/
        $url_publica_entorno = rtrim(URL, '/')
            . "/facturacion/UBL21/archivos_xml_sunat/cpe_xml/{$ambiente}/{$data['cliente_numerodocumento']}/";

        try {
            // Llamar a la API
            $resp = $this->enviarFacturaApi($apiUrl, $data);

            // 1) Validar HTTP
            $http = (int) ($resp['status'] ?? 0);
            if ($http !== 200) {
                throw new \RuntimeException('HTTP inesperado: ' . $http);
            }

            // 2) Validar JSON
            $json = $resp['json'] ?? null;
            if (!$json) {
                throw new \RuntimeException('No llegó el bloque JSON en la respuesta');
            }
            if (($json['respuesta'] ?? '') !== 'ok') {
                $detalle = $json['msj_sunat'] ?? $json['mensaje'] ?? 'sin mensaje';
                throw new \RuntimeException('La API no respondió OK: ' . $detalle);
            }

            $mensaje = $json['resp_sunat']['mensaje'] ?? ($json['msj_sunat'] ?? null);
            $hashCdr = $json['resp_sunat']['hash_cdr'] ?? ($json['hash_cdr'] ?? null);
            $hashCpe = $json['hash_cpe'] ?? null;

            $files = [
                'xml_cpe' => $json['name_file_xml_cpe'] ?? null,
                'zip_cpe' => $json['name_file_zip_cpe'] ?? null,
                'xml_cdr' => $json['name_file_xml_cdr'] ?? null,
                'zip_cdr' => $json['name_file_zip_cdr'] ?? null,
            ];

            // 3) Rutas devueltas por el API (por si las quieres mostrar)
            $rutasApi = [
                'ruta_xml' => $json['ruta_xml'] ?? null,
                'ruta_cdr' => $json['ruta_cdr'] ?? null,
                'ruta_pdf' => $json['ruta_pdf'] ?? null,
                'ruta_cpe_zip' => $json['ruta_cpe_zip'] ?? null,
                'ruta_cdr_zip' => $json['ruta_cdr_zip'] ?? null,
            ];

            // 4) Asegurar carpeta local
            if (!is_dir($dir_entorno) && !mkdir($dir_entorno, 0775, true) && !is_dir($dir_entorno)) {
                throw new \RuntimeException('No se pudo crear la carpeta: ' . $dir_entorno);
            }

            // 5) Guardar ZIPs en Base64 (si vienen)
            $guardarZipB64 = function (?string $b64, string $nombre) use ($dir_entorno): ?string {
                if (!$b64)
                    return null;
                $bin = base64_decode($b64, true);
                if ($bin === false) {
                    throw new \RuntimeException("Base64 inválido para $nombre");
                }
                $path = rtrim($dir_entorno, '/\\') . DIRECTORY_SEPARATOR . $nombre;
                if (file_put_contents($path, $bin) === false) {
                    throw new \RuntimeException("No se pudo guardar $nombre en $path");
                }
                return $path;
            };

            $nombreZipCpe = $json['name_file_zip_cpe'] ?? 'cpe.zip';
            $nombreZipCdr = $json['name_file_zip_cdr'] ?? 'cdr.zip';

            $zipCpeLocal = $guardarZipB64($json['file_cpe_zip'] ?? null, $nombreZipCpe);
            $zipCdrLocal = $guardarZipB64($json['file_cdr_zip'] ?? null, $nombreZipCdr);

            // URLs públicas correspondientes a lo guardado (opcional)
            $zipCpeUrl = $zipCpeLocal ? ($url_publica_entorno . $nombreZipCpe) : null;
            $zipCdrUrl = $zipCdrLocal ? ($url_publica_entorno . $nombreZipCdr) : null;

            // 6) Bloque SUNAT
            $respSunat = $json['resp_sunat'] ?? null;

            $respUpdate = $dataModel->setDataDocumento($id_venta, 1, $http, $mensaje, $nombreZipCpe, $hashCdr, $hashCpe);

            if (!$respUpdate) {
                throw new RuntimeException('No se pudo actualizar tm_venta (execute() falló).');
            }

            // 7) Retornar todo lo útil
            return [
                'ok' => true,
                'http' => $http,
                'resp_sunat' => $respSunat,
                'rutas_api' => $rutasApi,
                'dir_entorno' => $dir_entorno,      // dónde se guardó
                'zip_cpe_local' => $zipCpeLocal,      // path local completo
                'zip_cdr_local' => $zipCdrLocal,      // path local completo
                'zip_cpe_url' => $zipCpeUrl,        // URL pública (si aplica)
                'zip_cdr_url' => $zipCdrUrl,        // URL pública (si aplica)
                'nombres_zip' => [
                    'cpe' => $nombreZipCpe,
                    'cdr' => $nombreZipCdr,
                ],
            ];



        } catch (\Throwable $e) {
            return ['ok' => false, 'error' => $e->getMessage()];
        }
    }




    private function enviarFacturaApi(string $url, array $payload, array $extraHeaders = [], int $timeout = 60): array
    {
        $ch = curl_init($url);

        $headers = array_merge([
            'Content-Type: application/json',
            'Accept: application/json',
        ], $extraHeaders);

        $options = [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
            CURLOPT_CONNECTTIMEOUT => 20,   // segundos para conectar
            CURLOPT_TIMEOUT => $timeout, // segundos totales
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_MAXREDIRS => 5,
            CURLOPT_SSL_VERIFYPEER => true, // mantener true en producción
            CURLOPT_SSL_VERIFYHOST => 2,
        ];

        curl_setopt_array($ch, $options);

        $body = curl_exec($ch);
        $errNo = curl_errno($ch);
        $errMsg = curl_error($ch);
        $info = curl_getinfo($ch);
        curl_close($ch);

        if ($errNo) {

            throw new RuntimeException("Error cURL #$errNo: $errMsg");
        }

        $status = (int) ($info['http_code'] ?? 0);

        $decoded = null;
        if (is_string($body) && $body !== '') {
            $decoded = json_decode($body, true);
        }

        // Opcional: tratar códigos 4xx/5xx como error
        if ($status >= 400) {
            // Puedes registrar $body para depurar
            throw new RuntimeException("La API respondió HTTP $status. Respuesta: " . substr($body ?? '', 0, 1000));
        }

        return [
            'status' => $status,
            'headers' => $info,
            'body' => $body,
            'json' => $decoded,
        ];
    }
}

