<?php
ini_set('display_errors', 0);
// File: admin/ai_process.php

// 1. TAHAN OUTPUT (Fix Loading)
ob_start(); 

// 2. SETTING SERVER (Upaya Meningkatkan Limit)
// Note: Ini mungkin tidak ngefek di beberapa shared hosting, tapi layak dicoba.
@ini_set('upload_max_filesize', '100M');
@ini_set('post_max_size', '100M');
@ini_set('max_execution_time', 600); // 10 Menit
@set_time_limit(600);
@ini_set('memory_limit', '512M'); 
@ini_set('display_errors', 0); 
error_reporting(E_ALL);

require_once '../includes/security.php';
secureSessionStart();
if (!isset($_SESSION['admin_id']) || !validateAdminSession()) {
    ob_end_clean();
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'message' => 'Sesi habis, silakan login ulang.']);
    exit;
}
require_once '../includes/db_connect.php'; 

// Fungsi kirim JSON bersih
function sendJson($data) {
    ob_end_clean(); 
    header('Content-Type: application/json');
    echo json_encode($data);
    exit;
}

// 3. AUTO CLEANER
$tempFolderClean = '../uploads/ai_temp/';
if (is_dir($tempFolderClean)) {
    $files = glob($tempFolderClean . '*'); 
    $now = time();
    foreach ($files as $file) {
        if (is_file($file)) {
            if ($now - filemtime($file) >= 3600) { 
                @unlink($file);
            }
        }
    }
}

// 4. Validasi Request (DETEKSI FILE KEGEDEAN)
// Jika $_FILES dan $_POST kosong tapi ada konten, berarti post_max_size terlampaui.
if (empty($_FILES) && empty($_POST) && isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 0) {
    $maxSize = ini_get('post_max_size');
    sendJson([
        'success' => false, 
        'message' => "Gagal Upload: Video terlalu besar! Melebihi batas server ($maxSize). Coba kompres video dulu di bawah $maxSize."
    ]);
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    sendJson(['success' => false, 'message' => 'Invalid Request']);
}

// 5. Ambil API Key
try {
    if (isset($pdo)) {
        $stmt = $pdo->query("SELECT gemini_api_key FROM config_cabang LIMIT 1");
        $apiKey = $stmt->fetchColumn();
    }
} catch (Exception $e) {
    sendJson(['success' => false, 'message' => 'Gagal koneksi database']);
}

$apiKey = trim($apiKey);
if (empty($apiKey)) {
    sendJson(['success' => false, 'message' => 'API Key kosong.']);
}

$mode = $_POST['mode'] ?? 'artikel';
// AUDIT FIX: Sanitasi context untuk cegah prompt injection
$context = substr(strip_tags(trim($_POST['context'] ?? '')), 0, 500);
$modelId = $_POST['model_id'] ?? 'gemini-2.5-flash';

// WHITELIST MODEL GRATISAN (FLASH & PREVIEW ONLY)
$allowedModels = [
    'gemini-2.5-flash',
    'gemini-2.5-flash-lite',
    'gemini-3.0-flash-preview',
    'gemini-2.0-flash'
];

if (!in_array($modelId, $allowedModels)) {
    $modelId = 'gemini-2.5-flash';
}

// 6. Upload File (DETEKSI ERROR DETAIL)
if (!isset($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) {
    $err = isset($_FILES['image']['error']) ? $_FILES['image']['error'] : 'Unknown';
    $msg = "Gagal Upload (Code $err). ";
    
    switch ($err) {
        case UPLOAD_ERR_INI_SIZE:
            $msg .= "File melebihi upload_max_filesize di server.";
            break;
        case UPLOAD_ERR_FORM_SIZE:
            $msg .= "File melebihi batas form.";
            break;
        case UPLOAD_ERR_PARTIAL:
            $msg .= "Upload terputus/tidak lengkap.";
            break;
        case UPLOAD_ERR_NO_FILE:
            $msg .= "File tidak ditemukan.";
            break;
        default:
            $msg .= "Cek koneksi atau ukuran file.";
    }
    
    sendJson(['success' => false, 'message' => $msg]);
}

$uploadDir = '../uploads/ai_temp/';
if (!file_exists($uploadDir)) mkdir($uploadDir, 0755, true);

// AUDIT FIX: Validasi MIME pada tmp_name SEBELUM move (bukan sesudah)
$mimeType  = mime_content_type($_FILES['image']['tmp_name']);
$allowedMimeTypes = ['image/jpeg','image/png','image/webp','image/gif','video/mp4','video/webm'];
if (!in_array($mimeType, $allowedMimeTypes)) {
    sendJson(['success' => false, 'message' => 'Tipe file tidak diizinkan: ' . $mimeType]);
}

// AUDIT FIX: Tentukan ekstensi dari MIME type, bukan nama file asli (cegah ekstensi palsu)
$mimeToExt = ['image/jpeg'=>'jpg','image/png'=>'png','image/webp'=>'webp','image/gif'=>'gif','video/mp4'=>'mp4','video/webm'=>'webm'];
$originalExt = $mimeToExt[$mimeType] ?? 'jpg';
$fileName = 'ai_' . time() . '_' . bin2hex(random_bytes(4)) . '.' . $originalExt;
$targetPath = $uploadDir . $fileName;

if (!move_uploaded_file($_FILES['image']['tmp_name'], $targetPath)) {
    sendJson(['success' => false, 'message' => 'Gagal simpan file temp.']);
}
$isVideo = strpos($mimeType, 'video') !== false;
$tipePromo = $isVideo ? 'video' : 'image';

// 7. Optimisasi Gambar
$payloadPath = $targetPath;
$isCompressed = false;

if (!$isVideo && extension_loaded('gd')) {
    try {
        $compressedPath = $uploadDir . 'ai_small_' . time() . '.jpg';
        if (compressImageForAI($targetPath, $compressedPath)) {
            $payloadPath = $compressedPath;
            $isCompressed = true;
            $mimeType = 'image/jpeg';
        }
    } catch (Exception $e) { }
}

// 8. Siapkan Payload AI
if ($isVideo) {
    // VIDEO: Jangan kirim file video ke AI (berat), kirim prompt teks aja
    $promptPrefix = "Buat konten VIDEO PROMO kreatif. ";
    $base64Data = ""; 
} else {
    $promptPrefix = "Analisis gambar ini. ";
    $fileData = file_get_contents($payloadPath);
    $base64Data = base64_encode($fileData);
}

if ($isCompressed && file_exists($compressedPath)) {
    @unlink($compressedPath);
}

// 9. Prompt Engineering
$role = "Anda adalah Copywriter Profesional yang sangat berpengalaman membuat artikel blog dan artikel promosi yang viral. Gaya bahasa: Profesional, Persuasif, Natural Indonesia.";

if ($mode == 'artikel') {
    $prompt = "Lihat gambar ini. Buat ARTIKEL BLOG SEO.
    Konteks: '$context'
    Output JSON:
    { 
        \"judul\": \"Judul Menarik dan membuat penasaran\", 
        \"meta\": \"Meta description max 150 char\", 
        \"konten\": \"Artikel min 350 kata HTML (<p>,<ul>,<li>,<b>). Hook visual, fitur, soft selling, CTA jangan menulis nomor telepon dan menyebut nama sales atau orang tapi arahkan untuk mengklik tombol whatsapp.\" 
    }";
} else {
    $prompt = "Anda adalah Copywriter Profesional yang sangat berpengalaman membuat artikel blog dan artikel promosi yang viral. Gaya bahasa: Profesional, Persuasif, Natural Indonesia. Lihat media ini. Buat KONTEN PROMO.
    Konteks: '$context'
    Output JSON:
    { 
        \"judul\": \"Headline Hard Selling menarik dan membuat penasaran\", 
        \"meta\": \"Caption Pendek\", 
        \"konten\": \"Deskripsi Lengkap HTML (<p>,<br>). Urgensi & Hashtag. Hook visual, fitur, Hard selling, CTA jangan menulis nomor telepon dan menyebut nama sales atau orang tapi arahkan untuk mengklik tombol whatsapp.\" 
    }";
}

// 10. Eksekusi API
$model = $modelId;
$baseUrl = "https://generativelanguage.googleapis.com/v1beta/models/";
$url = $baseUrl . $model . ":generateContent?key=" . $apiKey;

$parts = [["text" => $prompt]];
if (!$isVideo && !empty($base64Data)) {
    $parts[] = ["inline_data" => ["mime_type" => $mimeType, "data" => $base64Data]];
}

$payload = [
    "system_instruction" => ["parts" => [["text" => $role]]],
    "contents" => [["parts" => $parts]],
    "generation_config" => ["response_mime_type" => "application/json"]
];

if (!function_exists('curl_init')) {
    sendJson(['success' => false, 'message' => 'Ekstensi cURL tidak tersedia di server ini. Hubungi hosting untuk mengaktifkan cURL.']);
}

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);

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

if ($response === false) {
    sendJson(['success' => false, 'message' => "Koneksi Gagal: " . $curlError]);
}

if ($httpCode !== 200) {
    sendJson(['success' => false, 'message' => "Error API ($httpCode): " . $response]);
}

// 11. Parsing
$decoded = json_decode($response, true);
$aiRawText = $decoded['candidates'][0]['content']['parts'][0]['text'] ?? '';
$parsedData = json_decode($aiRawText, true);

if (!$parsedData) {
    $parsedData = ['judul' => 'Draft (Perlu Edit)', 'meta' => '', 'konten' => $aiRawText];
}

$judul = $parsedData['judul'] ?? 'Draft AI';
$meta = $parsedData['meta'] ?? '';
$konten = $parsedData['konten'] ?? $aiRawText;

// 12. Save Database & Redirect
if ($mode == 'artikel') {
    $targetDir = '../uploads/artikel/';
    if (!file_exists($targetDir)) mkdir($targetDir, 0755, true);
    
    $newFileName = 'art_' . time() . '.' . $originalExt;
    $finalPath = $targetDir . $newFileName;
    $dbPath = 'uploads/artikel/' . $newFileName;
    
    rename($targetPath, $finalPath);

    try {
        if (isset($pdo)) {
            $sql = "INSERT INTO artikel (judul, meta_description, konten, status, gambar_cover_url, tanggal_buat) VALUES (:judul, :meta, :konten, 'published', :gambar, CURDATE())";
            $stmt = $pdo->prepare($sql);
            $stmt->execute([':judul' => $judul, ':meta' => $meta, ':konten' => $konten, ':gambar' => $dbPath]);
        }
        $redirectUrl = 'crud_artikel.php';
    } catch (Exception $e) { /* Ignore */ }

} else {
    $targetDir = '../uploads/promo/';
    if (!file_exists($targetDir)) mkdir($targetDir, 0755, true);
    
    $newFileName = 'prm_' . time() . '.' . $originalExt;
    $finalPath = $targetDir . $newFileName;
    $dbPath = 'uploads/promo/' . $newFileName;
    
    rename($targetPath, $finalPath);
    $expiredDate = date('Y-m-d', strtotime('+1 month'));

    try {
        if (isset($pdo)) {
            $sql = "INSERT INTO promo (judul, meta_description, deskripsi, gambar_url, tipe, tanggal_berakhir, is_featured) VALUES (:judul, :meta, :konten, :gambar, :tipe, :expired, 1)";
            $stmt = $pdo->prepare($sql);
            $stmt->execute([':judul' => $judul, ':meta' => $meta, ':konten' => $konten, ':gambar' => $dbPath, ':tipe' => $tipePromo, ':expired' => $expiredDate]);
        }
        $redirectUrl = 'crud_promo.php';
    } catch (Exception $e) { /* Ignore */ }
}

sendJson(['success' => true, 'redirect' => $redirectUrl]);

// Helper Kompresi
function compressImageForAI($source, $destination) {
    $info = getimagesize($source);
    if (!$info) return false;
    switch ($info['mime']) {
        case 'image/jpeg': $image = imagecreatefromjpeg($source); break;
        case 'image/png': $image = imagecreatefrompng($source); break;
        case 'image/webp': $image = imagecreatefromwebp($source); break;
        default: return false;
    }
    $maxWidth = 1024;
    $width = imagesx($image);
    $height = imagesy($image);
    if ($width > $maxWidth) {
        $newWidth = $maxWidth;
        $newHeight = floor($height * ($maxWidth / $width));
        $tmp = imagecreatetruecolor($newWidth, $newHeight);
        if ($info['mime'] == 'image/png' || $info['mime'] == 'image/webp') {
            imagecolortransparent($tmp, imagecolorallocatealpha($tmp, 0, 0, 0, 127));
            imagealphablending($tmp, false);
            imagesavealpha($tmp, true);
        }
        imagecopyresampled($tmp, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
        imagedestroy($image);
        $image = $tmp;
    }
    imagejpeg($image, $destination, 60);
    imagedestroy($image);
    return true;
}
?>