<?php
/**
 * API Arquitect App — proyectos en arquitect-app/reserved_projects/
 * Rutas validadas; la carpeta reserved_projects no se elimina desde aquí.
 */

if (!function_exists('arquitect_api_dispatch')) {
    function arquitect_api_projects_root() {
        $r = (defined('GRID_ROOT') ? GRID_ROOT : dirname(__DIR__)) . '/arquitect-app/reserved_projects';
        return str_replace(['\\', '//'], ['/', '/'], $r);
    }

    function arquitect_api_safe_id($id) {
        $id = (string)$id;
        if (!preg_match('/^[a-zA-Z0-9_-]{1,64}$/', $id)) {
            return '';
        }
        return $id;
    }

    function arquitect_api_project_dir($id) {
        $id = arquitect_api_safe_id($id);
        if ($id === '') {
            return '';
        }
        return arquitect_api_projects_root() . '/' . $id;
    }

    function arquitect_api_ensure_tree($dir) {
        $sub = ['assets', 'exports', 'snapshots', 'thumbs', 'ai'];
        if (!is_dir($dir)) {
            if (!@mkdir($dir, 0755, true)) {
                return false;
            }
        }
        foreach ($sub as $s) {
            $p = $dir . '/' . $s;
            if (!is_dir($p)) {
                @mkdir($p, 0755, true);
            }
        }
        return true;
    }

    function arquitect_api_read_json($path) {
        if (!is_file($path)) {
            return null;
        }
        $raw = @file_get_contents($path);
        if ($raw === false || $raw === '') {
            return null;
        }
        $d = json_decode($raw, true);
        return is_array($d) ? $d : null;
    }

    function arquitect_api_write_json($path, $data) {
        $json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
        if ($json === false) {
            return false;
        }
        return @file_put_contents($path, $json) !== false;
    }

    function arquitect_api_dispatch($action) {
        $action = (string)$action;
        $prefix = 'arquitect';
        if (strpos($action, $prefix) !== 0) {
            return false;
        }

        $root = arquitect_api_projects_root();
        if (!is_dir($root)) {
            @mkdir($root, 0755, true);
        }
        $configDir = $root . '/.config';
        if (!is_dir($configDir)) {
            @mkdir($configDir, 0755, true);
        }
        $keyFile = $configDir . '/openai_key.txt';

        header('Content-Type: application/json; charset=utf-8');

        // ---------- listProjects ----------
        if ($action === 'arquitectListProjects') {
            $out = [];
            if (is_dir($root)) {
                $items = @scandir($root);
                if ($items) {
                    foreach ($items as $name) {
                        if ($name === '.' || $name === '..' || $name === '.config') {
                            continue;
                        }
                        $pid = arquitect_api_safe_id($name);
                        if ($pid === '') {
                            continue;
                        }
                        $pdir = $root . '/' . $pid;
                        if (!is_dir($pdir)) {
                            continue;
                        }
                        $pj = arquitect_api_read_json($pdir . '/project.json');
                        if ($pj === null) {
                            continue;
                        }
                        $out[] = [
                            'id' => $pj['id'] ?? $pid,
                            'nombre' => $pj['nombre'] ?? $pid,
                            'descripcion' => $pj['descripcion'] ?? '',
                            'fecha_actualizacion' => $pj['fecha_actualizacion'] ?? '',
                            'miniatura_principal' => $pj['miniatura_principal'] ?? '',
                            'ubicacion_textual' => $pj['ubicacion_textual'] ?? '',
                            'coordenadas' => $pj['coordenadas'] ?? null,
                        ];
                    }
                }
            }
            usort($out, function ($a, $b) {
                return strcmp($b['fecha_actualizacion'] ?? '', $a['fecha_actualizacion'] ?? '');
            });
            echo json_encode(['success' => true, 'projects' => $out], JSON_UNESCAPED_UNICODE);
            return true;
        }

        // ---------- createProject ----------
        if ($action === 'arquitectCreateProject') {
            $input = json_decode(file_get_contents('php://input'), true);
            if (!is_array($input)) {
                echo json_encode(['success' => false, 'error' => 'JSON inválido']);
                return true;
            }
            $nombre = isset($input['nombre']) ? trim((string)$input['nombre']) : '';
            if ($nombre === '') {
                echo json_encode(['success' => false, 'error' => 'Nombre requerido']);
                return true;
            }
            $id = 'p_' . bin2hex(random_bytes(8));
            $pdir = arquitect_api_project_dir($id);
            if ($pdir === '' || !arquitect_api_ensure_tree($pdir)) {
                echo json_encode(['success' => false, 'error' => 'No se pudo crear carpeta']);
                return true;
            }
            $now = date('c');
            $sheetId = 's_' . bin2hex(random_bytes(6));
            $layerId = 'l_' . bin2hex(random_bytes(6));
            $project = [
                'schemaVersion' => 1,
                'id' => $id,
                'nombre' => $nombre,
                'descripcion' => isset($input['descripcion']) ? (string)$input['descripcion'] : '',
                'fecha_creacion' => $now,
                'fecha_actualizacion' => $now,
                'ubicacion_textual' => isset($input['ubicacion_textual']) ? (string)$input['ubicacion_textual'] : '',
                'coordenadas' => $input['coordenadas'] ?? null,
                'ruta_carpeta_proyecto' => 'arquitect-app/reserved_projects/' . $id,
                'miniatura_principal' => '',
                'estado' => 'active',
                'configuracion_local' => new stdClass(),
                'hojas' => [[
                    'id' => $sheetId,
                    'nombre' => 'Hoja 1',
                    'orden' => 0,
                    'ancho' => 1920,
                    'alto' => 1080,
                    'fondo' => '#f4f4f5',
                    'zoom_actual' => 1,
                    'rotacion_actual' => 0,
                    'pan_actual' => ['x' => 0, 'y' => 0],
                    'capas' => [[
                        'id' => $layerId,
                        'nombre' => 'Capa base',
                        'tipo' => 'vector',
                        'visible' => true,
                        'bloqueada' => false,
                        'opacidad' => 1,
                        'blend_mode' => 'normal',
                        'z_index' => 0,
                        'es_capa_base' => true,
                        'contenido' => [
                            'strokes' => [],
                            'texts' => [],
                            'shapes' => [],
                            'imageSrc' => null,
                            'imageTransform' => null,
                        ],
                        'metadatos' => new stdClass(),
                    ]],
                    'historial' => ['undo' => [], 'redo' => []],
                    'miniatura' => '',
                    'timestamp_ultima_edicion' => time(),
                ]],
                'hoja_activa_id' => $sheetId,
                'assets' => [],
                'historial_global' => [],
                'chat_ia' => [],
                'exportaciones' => [],
                'materiales' => [],
                'metadatos' => new stdClass(),
            ];
            if (!arquitect_api_write_json($pdir . '/project.json', $project)) {
                echo json_encode(['success' => false, 'error' => 'No se pudo guardar proyecto']);
                return true;
            }
            echo json_encode(['success' => true, 'project' => $project], JSON_UNESCAPED_UNICODE);
            return true;
        }

        // ---------- loadProject ----------
        if ($action === 'arquitectLoadProject') {
            $pid = arquitect_api_safe_id($_GET['projectId'] ?? '');
            if ($pid === '') {
                echo json_encode(['success' => false, 'error' => 'ID inválido']);
                return true;
            }
            $pdir = arquitect_api_project_dir($pid);
            if ($pdir === '' || !is_dir($pdir)) {
                echo json_encode(['success' => false, 'error' => 'Proyecto no encontrado']);
                return true;
            }
            $pj = arquitect_api_read_json($pdir . '/project.json');
            if ($pj === null) {
                echo json_encode(['success' => false, 'error' => 'JSON corrupto o vacío']);
                return true;
            }
            echo json_encode(['success' => true, 'project' => $pj], JSON_UNESCAPED_UNICODE);
            return true;
        }

        // ---------- saveProject ----------
        if ($action === 'arquitectSaveProject') {
            $input = json_decode(file_get_contents('php://input'), true);
            if (!is_array($input) || !isset($input['project'])) {
                echo json_encode(['success' => false, 'error' => 'Datos inválidos']);
                return true;
            }
            $pj = $input['project'];
            $pid = arquitect_api_safe_id($pj['id'] ?? '');
            if ($pid === '') {
                echo json_encode(['success' => false, 'error' => 'ID proyecto inválido']);
                return true;
            }
            $pdir = arquitect_api_project_dir($pid);
            if ($pdir === '' || !is_dir($pdir)) {
                echo json_encode(['success' => false, 'error' => 'Carpeta no existe']);
                return true;
            }
            $pj['fecha_actualizacion'] = date('c');
            if (!arquitect_api_write_json($pdir . '/project.json', $pj)) {
                echo json_encode(['success' => false, 'error' => 'Escritura fallida']);
                return true;
            }
            echo json_encode(['success' => true], JSON_UNESCAPED_UNICODE);
            return true;
        }

        // ---------- deleteProject ----------
        if ($action === 'arquitectDeleteProject') {
            $input = json_decode(file_get_contents('php://input'), true);
            $pid = arquitect_api_safe_id($input['projectId'] ?? '');
            if ($pid === '') {
                echo json_encode(['success' => false, 'error' => 'ID inválido']);
                return true;
            }
            $pdir = arquitect_api_project_dir($pid);
            if ($pdir === '' || !is_dir($pdir)) {
                echo json_encode(['success' => false, 'error' => 'No encontrado']);
                return true;
            }
            arquitect_api_rrmdir($pdir);
            echo json_encode(['success' => true]);
            return true;
        }

        // ---------- duplicateProject ----------
        if ($action === 'arquitectDuplicateProject') {
            $input = json_decode(file_get_contents('php://input'), true);
            $pid = arquitect_api_safe_id($input['projectId'] ?? '');
            if ($pid === '') {
                echo json_encode(['success' => false, 'error' => 'ID inválido']);
                return true;
            }
            $src = arquitect_api_project_dir($pid);
            if ($src === '' || !is_dir($src)) {
                echo json_encode(['success' => false, 'error' => 'Origen no existe']);
                return true;
            }
            $newId = 'p_' . bin2hex(random_bytes(8));
            $dst = arquitect_api_project_dir($newId);
            arquitect_api_copy_recursive($src, $dst);
            $pj = arquitect_api_read_json($dst . '/project.json');
            if ($pj === null) {
                arquitect_api_rrmdir($dst);
                echo json_encode(['success' => false, 'error' => 'Copia fallida']);
                return true;
            }
            $pj['id'] = $newId;
            $pj['nombre'] = isset($input['nombre']) && trim((string)$input['nombre']) !== ''
                ? trim((string)$input['nombre'])
                : (($pj['nombre'] ?? 'Proyecto') . ' (copia)');
            $pj['fecha_creacion'] = date('c');
            $pj['ruta_carpeta_proyecto'] = 'arquitect-app/reserved_projects/' . $newId;
            arquitect_api_write_json($dst . '/project.json', $pj);
            echo json_encode(['success' => true, 'project' => $pj], JSON_UNESCAPED_UNICODE);
            return true;
        }

        // ---------- renameProject ----------
        if ($action === 'arquitectRenameProject') {
            $input = json_decode(file_get_contents('php://input'), true);
            $pid = arquitect_api_safe_id($input['projectId'] ?? '');
            $nombre = isset($input['nombre']) ? trim((string)$input['nombre']) : '';
            if ($pid === '' || $nombre === '') {
                echo json_encode(['success' => false, 'error' => 'Datos inválidos']);
                return true;
            }
            $pdir = arquitect_api_project_dir($pid);
            $pj = arquitect_api_read_json($pdir . '/project.json');
            if ($pj === null) {
                echo json_encode(['success' => false, 'error' => 'Proyecto no encontrado']);
                return true;
            }
            $pj['nombre'] = $nombre;
            $pj['fecha_actualizacion'] = date('c');
            arquitect_api_write_json($pdir . '/project.json', $pj);
            echo json_encode(['success' => true, 'project' => $pj], JSON_UNESCAPED_UNICODE);
            return true;
        }

        // ---------- uploadProjectFile ----------
        if ($action === 'arquitectUploadProjectFile') {
            $pid = arquitect_api_safe_id($_POST['projectId'] ?? '');
            $folder = preg_replace('/[^a-z]/', '', strtolower((string)($_POST['folder'] ?? 'assets')));
            if (!in_array($folder, ['assets', 'exports', 'ai', 'thumbs', 'snapshots'], true)) {
                $folder = 'assets';
            }
            if ($pid === '' || !isset($_FILES['file'])) {
                echo json_encode(['success' => false, 'error' => 'Parámetros inválidos']);
                return true;
            }
            $pdir = arquitect_api_project_dir($pid);
            if ($pdir === '' || !is_dir($pdir)) {
                echo json_encode(['success' => false, 'error' => 'Proyecto no existe']);
                return true;
            }
            $f = $_FILES['file'];
            if ($f['error'] !== UPLOAD_ERR_OK) {
                echo json_encode(['success' => false, 'error' => 'Error de subida']);
                return true;
            }
            $ext = strtolower(pathinfo($f['name'], PATHINFO_EXTENSION));
            if (!preg_match('/^[a-z0-9]{1,8}$/', $ext)) {
                $ext = 'bin';
            }
            $fname = bin2hex(random_bytes(8)) . '_' . time() . '.' . $ext;
            $destDir = $pdir . '/' . $folder;
            if (!is_dir($destDir)) {
                @mkdir($destDir, 0755, true);
            }
            $dest = $destDir . '/' . $fname;
            if (!@move_uploaded_file($f['tmp_name'], $dest)) {
                echo json_encode(['success' => false, 'error' => 'No se pudo mover archivo']);
                return true;
            }
            $rel = 'arquitect-app/reserved_projects/' . $pid . '/' . $folder . '/' . $fname;
            echo json_encode(['success' => true, 'path' => $rel, 'filename' => $fname], JSON_UNESCAPED_UNICODE);
            return true;
        }

        // ---------- saveOpenaiKey ----------
        if ($action === 'arquitectSaveOpenaiKey') {
            $input = json_decode(file_get_contents('php://input'), true);
            $key = isset($input['apiKey']) ? trim((string)$input['apiKey']) : '';
            if ($key === '') {
                @unlink($keyFile);
                echo json_encode(['success' => true, 'saved' => false]);
                return true;
            }
            if (@file_put_contents($keyFile, $key) === false) {
                echo json_encode(['success' => false, 'error' => 'No se pudo guardar clave']);
                return true;
            }
            @chmod($keyFile, 0600);
            echo json_encode(['success' => true, 'saved' => true]);
            return true;
        }

        // ---------- openaiKeyStatus ----------
        if ($action === 'arquitectOpenaiKeyStatus') {
            $has = is_file($keyFile) && filesize($keyFile) > 0;
            echo json_encode(['success' => true, 'hasKey' => $has]);
            return true;
        }

        // ---------- openaiImage ----------
        if ($action === 'arquitectOpenaiImage') {
            if (!is_file($keyFile)) {
                echo json_encode(['success' => false, 'error' => 'API Key no configurada', 'code' => 'NO_KEY']);
                return true;
            }
            $apiKey = trim((string)@file_get_contents($keyFile));
            if ($apiKey === '') {
                echo json_encode(['success' => false, 'error' => 'API Key vacía', 'code' => 'NO_KEY']);
                return true;
            }
            $input = json_decode(file_get_contents('php://input'), true);
            if (!is_array($input) || empty($input['prompt'])) {
                echo json_encode(['success' => false, 'error' => 'Prompt requerido']);
                return true;
            }
            $body = json_encode([
                'model' => $input['model'] ?? 'dall-e-3',
                'prompt' => substr((string)$input['prompt'], 0, 4000),
                'n' => 1,
                'size' => $input['size'] ?? '1024x1024',
                'response_format' => 'b64_json',
            ], JSON_UNESCAPED_UNICODE);
            $ch = curl_init('https://api.openai.com/v1/images/generations');
            curl_setopt_array($ch, [
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => $body,
                CURLOPT_HTTPHEADER => [
                    'Content-Type: application/json',
                    'Authorization: Bearer ' . $apiKey,
                ],
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 120,
            ]);
            $resp = curl_exec($ch);
            $err = curl_error($ch);
            $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            if ($resp === false) {
                echo json_encode(['success' => false, 'error' => $err ?: 'Red']);
                return true;
            }
            $j = json_decode($resp, true);
            if ($code >= 400) {
                $msg = isset($j['error']['message']) ? $j['error']['message'] : $resp;
                echo json_encode(['success' => false, 'error' => $msg, 'http' => $code]);
                return true;
            }
            $b64 = $j['data'][0]['b64_json'] ?? null;
            if (!$b64) {
                echo json_encode(['success' => false, 'error' => 'Respuesta sin imagen']);
                return true;
            }
            echo json_encode(['success' => true, 'b64_json' => $b64], JSON_UNESCAPED_UNICODE);
            return true;
        }

        // ---------- openaiImageFromImage (visión + generación) ----------
        if ($action === 'arquitectOpenaiImageFromImage') {
            if (!is_file($keyFile)) {
                echo json_encode(['success' => false, 'error' => 'API Key no configurada', 'code' => 'NO_KEY']);
                return true;
            }
            $apiKey = trim((string)@file_get_contents($keyFile));
            if ($apiKey === '') {
                echo json_encode(['success' => false, 'error' => 'API Key vacía', 'code' => 'NO_KEY']);
                return true;
            }
            $input = json_decode(file_get_contents('php://input'), true);
            if (!is_array($input)) {
                echo json_encode(['success' => false, 'error' => 'JSON inválido']);
                return true;
            }
            $imageB64 = isset($input['imageB64']) ? (string)$input['imageB64'] : '';
            $prompt = isset($input['prompt']) ? trim((string)$input['prompt']) : '';
            if ($imageB64 === '' || $prompt === '') {
                echo json_encode(['success' => false, 'error' => 'Imagen (base64) y prompt requeridos']);
                return true;
            }
            if (strlen($imageB64) > 12000000) {
                echo json_encode(['success' => false, 'error' => 'Imagen demasiado grande']);
                return true;
            }
            $visionModel = $input['visionModel'] ?? 'gpt-4o-mini';
            $visionBody = json_encode([
                'model' => $visionModel,
                'messages' => [
                    [
                        'role' => 'user',
                        'content' => [
                            [
                                'type' => 'text',
                                'text' => 'Describe briefly in Spanish what you see in this image (architectural sketch, composition, materials). Maximum 3 short sentences.',
                            ],
                            [
                                'type' => 'image_url',
                                'image_url' => [
                                    'url' => 'data:image/png;base64,' . $imageB64,
                                ],
                            ],
                        ],
                    ],
                ],
                'max_tokens' => 400,
            ], JSON_UNESCAPED_UNICODE);
            $chV = curl_init('https://api.openai.com/v1/chat/completions');
            curl_setopt_array($chV, [
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => $visionBody,
                CURLOPT_HTTPHEADER => [
                    'Content-Type: application/json',
                    'Authorization: Bearer ' . $apiKey,
                ],
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 120,
            ]);
            $respV = curl_exec($chV);
            $codeV = curl_getinfo($chV, CURLINFO_HTTP_CODE);
            curl_close($chV);
            $desc = '';
            if ($respV !== false && $codeV < 400) {
                $jv = json_decode($respV, true);
                if (isset($jv['choices'][0]['message']['content'])) {
                    $desc = trim((string)$jv['choices'][0]['message']['content']);
                }
            }
            $fullPrompt = $prompt;
            if ($desc !== '') {
                $fullPrompt .= "\n\nContexto visual (descripción automática): " . $desc;
            }
            $genModel = $input['model'] ?? 'dall-e-3';
            $size = $input['size'] ?? '1024x1024';
            $body = json_encode([
                'model' => $genModel,
                'prompt' => substr($fullPrompt, 0, 4000),
                'n' => 1,
                'size' => $size,
                'response_format' => 'b64_json',
            ], JSON_UNESCAPED_UNICODE);
            $ch = curl_init('https://api.openai.com/v1/images/generations');
            curl_setopt_array($ch, [
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => $body,
                CURLOPT_HTTPHEADER => [
                    'Content-Type: application/json',
                    'Authorization: Bearer ' . $apiKey,
                ],
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 120,
            ]);
            $resp = curl_exec($ch);
            $err = curl_error($ch);
            $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            if ($resp === false) {
                echo json_encode(['success' => false, 'error' => $err ?: 'Red']);
                return true;
            }
            $j = json_decode($resp, true);
            if ($code >= 400) {
                $msg = isset($j['error']['message']) ? $j['error']['message'] : $resp;
                echo json_encode(['success' => false, 'error' => $msg, 'http' => $code]);
                return true;
            }
            $b64 = $j['data'][0]['b64_json'] ?? null;
            if (!$b64) {
                echo json_encode(['success' => false, 'error' => 'Respuesta sin imagen']);
                return true;
            }
            echo json_encode([
                'success' => true,
                'b64_json' => $b64,
                'prompt_final' => $fullPrompt,
                'vision_description' => $desc,
            ], JSON_UNESCAPED_UNICODE);
            return true;
        }

        // ---------- saveSnapshot ----------
        if ($action === 'arquitectSaveSnapshot') {
            $input = json_decode(file_get_contents('php://input'), true);
            $pid = arquitect_api_safe_id($input['projectId'] ?? '');
            if ($pid === '') {
                echo json_encode(['success' => false, 'error' => 'ID inválido']);
                return true;
            }
            $pdir = arquitect_api_project_dir($pid);
            if ($pdir === '' || !is_dir($pdir)) {
                echo json_encode(['success' => false, 'error' => 'Proyecto no existe']);
                return true;
            }
            $snapDir = $pdir . '/snapshots';
            if (!is_dir($snapDir)) {
                @mkdir($snapDir, 0755, true);
            }
            $name = preg_replace('/[^a-zA-Z0-9_-]/', '_', (string)($input['label'] ?? 'snap'));
            $file = $snapDir . '/' . time() . '_' . $name . '.json';
            $data = $input['data'] ?? null;
            if (!is_array($data)) {
                echo json_encode(['success' => false, 'error' => 'Sin datos']);
                return true;
            }
            if (@file_put_contents($file, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)) === false) {
                echo json_encode(['success' => false, 'error' => 'Escritura fallida']);
                return true;
            }
            $rel = 'arquitect-app/reserved_projects/' . $pid . '/snapshots/' . basename($file);
            echo json_encode(['success' => true, 'path' => $rel], JSON_UNESCAPED_UNICODE);
            return true;
        }

        // ---------- listSnapshots ----------
        if ($action === 'arquitectListSnapshots') {
            $pid = arquitect_api_safe_id($_GET['projectId'] ?? '');
            if ($pid === '') {
                echo json_encode(['success' => false, 'error' => 'ID inválido']);
                return true;
            }
            $snapDir = arquitect_api_project_dir($pid) . '/snapshots';
            $list = [];
            if (is_dir($snapDir)) {
                $items = @scandir($snapDir);
                if ($items) {
                    foreach ($items as $f) {
                        if (substr($f, -5) !== '.json') {
                            continue;
                        }
                        $list[] = ['name' => $f, 'mtime' => @filemtime($snapDir . '/' . $f)];
                    }
                }
            }
            usort($list, function ($a, $b) {
                return ($b['mtime'] ?? 0) - ($a['mtime'] ?? 0);
            });
            echo json_encode(['success' => true, 'snapshots' => $list], JSON_UNESCAPED_UNICODE);
            return true;
        }

        // ---------- loadSnapshot ----------
        if ($action === 'arquitectLoadSnapshot') {
            $pid = arquitect_api_safe_id($_GET['projectId'] ?? '');
            $name = basename((string)($_GET['name'] ?? ''));
            if ($pid === '' || $name === '' || strpos($name, '..') !== false) {
                echo json_encode(['success' => false, 'error' => 'Parámetros inválidos']);
                return true;
            }
            $path = arquitect_api_project_dir($pid) . '/snapshots/' . $name;
            $data = arquitect_api_read_json($path);
            if ($data === null) {
                echo json_encode(['success' => false, 'error' => 'No encontrado']);
                return true;
            }
            echo json_encode(['success' => true, 'data' => $data], JSON_UNESCAPED_UNICODE);
            return true;
        }

        return false;
    }

    function arquitect_api_rrmdir($dir) {
        if (!is_dir($dir)) {
            return;
        }
        $items = @scandir($dir);
        if ($items) {
            foreach ($items as $it) {
                if ($it === '.' || $it === '..') {
                    continue;
                }
                $p = $dir . '/' . $it;
                if (is_dir($p)) {
                    arquitect_api_rrmdir($p);
                } else {
                    @unlink($p);
                }
            }
        }
        @rmdir($dir);
    }

    function arquitect_api_copy_recursive($src, $dst) {
        if (!is_dir($src)) {
            return false;
        }
        if (!is_dir($dst)) {
            @mkdir($dst, 0755, true);
        }
        $items = @scandir($src);
        if (!$items) {
            return true;
        }
        foreach ($items as $it) {
            if ($it === '.' || $it === '..') {
                continue;
            }
            $from = $src . '/' . $it;
            $to = $dst . '/' . $it;
            if (is_dir($from)) {
                arquitect_api_copy_recursive($from, $to);
            } else {
                @copy($from, $to);
            }
        }
        return true;
    }
}
