<?php
/**
 * سودانا — ToolsEngine v2 (PATCHED)
 * PATCH: removed callWithImage (doesn't exist in AIClient),
 *        all tools wrapped in try/catch, structured error returns,
 *        execution_id propagated, NO silent failures
 */
class ToolsEngine {

    /**
     * Universal tool dispatcher
     * Returns: {ok, output, type, trace_id, execution_id} always
     */
    public static function run(string $type, string $input, array $meta = []): array {
        $traceId     = uniqid('tool_', true);
        $executionId = $meta['execution_id'] ?? $traceId;

        if (!$input) {
            return ['ok'=>false,'error'=>'empty_input','type'=>$type,'trace_id'=>$traceId,'execution_id'=>$executionId];
        }

        $allowed = ['document','code','analysis','export_pdf','text'];
        if (!in_array($type, $allowed)) {
            return ['ok'=>false,'error'=>"unknown_tool_type: $type",'allowed'=>$allowed,'trace_id'=>$traceId,'execution_id'=>$executionId];
        }

        try {
            $result = match($type) {
                'document'   => self::generateDocument($input, $meta['sector'] ?? 'general', (int)($meta['user_id']??0)),
                'code'       => self::generateCode($input, $meta['sector'] ?? 'tech'),
                'analysis'   => self::generateAnalysis($input, $meta['sector'] ?? 'business'),
                'export_pdf' => self::exportPDF($input, $meta),
                default      => self::generateText($input, $meta['sector'] ?? 'general'),
            };
            return array_merge(['ok'=>true,'trace_id'=>$traceId,'execution_id'=>$executionId], $result);

        } catch (Throwable $e) {
            error_log("[ToolsEngine::$type] execution_id=$executionId error=" . $e->getMessage());
            return [
                'ok'          => false,
                'error'       => $e->getMessage(),
                'type'        => $type,
                'trace_id'    => $traceId,
                'execution_id'=> $executionId,
                'message'     => 'فشل تنفيذ الأداة — سيتم استرداد رصيدك',
            ];
        }
    }

    /**
     * Generate a document (contract, report) via AI — wrapped in UsageMeter
     */
    public static function generateDocument(string $query, string $sector, int $userId = 0, string $docType = 'contract'): array {
        require_once __DIR__ . '/AIClient.php';
        require_once __DIR__ . '/UsageMeter.php';

        $systemPrompt = "أنت متخصص في إعداد المستندات الاحترافية لقطاع $sector. أعد مستنداً منظماً ومفصلاً.";

        // Wrap in UsageMeter: pre-check budget, execute, post-charge
        $metered = UsageMeter::wrap($userId, 'document', $docType,
            fn() => AIClient::call($query, $systemPrompt, ['max_tokens' => 2000])
        );

        if (!$metered['ok']) {
            // Insufficient funds / limit exceeded
            return ['error' => $metered['error'], 'detail' => $metered['detail'] ?? null,
                    'type' => 'document_blocked'];
        }

        $result  = $metered['result'];
        $content = $result['content'] ?? $result['text'] ?? '';
        if (!$content) throw new RuntimeException('AI returned empty document');

        // Save to disk (with size limit: 100KB)
        if (strlen($content) > 102400) $content = mb_substr($content, 0, 102400);
        $uploadDir = __DIR__ . '/../uploads/documents/';
        if (!is_dir($uploadDir)) @mkdir($uploadDir, 0755, true);

        $filename = 'doc_' . time() . '_' . substr($sector, 0, 4) . '.txt';
        $saved    = (bool)file_put_contents($uploadDir . $filename, $content);
        $fileUrl  = $saved ? (defined('SITE_URL') ? SITE_URL . '/uploads/documents/' . $filename : null) : null;

        return [
            'output'       => $content,
            'type'         => 'document',
            'filename'     => $filename,
            'file_url'     => $fileUrl,
            'sector'       => $sector,
            'doc_type'     => $docType,
            'word_count'   => str_word_count($content),
            'charged_sdg'  => $metered['charged_sdg'],
            'wallet_after' => $metered['wallet_after'],
            'tokens_used'  => $metered['tokens_in'] + $metered['tokens_out'],
        ];
    }

    /**
     * Generate code via AI
     */
    public static function generateCode(string $query, string $sector = 'tech', int $userId = 0): array {
        require_once __DIR__ . '/AIClient.php';
        require_once __DIR__ . '/UsageMeter.php';

        $sys  = "You are an expert developer. Write clean, well-commented code only. No explanations unless requested.";

        if ($userId > 0) {
            $metered = UsageMeter::wrap($userId, 'document', 'code',
                fn() => AIClient::call("Code for: $query", $sys, ['max_tokens' => 2000])
            );
            if (!$metered['ok']) {
                return ['error' => $metered['error'], 'detail' => $metered['detail'] ?? null,
                        'type' => 'code_blocked'];
            }
            $res = $metered['result'];
        } else {
            $res = AIClient::call("Code for: $query", $sys, ['max_tokens' => 2000]);
        }
        $code = $res['content'] ?? $res['text'] ?? '';

        if (!$code) throw new RuntimeException('AI returned empty code');

        // Detect language
        $lang = 'code';
        foreach (['php','python','javascript','html','css','sql','bash'] as $l) {
            if (stripos($query, $l) !== false) { $lang = $l; break; }
        }

        return ['output'=>$code,'type'=>'code','language'=>$lang,'lines'=>substr_count($code,"\n")];
    }

    /**
     * Generate analysis report
     */
    public static function generateAnalysis(string $query, string $sector = 'business', int $userId = 0): array {
        require_once __DIR__ . '/AIClient.php';
        require_once __DIR__ . '/UsageMeter.php';

        $sys    = "أنت خبير تحليل في قطاع $sector. قدّم تحليلاً مهنياً مع توصيات قابلة للتنفيذ.";

        if ($userId > 0) {
            $metered = UsageMeter::wrap($userId, 'document', 'analysis',
                fn() => AIClient::call($query, $sys, ['max_tokens' => 1500])
            );
            if (!$metered['ok']) {
                return ['error' => $metered['error'], 'detail' => $metered['detail'] ?? null,
                        'type' => 'analysis_blocked'];
            }
            $result = $metered['result'];
        } else {
            $result = AIClient::call($query, $sys, ['max_tokens' => 1500]);
        }
        $output = $result['content'] ?? $result['text'] ?? '';

        if (!$output) throw new RuntimeException('AI returned empty analysis');

        return ['output'=>$output,'type'=>'analysis','sector'=>$sector];
    }

    /**
     * Export to printable HTML (no external PDF library needed)
     */
    public static function exportPDF(string $content, array $meta = []): array {
        $title   = htmlspecialchars($meta['title'] ?? 'وثيقة سودانا');
        $date    = date('d/m/Y H:i');
        $html    = "<!DOCTYPE html><html dir='rtl' lang='ar'><head><meta charset='utf-8'>
<style>body{font-family:serif;padding:40px;direction:rtl;max-width:800px;margin:0 auto}
h1{color:#073328}.footer{margin-top:40px;font-size:11px;color:#999;border-top:1px solid #eee;padding-top:10px}
</style></head><body><h1>$title</h1><p style='font-size:11px;color:#666;margin-bottom:20px'>$date</p><hr>
" . nl2br(htmlspecialchars($content)) . "
<div class='footer'>سودانا للخدمات الذكية — finance@sudanna.ai</div></body></html>";

        // Limit size: 500KB
        if (strlen($html) > 512000) throw new RuntimeException('export_too_large');

        $uploadDir = __DIR__ . '/../uploads/exports/';
        if (!is_dir($uploadDir)) @mkdir($uploadDir, 0755, true);

        $filename = 'export_' . time() . '.html';
        if (!file_put_contents($uploadDir . $filename, $html)) {
            throw new RuntimeException('export_write_failed');
        }

        $url = defined('SITE_URL') ? SITE_URL . '/uploads/exports/' . $filename : null;
        return ['output'=>$content,'type'=>'pdf_html','file_url'=>$url,'filename'=>$filename];
    }

    /**
     * Plain text generation (fallback)
     */
    private static function generateText(string $query, string $sector, int $userId = 0): array {
        require_once __DIR__ . '/AIClient.php';
        require_once __DIR__ . '/UsageMeter.php';

        if ($userId > 0) {
            $metered = UsageMeter::wrap($userId, 'chat', $sector,
                fn() => AIClient::call($query, "أنت مساعد سودانا المتخصص في $sector.", ['max_tokens' => 1000]),
                ['skip_debit' => true]
            );
            $result = $metered['ok'] ? $metered['result'] : ['content' => ''];
        } else {
            $result = AIClient::call($query, "أنت مساعد سودانا المتخصص في $sector.", ['max_tokens' => 1000]);
        }
        $output = $result['content'] ?? $result['text'] ?? '';
        if (!$output) throw new RuntimeException('AI returned empty response');
        return ['output' => $output, 'type' => 'text'];
    }
}
