<?php
declare(strict_types=1);

// Prevent direct access from web
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

if (!defined('LUNA_APP')) {
    define('LUNA_APP', true);
}

require_once __DIR__ . '/config.php';
require_once __DIR__ . '/../../config/database.php';

/**
 * Write log to file
 * 
 * @param string $message Log message
 * @param string $level Log level (INFO, SUCCESS, ERROR, DEBUG)
 * @return bool True on success, false on failure
 */
function zalo_log(string $message, string $level = 'INFO'): bool
{
    $logFile = __DIR__ . '/log.txt';
    $timestamp = date('Y-m-d H:i:s');
    $logEntry = "[{$timestamp}] [{$level}] {$message}\n";
    
    // Ensure directory exists
    $dir = dirname($logFile);
    if (!is_dir($dir)) {
        mkdir($dir, 0755, true);
    }
    
    // Write to file
    $result = file_put_contents($logFile, $logEntry, FILE_APPEND | LOCK_EX);
    
    // Also write to PHP error log for critical errors
    if ($level === 'ERROR') {
        error_log("Zalo: {$message}");
    }
    
    return $result !== false;
}

/**
 * Set last error message
 */
function zalo_set_last_error(string $message): void
{
    $_SESSION['zalo_last_error'] = $message;
    zalo_log($message, 'ERROR');
}

/**
 * Get last error message
 */
function zalo_get_last_error(): string
{
    return (string)($_SESSION['zalo_last_error'] ?? '');
}

/**
 * Get Bot information from database by Zalo User ID
 * 
 * @param string $userId Zalo User ID (Zalo_ID_User from DataWork)
 * @return array|null Bot info array or null if not found
 */
function zalo_get_bot_by_user(string $userId): ?array
{
    try {
        $conn = db_connect();
        
        // Step 1: Find Zalo_Id_Bot from DataWork table using Zalo_ID_User
        $sql = "SELECT Zalo_Id_Bot FROM DataWork 
                WHERE Zalo_ID_User = ? 
                  AND Zalo_Id_Bot IS NOT NULL 
                  AND Zalo_Id_Bot <> ''";
        
        $params = [$userId];
        $stmt = sqlsrv_query($conn, $sql, $params);
        
        if (!$stmt || !sqlsrv_has_rows($stmt)) {
            db_disconnect($conn);
            zalo_set_last_error("Zalo User ID '{$userId}' not found or has no assigned bot");
            return null;
        }
        
        $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
        $botId = $row['Zalo_Id_Bot'];
        sqlsrv_free_stmt($stmt);
        
        // Step 2: Get Bot information from Zalo table
        $sql = "SELECT Id, Name, Token, Link_QR FROM Zalo WHERE Id = ?";
        $params = [(int)$botId];
        $stmt = sqlsrv_query($conn, $sql, $params);
        
        if (!$stmt || !sqlsrv_has_rows($stmt)) {
            db_disconnect($conn);
            zalo_set_last_error("Bot with ID '{$botId}' not found in Zalo table");
            return null;
        }
        
        $botInfo = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
        sqlsrv_free_stmt($stmt);
        db_disconnect($conn);
        
        return [
            'id' => (int)$botInfo['Id'],
            'name' => (string)$botInfo['Name'],
            'token' => (string)$botInfo['Token'],
            'link_qr' => (string)$botInfo['Link_QR']
        ];
        
    } catch (Exception $e) {
        zalo_set_last_error('Database error: ' . $e->getMessage());
        return null;
    }
}

/**
 * Increment message count for a bot
 * 
 * @param int $botId Bot ID from Zalo table
 * @return bool True on success, false on failure
 */
function zalo_increment_message_count(int $botId): bool
{
    try {
        $conn = db_connect();
        
        // Update Message_Number by incrementing it by 1
        $sql = "UPDATE Zalo SET Message_Number = Message_Number + 1 WHERE Id = ?";
        $params = [$botId];
        $stmt = sqlsrv_query($conn, $sql, $params);
        
        if (!$stmt) {
            db_disconnect($conn);
            return false;
        }
        
        sqlsrv_free_stmt($stmt);
        db_disconnect($conn);
        
        return true;
        
    } catch (Exception $e) {
        return false;
    }
}

/**
 * Send message to Zalo user via Bot Creator API
 * Automatically finds the correct bot assigned to the user
 * 
 * @param string $userId Zalo User ID (Zalo_ID_User from DataWork table)
 * @param string $message Message content to send
 * @return bool True on success, false on failure
 */
function sendzalo(string $userId, string $message): bool
{
    // Validate inputs
    $userId = trim($userId);
    $message = trim($message);
    
    if ($userId === '' || $message === '') {
        zalo_set_last_error('User ID and message cannot be empty');
        return false;
    }
    
    // Step 1: Try to find bot assigned to this user
    $botInfo = zalo_get_bot_by_user($userId);
    
    // Step 2: If user not found in database, use first available bot
    if ($botInfo === null) {
        try {
            $conn = db_connect();
            $sql = "SELECT TOP 1 Id, Name, Token FROM Zalo WHERE Token IS NOT NULL AND Token <> ''";
            $stmt = sqlsrv_query($conn, $sql);
            
            if ($stmt && sqlsrv_has_rows($stmt)) {
                $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
                $botInfo = [
                    'id' => (int)$row['Id'],
                    'name' => (string)$row['Name'],
                    'token' => (string)$row['Token']
                ];
                sqlsrv_free_stmt($stmt);
            }
            db_disconnect($conn);
            
            if ($botInfo === null) {
                zalo_set_last_error('No bot available in database');
                return false;
            }
        } catch (Exception $e) {
            zalo_set_last_error('Database error: ' . $e->getMessage());
            return false;
        }
    }
    
    // Step 3: Get default config (for endpoint and timeout)
    $config = zalo_get_config();
    
    // Step 4: Use bot-specific token from database
    $token = $botInfo['token'];
    
    if (empty($token)) {
        zalo_set_last_error("Bot '{$botInfo['name']}' has no token configured");
        return false;
    }
    
    // Build endpoint URL (Telegram-style) with bot-specific token
    $endpoint = $config['bot_api_endpoint'] . $token . '/sendMessage';
    
    // Prepare request data
    $postData = [
        'chat_id' => $userId,
        'text' => $message
    ];
    
    $jsonData = json_encode($postData, JSON_UNESCAPED_UNICODE);
    
    // Send request using cURL
    $ch = curl_init($endpoint);
    
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $jsonData,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $config['timeout'],
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Accept: application/json'
        ]
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);
    
    // Handle cURL errors
    if ($response === false || !empty($curlError)) {
        zalo_set_last_error('cURL Error: ' . $curlError);
        return false;
    }
    
    // Parse response
    $responseData = json_decode($response, true);
    
    // Check for success (Telegram-style response)
    if ($httpCode === 200 && isset($responseData['ok']) && $responseData['ok'] === true) {
        // Update message count for this bot
        zalo_increment_message_count($botInfo['id']);
        zalo_log("Message sent successfully to user {$userId} using bot '{$botInfo['name']}' (ID: {$botInfo['id']})", 'SUCCESS');
        return true;
    }
    
    // Extract error message
    $errorMsg = "HTTP {$httpCode}";
    if (isset($responseData['description'])) {
        $errorMsg .= ' - ' . $responseData['description'];
    }
    if (isset($responseData['error_code'])) {
        $errorMsg .= ' (Code: ' . $responseData['error_code'] . ')';
    }
    
    zalo_log("Failed to send message to user {$userId}: {$errorMsg}: with Bot_ID:{$botInfo['id']}", 'ERROR');
    zalo_set_last_error($errorMsg);
    return false;
}

/**
 * Send message directly using a specific bot token (bypass user lookup)
 * 
 * @param string $botToken Bot token from Zalo table
 * @param string $chatId Zalo chat ID
 * @param string $message Message content
 * @return bool True on success, false on failure
 */
function sendzalo_direct(string $botToken, string $chatId, string $message): bool
{
    // Validate inputs
    $botToken = trim($botToken);
    $chatId = trim($chatId);
    $message = trim($message);
    
    if ($botToken === '' || $chatId === '' || $message === '') {
        zalo_set_last_error('Bot token, chat ID, and message cannot be empty');
        return false;
    }
    
    $config = zalo_get_config();
    $endpoint = $config['bot_api_endpoint'] . $botToken . '/sendMessage';
    
    $postData = [
        'chat_id' => $chatId,
        'text' => $message
    ];
    
    $jsonData = json_encode($postData, JSON_UNESCAPED_UNICODE);
    
    $ch = curl_init($endpoint);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $jsonData,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => $config['timeout'],
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Accept: application/json'
        ]
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);
    
    // Log request for debugging
    zalo_log("Direct Send - Endpoint: {$endpoint}", 'DEBUG');
    zalo_log("Direct Send - Payload: {$jsonData}", 'DEBUG');
    
    if ($response === false) {
        $errorMsg = 'cURL Error: ' . $curlError;
        zalo_log("Direct Send - cURL Failed: {$errorMsg}", 'ERROR');
        zalo_set_last_error($errorMsg);
        return false;
    }
    
    // Log response
    zalo_log("Direct Send - HTTP {$httpCode} Response: {$response}", 'DEBUG');
    
    $responseData = json_decode($response, true);
    
    if ($httpCode === 200 && isset($responseData['ok']) && $responseData['ok'] === true) {
        zalo_log("Direct Send - SUCCESS! Chat ID: {$chatId}, Message sent", 'SUCCESS');
        return true;
    }
    
    $errorMsg = "HTTP {$httpCode}";
    if (isset($responseData['description'])) {
        $errorMsg .= ' - ' . $responseData['description'];
    }
    if (isset($responseData['error_code'])) {
        $errorMsg .= ' (Code: ' . $responseData['error_code'] . ')';
    }
    
    zalo_log("Direct Send - FAILED: {$errorMsg}", 'ERROR');
    zalo_set_last_error($errorMsg);
    return false;
}
