<?php
/**
 * Generate API Endpoint (Polling Architecture)
 * POST: Create generation job, return jobId immediately
 * GET with ?jobId=xxx: Return job status (process if pending)
 * GET without jobId: Return available sizes
 */

require_once __DIR__ . '/../includes/ZaiApi.php';

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

$baseDir = dirname(__DIR__);
$jobsDir = $baseDir . '/data/jobs';
if (!is_dir($jobsDir)) {
    mkdir($jobsDir, 0755, true);
}

/* ─── Constants ─── */
$SUPPORTED_SIZES = [
    ['id' => 'square',    'label' => 'مربع (1:1)',    'value' => '1024x1024'],
    ['id' => 'portrait',  'label' => 'عمودي (3:4)',   'value' => '864x1152'],
    ['id' => 'landscape', 'label' => 'أفقي (16:9)',   'value' => '1344x768'],
    ['id' => 'wide',      'label' => 'عريض (2:1)',    'value' => '1440x720'],
];

$PROGRESS_MESSAGES = [
    'جارٍ تحليل الوصف...',
    'يتم تحضير الألوان والأشكال...',
    'الذكاء الاصطناعي يرسم الآن...',
    'جارٍ إضافة التفاصيل...',
    'يتم تحسين الجودة...',
    'أقرب من أي وقت مضى...',
];

/* ─── Helper functions ─── */
function hasArabic(string $text): bool {
    return (bool)preg_match('/[\x{0600}-\x{06FF}]/u', $text);
}

function translateToEnglish(string $arabicPrompt): string {
    try {
        $zai = new ZaiApi();
        $result = $zai->chatCompletion('glm-4-flash', [
            [
                'role' => 'system',
                'content' => 'You are an expert image prompt writer. Translate the following Arabic text into a detailed, high-quality English image generation prompt. Add artistic and quality details. Output ONLY the English prompt, nothing else. Keep under 80 words.',
            ],
            [
                'role' => 'user',
                'content' => $arabicPrompt,
            ],
        ]);
        $translated = $result['choices'][0]['message']['content'] ?? '';
        $translated = trim($translated);
        if ($translated) {
            return $translated;
        }
    } catch (Exception $e) {
        error_log('[GEN] Translation failed: ' . $e->getMessage());
    }
    return $arabicPrompt;
}

function makeSafePrompt(string $originalPrompt): string {
    try {
        $zai = new ZaiApi();
        $result = $zai->chatCompletion('glm-4-flash', [
            [
                'role' => 'system',
                'content' => 'Rewrite the following image generation prompt to be content-filter-safe while preserving the visual intent as much as possible. Use simple, positive, artistic language. Avoid any sensitive, violent, or controversial themes. Output ONLY the rewritten English prompt, nothing else. Keep under 40 words.',
            ],
            [
                'role' => 'user',
                'content' => $originalPrompt,
            ],
        ]);
        $safe = $result['choices'][0]['message']['content'] ?? '';
        $safe = trim($safe);
        if ($safe) {
            return $safe;
        }
    } catch (Exception $e) {
        error_log('[GEN] Safe prompt generation failed: ' . $e->getMessage());
    }
    return '';
}

function isContentFilterError(string $msg): bool {
    return (
        strpos($msg, 'contentFilter') !== false ||
        strpos($msg, '1301') !== false ||
        mb_strpos($msg, '敏感') !== false ||
        mb_strpos($msg, '不安全') !== false
    );
}

function classifyError(string $msg): string {
    if (isContentFilterError($msg)) {
        return 'لم نتمكن من رسم هذه الصورة بسبب قيود أمان. جرّب وصفاً مختلفاً.';
    }
    if (strpos($msg, '400') !== false) {
        return 'وصف غير صالح. جرّب وصفاً أوضح وأبسط.';
    }
    if (strpos($msg, '429') !== false) {
        return 'طلبات كثيرة. انتظر قليلاً ثم حاول.';
    }
    if (strpos($msg, '500') !== false || strpos($msg, '502') !== false || strpos($msg, '503') !== false) {
        return 'خدمة الرسم غير متاحة حالياً. حاول بعد قليل.';
    }
    if (strpos($msg, 'ECONNREFUSED') !== false || strpos($msg, 'cURL error') !== false || strpos($msg, 'network') !== false) {
        return 'خطأ في الاتصال بالخادم. حاول بعد قليل.';
    }
    return mb_strlen($msg) > 120 ? mb_substr($msg, 0, 120) . '...' : $msg;
}

/* ─── Job file operations ─── */
function readJob(string $jobsDir, string $jobId): ?array {
    $path = $jobsDir . '/' . $jobId . '.json';
    if (!file_exists($path)) return null;
    $data = json_decode(file_get_contents($path), true);
    if (!$data) return null;
    return $data;
}

function writeJob(string $jobsDir, array $job): void {
    $path = $jobsDir . '/' . $job['id'] . '.json';
    file_put_contents($path, json_encode($job, JSON_UNESCAPED_UNICODE));
}

/* ─── Cleanup old jobs (>10 minutes) ─── */
$now = time();
foreach (glob($jobsDir . '/*.json') as $jobFile) {
    $mtime = filemtime($jobFile);
    if ($now - $mtime > 10 * 60) {
        @unlink($jobFile);
    }
}

/* ─── Process a pending job (blocking) ─── */
function processJob(string $jobsDir, array &$job): void {
    global $baseDir;
    $job['status'] = 'processing';

    try {
        // Step 1: Translate Arabic to English
        $englishPrompt = trim($job['prompt']);
        if (hasArabic($englishPrompt)) {
            $job['status'] = 'translating';
            $job['message'] = 'جارٍ ترجمة الوصف إلى الإنجليزية...';
            $job['progress'] = 10;
            writeJob($jobsDir, $job);
            $englishPrompt = translateToEnglish($englishPrompt);
        }

        // Step 2: Generate image
        $job['status'] = 'generating';
        $job['progress'] = 20;
        $job['message'] = $GLOBALS['PROGRESS_MESSAGES'][0];
        writeJob($jobsDir, $job);

        $zai = new ZaiApi();
        $response = null;
        $usedPrompt = $englishPrompt;

        // Attempt 1: Original prompt
        try {
            $response = $zai->imageGeneration($usedPrompt, $job['size']);
        } catch (Exception $err1) {
            $errMsg1 = $err1->getMessage();
            error_log('[GEN] Job ' . $job['id'] . ' attempt 1 error: ' . $errMsg1);

            if (!isContentFilterError($errMsg1)) {
                throw $err1;
            }

            // Attempt 2: LLM safe rewrite
            $job['status'] = 'retrying';
            $job['message'] = 'جارٍ تعديل الوصف ليتوافق مع متطلبات الأمان...';
            $job['progress'] = 40;
            writeJob($jobsDir, $job);

            $safePrompt = makeSafePrompt($englishPrompt);
            if ($safePrompt && $safePrompt !== $englishPrompt) {
                $usedPrompt = $safePrompt;
                error_log('[GEN] Job ' . $job['id'] . ' attempt 2 with safe prompt: ' . $safePrompt);
                try {
                    $response = $zai->imageGeneration($usedPrompt, $job['size']);
                } catch (Exception $err2) {
                    $errMsg2 = $err2->getMessage();
                    error_log('[GEN] Job ' . $job['id'] . ' attempt 2 error: ' . $errMsg2);
                    if (!isContentFilterError($errMsg2)) {
                        throw $err2;
                    }
                    $response = null;
                }
            }

            // Attempt 3: Generic fallback
            if (!$response) {
                $usedPrompt = 'A beautiful artistic illustration, vibrant colors, high quality, detailed, professional artwork';
                error_log('[GEN] Job ' . $job['id'] . ' attempt 3 with generic fallback');
                try {
                    $response = $zai->imageGeneration($usedPrompt, $job['size']);
                } catch (Exception $err3) {
                    throw $err3;
                }
            }
        }

        if (!$response || !isset($response['data'][0]['base64'])) {
            throw new RuntimeException('لم يتم الحصول على صورة من الذكاء الاصطناعي');
        }

        $imageBase64 = $response['data'][0]['base64'];
        $imageData = base64_decode($imageBase64);
        error_log('[GEN] Job ' . $job['id'] . ' image received, size: ' . strlen($imageData) . ' bytes');

        // Save image
        $genDir = $baseDir . '/public/generated';
        if (!is_dir($genDir)) {
            mkdir($genDir, 0755, true);
        }

        $filename = 'gen_' . bin2hex(random_bytes(8)) . '.png';
        file_put_contents($genDir . '/' . $filename, $imageData);

        $job['status'] = 'done';
        $job['progress'] = 100;
        $job['message'] = 'تم بنجاح!';
        $job['imageUrl'] = '/generated/' . $filename;
        error_log('[GEN] Job ' . $job['id'] . ' completed: ' . $job['imageUrl']);

    } catch (Exception $error) {
        $errorMsg = classifyError($error->getMessage());
        error_log('[GEN] Job ' . $job['id'] . ' failed: ' . $errorMsg);
        $job['status'] = 'error';
        $job['error'] = $errorMsg;
        $job['message'] = $errorMsg;
    }
}

/* ─── Route handling ─── */
$method = $_SERVER['REQUEST_METHOD'];

if ($method === 'POST') {
    $input = json_decode(file_get_contents('php://input'), true);
    $prompt = trim($input['prompt'] ?? '');
    $sizeId = $input['sizeId'] ?? 'square';

    if (empty($prompt)) {
        http_response_code(400);
        echo json_encode(['error' => 'يرجى كتابة وصف للصورة']);
        exit;
    }

    // Find size
    $sizeValue = '1024x1024';
    foreach ($SUPPORTED_SIZES as $s) {
        if ($s['id'] === $sizeId) {
            $sizeValue = $s['value'];
            break;
        }
    }

    $jobId = bin2hex(random_bytes(12));
    $job = [
        'id'        => $jobId,
        'status'    => 'pending',
        'progress'  => 5,
        'message'   => 'جارٍ البدء...',
        'size'      => $sizeValue,
        'prompt'    => $prompt,
        'createdAt' => time(),
        'imageUrl'  => null,
        'error'     => null,
    ];

    writeJob($jobsDir, $job);

    echo json_encode([
        'jobId'  => $jobId,
        'status' => $job['status'],
        'message' => $job['message'],
    ]);
    exit;
}

if ($method === 'GET') {
    $jobId = $_GET['jobId'] ?? '';

    // Return available sizes if no jobId
    if (empty($jobId)) {
        echo json_encode(['sizes' => $SUPPORTED_SIZES]);
        exit;
    }

    $job = readJob($jobsDir, $jobId);

    if (!$job) {
        http_response_code(404);
        echo json_encode(['error' => 'العملية غير موجودة']);
        exit;
    }

    // If job is pending, process it now (blocking — client polls, so this is fine)
    if ($job['status'] === 'pending') {
        processJob($jobsDir, $job);
        writeJob($jobsDir, $job);
    }

    echo json_encode([
        'jobId'    => $job['id'],
        'status'   => $job['status'],
        'progress' => $job['progress'],
        'message'  => $job['message'],
        'imageUrl' => $job['imageUrl'] ?? null,
        'error'    => $job['error'] ?? null,
    ]);
    exit;
}

http_response_code(405);
echo json_encode(['error' => 'طريقة الطلب غير مدعومة']);