<?php
/**
 * chat.php - AI Backend untuk Clyde 37-DE · RCI-1550
 * Menggunakan Groq API (Llama 3.3)
 */

// ============================================================
// 1. CORS HEADERS
// ============================================================
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

// ============================================================
// 2. GROQ API CONFIGURATION
// ============================================================
$GROQ_API_KEY = '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';

// ✅ MODEL TERBARU YANG DIDUKUNG GROQ (Feb 2026)
// Jangan pakai llama-3.1-70b-versatile lagi — sudah decommissioned!
$GROQ_MODEL = 'llama-3.3-70b-versatile';
// Alternatif: 'llama-3.1-8b-instant' (lebih cepat)
// Alternatif: 'mixtral-8x7b-32768' (konteks besar)

// ============================================================
// 3. SYSTEM PROMPT - RCI-1550 + Clyde 37-DE
// ============================================================
$SYSTEM_PROMPT_ID = "Anda adalah AI Technician spesialis Crane Safety Systems dengan keahlian mendalam pada:
- Robway RCI-1550 Rated Capacity Indicator / Load Moment Indicator
- Crane Clyde Iron Works 37-DE (SWL 250 Ton, Cat D-3406/D-346)
- Tensiometer / Line-rider based systems
- Load cell calibration (main & aux winch)
- Boom angle & length sensor calibration
- Anti-Two-Block (ATB) system
- Motion cut & override systems
- CPU Box Robway troubleshooting
- Data logging & download

PROSEDUR KALIBRASI LOAD CELL RCI-1550:
1. Pastikan duty, winch, dan falls benar sebelum kalibrasi.
2. F-02 CAL MAIN LOW: Angkat hook block (light load), masukkan berat aktual.
3. F-03 CAL MAIN HIGH: Angkat test weight >75% line-pull, masukkan berat aktual.
4. F-05/F-06 untuk Aux winch.
5. Verifikasi dengan F-01 VIEW MAIN LOAD.
6. Load/Angle Correction: F-74 (Low Angle), F-75 (High Angle), F-76 (Correction Factor).
7. Selalu lakukan F-44 BACKUP CAL-TABLE setelah kalibrasi.

TROUBLESHOOTING CPU BOX RCI-1550 (10 LANGKAH):
1. Cek power supply (10-40V DC, fuse 5A slow blow).
2. Cek LED pada DIO section: input/output status.
3. Verifikasi raw signal sensor (F-14, F-18) antara 33-999.
4. Cek koneksi RS-485 antara Display dan Control Unit.
5. Cek SIMM card (load chart & calibration) terpasang benar.
6. Cek battery backup SRAM (garansi 10 tahun).
7. Jika EPROM U5 ada, pastikan tidak ada EPROM di U8.
8. Gunakan disable key switch untuk hardware bypass.
9. Reset power 30 detik lalu nyalakan kembali.
10. Hubungi Robway Support jika gagal: +61 8 8352 6055.

ERROR CODES RCI-1550:
101-108: Angle sensor open/short circuit
201-208: Load sensor open/short circuit
220: ATB / Two-blocking
240: Overload (100% SWL exceeded)
280: Line-pull exceeded
301: Angle out of allowed range
304: Radius out of allowed range
308: Height out of allowed range
310: Slew out of allowed range

CRANE CLYDE 37-DE:
- SWL Main: 250 Ton (revolving)
- SWL Aux: 30 Ton
- Max reach/height: 64m
- Serial: CW-3936
- Engine: Cat D-3406 (boom), Cat D-346 (hoist), Cat D-343 (swing)

JAWAB dalam bahasa yang SAMA dengan bahasa pertanyaan. Jika pertanyaan dalam Bahasa Indonesia, jawab dalam Bahasa Indonesia. Jika pertanyaan dalam Bahasa Inggris, jawab dalam Bahasa Inggris. Gunakan bullet points untuk langkah-langkah.";

$SYSTEM_PROMPT_EN = "You are an AI Technician specializing in Crane Safety Systems with deep expertise in:
- Robway RCI-1550 Rated Capacity Indicator / Load Moment Indicator
- Crane Clyde Iron Works 37-DE (SWL 250 Ton, Cat D-3406/D-346)
- Tensiometer / Line-rider based systems
- Load cell calibration (main & aux winch)
- Boom angle & length sensor calibration
- Anti-Two-Block (ATB) system
- Motion cut & override systems
- CPU Box Robway troubleshooting
- Data logging & download

RCI-1550 LOAD CELL CALIBRATION PROCEDURE:
1. Ensure duty, winch, and falls are correct before calibration.
2. F-02 CAL MAIN LOW: Lift hook block (light load), enter actual weight.
3. F-03 CAL MAIN HIGH: Lift test weight >75% line-pull, enter actual weight.
4. F-05/F-06 for Aux winch.
5. Verify with F-01 VIEW MAIN LOAD.
6. Load/Angle Correction: F-74 (Low Angle), F-75 (High Angle), F-76 (Correction Factor).
7. Always do F-44 BACKUP CAL-TABLE after calibration.

CPU BOX RCI-1550 TROUBLESHOOTING (10 STEPS):
1. Check power supply (10-40V DC, fuse 5A slow blow).
2. Check LED on DIO section: input/output status.
3. Verify raw signal sensor (F-14, F-18) between 33-999.
4. Check RS-485 connection between Display and Control Unit.
5. Check SIMM card (load chart & calibration) installed correctly.
6. Check battery backup SRAM (10 year warranty).
7. If EPROM U5 present, ensure no EPROM in U8.
8. Use disable key switch for hardware bypass.
9. Power cycle 30 seconds then restart.
10. Contact Robway Support: +61 8 8352 6055.

RCI-1550 ERROR CODES:
101-108: Angle sensor open/short circuit
201-208: Load sensor open/short circuit
220: ATB / Two-blocking
240: Overload (100% SWL exceeded)
280: Line-pull exceeded
301: Angle out of allowed range
304: Radius out of allowed range
308: Height out of allowed range
310: Slew out of allowed range

CRANE CLYDE 37-DE SPECS:
- SWL Main: 250 Ton (revolving)
- SWL Aux: 30 Ton
- Max reach/height: 64m
- Serial: CW-3936
- Engines: Cat D-3406 (boom), Cat D-346 (hoist), Cat D-343 (swing)

ANSWER in the SAME LANGUAGE as the question. If question is in English, answer in English. If question is in Indonesian, answer in Indonesian. Use bullet points for steps.";

// ============================================================
// 4. DETEKSI BAHASA
// ============================================================
function detectLanguage($text) {
    $idPatterns = ['kalibrasi', 'cara', 'bagaimana', 'apa', 'yang', 'di', 'ke', 'dari', 'untuk', 'dengan', 'pada', 'saya', 'anda', 'bisa', 'apakah'];
    $enPatterns = ['how', 'what', 'is', 'are', 'the', 'to', 'for', 'with', 'from', 'calibrate', 'troubleshoot', 'step', 'does', 'do', 'can'];
    
    $lower = strtolower($text);
    $idScore = 0;
    $enScore = 0;
    
    foreach ($idPatterns as $p) {
        if (strpos($lower, $p) !== false) $idScore++;
    }
    foreach ($enPatterns as $p) {
        if (strpos($lower, $p) !== false) $enScore++;
    }
    
    return ($idScore > $enScore) ? 'id' : 'en';
}

// ============================================================
// 5. PROCESS REQUEST
// ============================================================
$input = json_decode(file_get_contents('php://input'), true);

if (!$input) {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid request: No JSON input']);
    exit();
}

$messages = $input['messages'] ?? [];
$system = $input['system'] ?? null;
$max_tokens = $input['max_tokens'] ?? 1024;
$temperature = $input['temperature'] ?? 0.3;

// 🔧 PRIORITAS: Gunakan system dari frontend jika ada
if (!empty($system)) {
    $finalSystem = $system;
} else {
    // Fallback: deteksi bahasa dari pesan terakhir
    $lastMessage = '';
    if (!empty($messages)) {
        $last = end($messages);
        if ($last && isset($last['content'])) {
            $lastMessage = $last['content'];
        }
    }
    $lang = detectLanguage($lastMessage);
    $finalSystem = ($lang === 'id') ? $SYSTEM_PROMPT_ID : $SYSTEM_PROMPT_EN;
}

$history = array_slice($messages, -10);

// ============================================================
// 6. CALL GROQ API
// ============================================================
$payload = [
    'model' => $GROQ_MODEL,
    'messages' => array_merge(
        [['role' => 'system', 'content' => $finalSystem]],
        $history
    ),
    'max_tokens' => $max_tokens,
    'temperature' => $temperature
];

$ch = curl_init('https://api.groq.com/openai/v1/chat/completions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Authorization: Bearer ' . $GROQ_API_KEY
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_TIMEOUT, 30);

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

// ============================================================
// 7. RESPONSE
// ============================================================
if ($curlError) {
    http_response_code(500);
    echo json_encode([
        'error' => 'Curl error: ' . $curlError,
        'fallback' => true
    ]);
    exit();
}

if ($httpCode !== 200) {
    $errorData = json_decode($response, true);
    $errorMsg = $errorData['error']['message'] ?? 'Unknown API error';
    
    // Jika model decommissioned, coba fallback ke model lain
    if (strpos($errorMsg, 'decommissioned') !== false) {
        $fallbackModels = ['llama-3.3-70b-versatile', 'llama-3.1-8b-instant', 'mixtral-8x7b-32768'];
        foreach ($fallbackModels as $model) {
            if ($model === $GROQ_MODEL) continue;
            
            $payload['model'] = $model;
            $ch2 = curl_init('https://api.groq.com/openai/v1/chat/completions');
            curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch2, CURLOPT_POST, true);
            curl_setopt($ch2, CURLOPT_HTTPHEADER, [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $GROQ_API_KEY
            ]);
            curl_setopt($ch2, CURLOPT_POSTFIELDS, json_encode($payload));
            curl_setopt($ch2, CURLOPT_TIMEOUT, 30);
            $response2 = curl_exec($ch2);
            $httpCode2 = curl_getinfo($ch2, CURLINFO_HTTP_CODE);
            curl_close($ch2);
            
            if ($httpCode2 === 200) {
                http_response_code(200);
                echo $response2;
                exit();
            }
        }
    }
    
    http_response_code($httpCode);
    echo json_encode([
        'error' => $errorMsg,
        'http_code' => $httpCode,
        'fallback' => true
    ]);
    exit();
}

http_response_code(200);
echo $response;
?>