<?php
require_once __DIR__ . '/config/db.php';
require_once __DIR__ . '/includes/helpers.php';

date_default_timezone_set('Europe/Moscow');

$database = new Database();
$db = null;

// Wait for database connection
echo "Waiting for database connection...\n";
while ($db === null) {
    $db = $database->getConnection();
    if ($db === null) {
        echo "Database not ready, retrying in 5 seconds...\n";
        sleep(5);
    }
}

// Sync MySQL timezone with PHP
$db->exec("SET time_zone = '+03:00'");

$botToken = getSetting($db, 'telegram_bot_token');
if (empty($botToken)) {
    die("Telegram Bot Token not set.\n");
}
$apiUrl = "https://api.telegram.org/bot$botToken/";

echo "Telegram Worker Started [Europe/Moscow]\n";

while (true) {
    echo "Checking for pending posts... [" . date('Y-m-d H:i:s') . "]\n";
    
    // 1. Fetch pending posts
    $currentTime = date('Y-m-d H:i:s');
    $stmt = $db->prepare("
        SELECT p.*, g.chat_id 
        FROM telegram_posts p 
        JOIN telegram_groups g ON p.group_id = g.id 
        WHERE p.schedule_time <= :now AND p.is_sent = FALSE AND p.is_active = 1
    ");
    $stmt->execute([':now' => $currentTime]);
    $posts = $stmt->fetchAll(PDO::FETCH_ASSOC);

    if (count($posts) > 0) {
        echo "Found " . count($posts) . " pending posts.\n";
    }

    foreach ($posts as $post) {
        $chatId = $post['chat_id'];
        $content = $post['content'];
        $mediaPath = $post['media_path'];
        $mediaType = $post['media_type'];
        $mediaUrl = $post['media_url'];
        
        $tempFile = null;
        
        // Re-check activity in case it was toggled while the loop was starting
        $stmtReCheck = $db->prepare("SELECT is_active FROM telegram_posts WHERE id = :id");
        $stmtReCheck->execute([':id' => $post['id']]);
        if (!($reCheck = $stmtReCheck->fetch()) || !$reCheck['is_active']) {
            echo "Post ID {$post['id']} was deactivated just before sending. Skipping.\n";
            continue;
        }

        $response = null;
        
        try {
            // 0. Handle Media URL download if provided
            if (!empty($mediaUrl)) {
                echo "Downloading media from URL: $mediaUrl\n";
                $ext = pathinfo(parse_url($mediaUrl, PHP_URL_PATH), PATHINFO_EXTENSION) ?: 'tmp';
                $tempFile = sys_get_temp_dir() . '/tg_media_' . uniqid() . '.' . $ext;
                
                $ch = curl_init($mediaUrl);
                $fp = fopen($tempFile, 'wb');
                curl_setopt($ch, CURLOPT_FILE, $fp);
                curl_setopt($ch, CURLOPT_HEADER, 0);
                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
                curl_setopt($ch, CURLOPT_TIMEOUT, 60);
                curl_exec($ch);
                $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                curl_close($ch);
                fclose($fp);
                
                if ($httpCode !== 200) {
                    throw new Exception("Failed to download media from URL. HTTP Code: $httpCode");
                }
                
                $fullPath = $tempFile;
                echo "Downloaded to: $fullPath\n";
            } else {
                $fullPath = realpath(__DIR__ . '/public/' . $mediaPath);
            }

            // Increase threshold to 1 hour to handle timezone drifts or delayed tasks gracefully
            $isPastTime = (strtotime($post['schedule_time']) < time() - 3600);
            
            if ($isPastTime) {
                echo "Skipping past-time post ID {$post['id']} (scheduled for {$post['schedule_time']})\n";
                // Mock a successful response to mark it as processed
                $response = ['ok' => true, 'result' => ['message_id' => -1]]; 
            } elseif ($mediaType === 'none' || (empty($mediaPath) && empty($mediaUrl))) {
                $response = sendRequest($apiUrl . "sendMessage", [
                    'chat_id' => $chatId,
                    'text' => $content,
                    'parse_mode' => 'HTML'
                ]);
            } elseif ($mediaType === 'image') {
                $response = sendRequest($apiUrl . "sendPhoto", [
                    'chat_id' => $chatId,
                    'caption' => $content,
                    'photo' => new CURLFile($fullPath),
                    'parse_mode' => 'HTML'
                ], true);
            } elseif ($mediaType === 'video') {
                $response = sendRequest($apiUrl . "sendVideo", [
                    'chat_id' => $chatId,
                    'caption' => $content,
                    'video' => new CURLFile($fullPath),
                    'parse_mode' => 'HTML'
                ], true);
            } elseif ($mediaType === 'file') {
                $response = sendRequest($apiUrl . "sendDocument", [
                    'chat_id' => $chatId,
                    'caption' => $content,
                    'document' => new CURLFile($fullPath),
                    'parse_mode' => 'HTML'
                ], true);
            }

            if ($response && isset($response['ok']) && $response['ok']) {
                $messageId = $response['result']['message_id'];
                $statusText = ($messageId === -1) ? "Skipped (Past Time)" : "Successfully sent";
                $stmtUpdate = $db->prepare("UPDATE telegram_posts SET is_sent = TRUE, sent_message_id = :mid, sent_at = NOW() WHERE id = :id");
                $stmtUpdate->execute([':mid' => $messageId, ':id' => $post['id']]);
                echo "{$statusText} post ID {$post['id']} to group {$chatId}\n";

                if ($post['is_recurring']) {
                    echo "Post ID {$post['id']} is recurring. Processing repeat logic...\n";
                    $interval = $post['repeat_interval'];
                    $unit = $post['repeat_unit'];
                    $currentRepeatCount = (int)$post['repeat_count'];
                    
                    $shouldRepeat = false;
                    $nextRepeatCount = 0;
                    $nextIsRecurring = 1;

                    if ($currentRepeatCount === 0) {
                        // Infinity
                        $shouldRepeat = true;
                        $nextRepeatCount = 0;
                        $nextIsRecurring = 1;
                    } elseif ($currentRepeatCount > 1) {
                        // More repeats remaining
                        $shouldRepeat = true;
                        $nextRepeatCount = $currentRepeatCount - 1;
                        $nextIsRecurring = 1;
                    } elseif ($currentRepeatCount === 1) {
                        // Last repeat
                        $shouldRepeat = true;
                        $nextRepeatCount = 0;
                        $nextIsRecurring = 0; // Stop after this next one
                    }

                    if ($shouldRepeat) {
                        $nextTimeTimestamp = strtotime($post['schedule_time'] . " + $interval $unit");
                        $nowTs = time();
                        
                        // Catch-up logic: if calculated nextTime is still in the past, keep adding intervals
                        // until we reach the future (relative to original schedule)
                        while ($nextTimeTimestamp <= $nowTs) {
                            echo "Next occurrence " . date('Y-m-d H:i:s', $nextTimeTimestamp) . " is in the past. Jumping forward...\n";
                            $nextTimeTimestamp = strtotime(date('Y-m-d H:i:s', $nextTimeTimestamp) . " + $interval $unit");
                            
                            // If it's not infinite, we should decrement repeat_count for each "missed" occurrence
                            if ($nextIsRecurring && $nextRepeatCount > 0) {
                                $nextRepeatCount--;
                                if ($nextRepeatCount === 0) {
                                    $nextIsRecurring = 0;
                                    break; 
                                }
                            } elseif ($nextIsRecurring === 0) {
                                // We reached the last planned repeat during catch-up
                                $shouldRepeat = ($nextTimeTimestamp > $nowTs); // Only repeat if we actually found a future slot
                                break;
                            }
                        }
                        
                        $nextTime = date('Y-m-d H:i:s', $nextTimeTimestamp);
                        
                        if ($shouldRepeat && $nextTimeTimestamp > $nowTs) {
                            // Check if a successor already exists (to prevent cloning)
                            $stmtCheck = $db->prepare("SELECT id FROM telegram_posts WHERE group_id = :g AND content = :c AND schedule_time = :s AND is_sent = 0 LIMIT 1");
                            $stmtCheck->execute([':g' => $post['group_id'], ':c' => $post['content'], ':s' => $nextTime]);
                            if ($stmtCheck->fetch()) {
                                echo "Next repeat for post ID {$post['id']} already exists at $nextTime. Skipping insertion.\n";
                            } else {
                                echo "Scheduling next repeat for post ID {$post['id']} at $nextTime (Remaining: " . ($nextIsRecurring ? ($currentRepeatCount === 0 ? "Infinity" : $nextRepeatCount) : "Last one") . ")\n";
                                
                                $stmtNext = $db->prepare("INSERT INTO telegram_posts 
                                    (content, media_path, media_url, media_type, schedule_time, group_id, repeat_count, repeat_interval, repeat_unit, is_recurring, delete_after_minutes, is_active, chain_id) 
                                    VALUES (:c, :m, :mu, :t, :s, :g, :rc, :ri, :ru, :ir, :dam, 1, :cid)");
                                
                                $stmtNext->execute([
                                    ':c' => $post['content'],
                                    ':m' => $post['media_path'],
                                    ':mu' => $post['media_url'],
                                    ':t' => $post['media_type'],
                                    ':s' => $nextTime,
                                    ':g' => $post['group_id'],
                                    ':rc' => $nextRepeatCount,
                                    ':ri' => $post['repeat_interval'],
                                    ':ru' => $post['repeat_unit'],
                                    ':ir' => $nextIsRecurring,
                                    ':dam' => $post['delete_after_minutes'],
                                    ':cid' => $post['chain_id'] ?: $post['id']
                                ]);
                                echo "Next repeat for post ID {$post['id']} successfully inserted.\n";
                            }
                        } else {
                            echo "All repeats for post ID {$post['id']} were in the past or count reached 0 during catch-up. Deactivating.\n";
                            $db->prepare("UPDATE telegram_posts SET is_active = 0 WHERE id = :id")->execute([':id' => $post['id']]);
                        }
                    } else {
                        echo "No more repeats for post ID {$post['id']}. Deactivating.\n";
                        $db->prepare("UPDATE telegram_posts SET is_active = 0 WHERE id = :id")->execute([':id' => $post['id']]);
                    }
                } else {
                    // Not recurring, deactivate after successful send
                    echo "Post ID {$post['id']} is not recurring. Deactivating.\n";
                    $db->prepare("UPDATE telegram_posts SET is_active = 0 WHERE id = :id")->execute([':id' => $post['id']]);
                }
            } else {
                echo "Failed to send post ID {$post['id']}: " . json_encode($response) . "\n";
            }
        } catch (Exception $e) {
            echo "ERROR processing post ID {$post['id']}: " . $e->getMessage() . "\n";
        } finally {
            if ($tempFile && file_exists($tempFile)) {
                unlink($tempFile);
                echo "Deleted temporary file: $tempFile\n";
            }
        }
    }

    // 2. Handle Auto-deletion
    $stmtDelCheck = $db->prepare("
        SELECT p.*, g.chat_id 
        FROM telegram_posts p 
        JOIN telegram_groups g ON p.group_id = g.id 
        WHERE p.is_sent = TRUE AND p.delete_after_minutes > 0 AND p.is_deleted = FALSE AND p.sent_message_id IS NOT NULL
    ");
    $stmtDelCheck->execute();
    $sentPosts = $stmtDelCheck->fetchAll(PDO::FETCH_ASSOC);

    foreach ($sentPosts as $post) {
        $deleteTime = strtotime($post['sent_at'] . ' + ' . $post['delete_after_minutes'] . ' minutes');
        if (time() >= $deleteTime) {
            $response = sendRequest($apiUrl . "deleteMessage", [
                'chat_id' => $post['chat_id'],
                'message_id' => $post['sent_message_id']
            ]);

            if ($response && isset($response['ok']) && $response['ok']) {
                $db->prepare("UPDATE telegram_posts SET is_deleted = TRUE WHERE id = :id")->execute([':id' => $post['id']]);
                echo "Deleted post ID {$post['id']} from group {$post['chat_id']}\n";
            }
        }
    }

    sleep(30); // Check every 30 seconds
}

function sendRequest($url, $params, $isMultipart = false) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 120);
    // No manual Content-Type: multipart/form-data header needed. 
    // PHP's curl will set it correctly with boundaries when $params is an array.
    $result = curl_exec($ch);
    $error = curl_error($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($error) {
        return ['ok' => false, 'description' => "CURL Error: $error"];
    }

    $response = json_decode($result, true);
    if ($httpCode !== 200 && !isset($response['ok'])) {
        return ['ok' => false, 'description' => "HTTP Error $httpCode: $result"];
    }

    return $response;
}
