<?php
declare(strict_types=1);

/**
 * /elms/includes/gemini_ai.php
 * Gemini Free API helper for EDEN CAMPUS ELMS
 */

/*
Temporary only if server env variable is not working:
putenv('GEMINI_API_KEY=your_gemini_api_key_here');
*/

function gemini_api_key(): string
{
    return trim((string)getenv('GEMINI_API_KEY'));
}

function gemini_model(): string
{
    /*
      Good free-tier first model:
      - gemini-2.5-flash
      If your key/model access gives error, change to:
      - gemini-2.0-flash
      - gemini-1.5-flash
    */
    return 'gemini-2.5-flash';
}

function gemini_system_prompt(string $mode, string $role = 'student', string $name = 'Student'): string
{
    $base = "You are EDEN CAMPUS ELMS AI Assistant. "
        . "Help students clearly and safely. "
        . "Use simple English. Add brief Sinhala explanation only when useful. "
        . "Do not help with cheating, plagiarism, bypassing assessments, or writing dishonest final submissions. "
        . "For graded assignments, guide using explanation, outline, checklist, grammar improvement, and marking criteria. "
        . "User role: {$role}. User name: {$name}.";

    return match ($mode) {
        'chat' => $base . " Chat mode: answer study questions clearly with examples.",
        'assignment' => $base . " Assignment Help mode: explain the assignment question, give an answer outline, improve grammar, explain marking criteria, and provide a checklist. Do not write a complete dishonest submission.",
        'pdf' => $base . " PDF Explain mode: explain the provided PDF or lesson content, summarize sections, define key terms, and create revision notes.",
        'tutor' => $base . " AI Tutor mode: teach step by step according to the student's level. Give simple examples and end with one short practice question.",
        'summarize' => $base . " Lecture Summary mode: summarize lecture content into key points, definitions, examples, revision notes, and possible exam questions.",
        'mcq_admin' => $base . " MCQ Generator mode for admin/lecturer only. Generate valid MCQs with four options, correct answer, and explanation.",
        default => $base,
    };
}

function gemini_extract_text(array $data): string
{
    $answer = '';

    if (!empty($data['candidates']) && is_array($data['candidates'])) {
        foreach ($data['candidates'] as $candidate) {
            $parts = $candidate['content']['parts'] ?? [];
            if (is_array($parts)) {
                foreach ($parts as $part) {
                    if (isset($part['text'])) {
                        $answer .= (string)$part['text'] . "\n";
                    }
                }
            }
        }
    }

    return trim($answer);
}

function gemini_generate_text(
    string $mode,
    string $message,
    string $role = 'student',
    string $name = 'Student',
    int $maxTokens = 1800
): array {
    $apiKey = gemini_api_key();

    if ($apiKey === '') {
        return [
            'ok' => false,
            'message' => 'Gemini API key is not configured on server.'
        ];
    }

    $system = gemini_system_prompt($mode, $role, $name);

    $payload = [
        'system_instruction' => [
            'parts' => [
                ['text' => $system]
            ]
        ],
        'contents' => [
            [
                'role' => 'user',
                'parts' => [
                    ['text' => $message]
                ]
            ]
        ],
        'generationConfig' => [
            'temperature' => 0.45,
            'topP' => 0.9,
            'maxOutputTokens' => $maxTokens,
        ],
    ];

    $url = 'https://generativelanguage.googleapis.com/v1beta/models/' . rawurlencode(gemini_model()) . ':generateContent';

    $ch = curl_init($url);

    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'x-goog-api-key: ' . $apiKey,
        ],
        CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
        CURLOPT_TIMEOUT => 90,
    ]);

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

    if ($response === false || $error !== '') {
        return [
            'ok' => false,
            'message' => 'Gemini connection failed: ' . $error
        ];
    }

    $data = json_decode($response, true);

    if ($httpCode < 200 || $httpCode >= 300) {
        return [
            'ok' => false,
            'message' => $data['error']['message'] ?? 'Gemini API request failed.'
        ];
    }

    $answer = gemini_extract_text($data);

    if ($answer === '') {
        $blockReason = $data['promptFeedback']['blockReason'] ?? '';
        if ($blockReason !== '') {
            $answer = 'Gemini blocked this request: ' . $blockReason;
        } else {
            $answer = 'Gemini returned an empty response. Please try again.';
        }
    }

    return [
        'ok' => true,
        'answer' => $answer,
        'usage' => $data['usageMetadata'] ?? [],
        'raw' => $data,
    ];
}

function gemini_generate_pdf_explain(
    string $pdfPath,
    string $question = '',
    string $role = 'student',
    string $name = 'Student'
): array {
    $apiKey = gemini_api_key();

    if ($apiKey === '') {
        return [
            'ok' => false,
            'message' => 'Gemini API key is not configured on server.'
        ];
    }

    if (!is_file($pdfPath)) {
        return [
            'ok' => false,
            'message' => 'PDF file not found.'
        ];
    }

    $size = filesize($pdfPath);
    if ($size === false || $size <= 0) {
        return [
            'ok' => false,
            'message' => 'Invalid PDF file.'
        ];
    }

    /*
      Keep smaller than official inline limit for safety.
      Gemini docs mention PDF inline processing; use small PDFs first.
    */
    if ($size > 20 * 1024 * 1024) {
        return [
            'ok' => false,
            'message' => 'PDF is too large. Please use a PDF under 20MB for this LMS assistant.'
        ];
    }

    $pdfBytes = file_get_contents($pdfPath);

    if ($pdfBytes === false) {
        return [
            'ok' => false,
            'message' => 'Unable to read PDF file.'
        ];
    }

    $prompt = trim($question);
    if ($prompt === '') {
        $prompt = 'Explain this PDF for a student. Include: short summary, key points, important definitions, examples, revision notes, and 5 possible exam questions.';
    }

    $payload = [
        'system_instruction' => [
            'parts' => [
                ['text' => gemini_system_prompt('pdf', $role, $name)]
            ]
        ],
        'contents' => [
            [
                'role' => 'user',
                'parts' => [
                    [
                        'inline_data' => [
                            'mime_type' => 'application/pdf',
                            'data' => base64_encode($pdfBytes),
                        ]
                    ],
                    [
                        'text' => $prompt
                    ]
                ]
            ]
        ],
        'generationConfig' => [
            'temperature' => 0.35,
            'topP' => 0.9,
            'maxOutputTokens' => 2400,
        ],
    ];

    $url = 'https://generativelanguage.googleapis.com/v1beta/models/' . rawurlencode(gemini_model()) . ':generateContent';

    $ch = curl_init($url);

    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'x-goog-api-key: ' . $apiKey,
        ],
        CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
        CURLOPT_TIMEOUT => 120,
    ]);

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

    if ($response === false || $error !== '') {
        return [
            'ok' => false,
            'message' => 'Gemini PDF request failed: ' . $error
        ];
    }

    $data = json_decode($response, true);

    if ($httpCode < 200 || $httpCode >= 300) {
        return [
            'ok' => false,
            'message' => $data['error']['message'] ?? 'Gemini PDF request failed.'
        ];
    }

    $answer = gemini_extract_text($data);

    return [
        'ok' => true,
        'answer' => $answer !== '' ? $answer : 'Gemini returned an empty PDF explanation.',
        'usage' => $data['usageMetadata'] ?? [],
        'raw' => $data,
    ];
}