<?php
/*
==================================================================================
                    ابزار انتقال دیتابیس ربات آپلودک
==================================================================================
این اسکریپت برای انتقال دیتابیس از ربات قدیمی که کپی‌رایت خورده به ربات جدید استفاده می‌شه

نحوه استفاده:
1. کانفیگ‌های دیتابیس قدیمی و جدید رو تنظیم کنید
2. توکن‌های ربات قدیمی و جدید رو وارد کنید  
3. اسکریپت رو اجرا کنید

ویژگی‌ها:
- انتقال کامل جدول فایل‌ها
- بروزرسانی خودکار لینک‌ها
- حفظ شناسه‌های فایل
- بک‌آپ قبل از انتقال
- لاگ کامل عملیات
==================================================================================
*/

error_reporting(E_ALL);
ini_set('display_errors', 1);
set_time_limit(0); // Remove time limit for large transfers

// کانفیگ دیتابیس قدیمی
$OLD_DB_CONFIG = [
    'host' => 'localhost',
    'username' => 'pythonam_test',  // نام کاربری دیتابیس قدیمی
    'password' => '484DDGDh_548',   // رمز دیتابیس قدیمی
    'database' => 'pythonam_test'   // نام دیتابیس قدیمی
];

// کانفیگ دیتابیس جدید
$NEW_DB_CONFIG = [
    'host' => 'localhost',
    'username' => 'new_db_user',    // نام کاربری دیتابیس جدید
    'password' => 'new_db_pass',    // رمز دیتابیس جدید
    'database' => 'new_db_name'     // نام دیتابیس جدید
];

// مشخصات ربات‌های قدیمی و جدید
$OLD_BOT_USERNAME = 'viduplodertestbot';  // یوزرنیم ربات قدیمی
$NEW_BOT_USERNAME = 'yournewbotusername'; // یوزرنیم ربات جدید
$NEW_BOT_TOKEN = '8132031724:AAHOxbFDFjtD_De14kwlVyCPFd8rtV6nC0k'; // توکن ربات جدید

// ==================================================================================

class DatabaseMigrationTool {
    private $oldDb;
    private $newDb;
    private $logFile;
    private $oldBotUsername;
    private $newBotUsername;
    private $newBotToken;
    private $stats = [
        'total_files' => 0,
        'migrated_files' => 0,
        'skipped_files' => 0,
        'errors' => 0
    ];

    public function __construct($oldDbConfig, $newDbConfig, $oldBotUsername, $newBotUsername, $newBotToken) {
        $this->oldBotUsername = $oldBotUsername;
        $this->newBotUsername = $newBotUsername;
        $this->newBotToken = $newBotToken;
        $this->logFile = 'migration_log_' . date('Y-m-d_H-i-s') . '.txt';
        
        $this->connectDatabases($oldDbConfig, $newDbConfig);
        $this->log("شروع عملیات انتقال دیتابیس - " . date('Y-m-d H:i:s'));
    }

    private function connectDatabases($oldConfig, $newConfig) {
        try {
            // اتصال به دیتابیس قدیمی
            $this->oldDb = new mysqli($oldConfig['host'], $oldConfig['username'], $oldConfig['password'], $oldConfig['database']);
            if ($this->oldDb->connect_error) {
                throw new Exception("خطا در اتصال به دیتابیس قدیمی: " . $this->oldDb->connect_error);
            }
            $this->oldDb->set_charset('utf8mb4');

            // اتصال به دیتابیس جدید
            $this->newDb = new mysqli($newConfig['host'], $newConfig['username'], $newConfig['password'], $newConfig['database']);
            if ($this->newDb->connect_error) {
                throw new Exception("خطا در اتصال به دیتابیس جدید: " . $this->newDb->connect_error);
            }
            $this->newDb->set_charset('utf8mb4');

            $this->log("اتصال به دیتابیس‌ها موفق بود");
        } catch (Exception $e) {
            $this->log("خطا: " . $e->getMessage());
            die($e->getMessage());
        }
    }

    private function log($message) {
        $timestamp = date('Y-m-d H:i:s');
        $logMessage = "[$timestamp] $message\n";
        file_put_contents($this->logFile, $logMessage, FILE_APPEND);
        echo $logMessage;
    }

    public function createBackup() {
        $this->log("شروع بک‌آپ دیتابیس جدید...");
        
        $backupFile = 'backup_' . date('Y-m-d_H-i-s') . '.sql';
        $command = "mysqldump --host={$NEW_DB_CONFIG['host']} --user={$NEW_DB_CONFIG['username']} --password={$NEW_DB_CONFIG['password']} {$NEW_DB_CONFIG['database']} > $backupFile";
        
        if (function_exists('exec')) {
            exec($command, $output, $return_var);
            if ($return_var === 0) {
                $this->log("بک‌آپ با موفقیت در فایل $backupFile ذخیره شد");
            } else {
                $this->log("خطا در ایجاد بک‌آپ");
            }
        } else {
            $this->log("تابع exec غیرفعال است - بک‌آپ دستی انجام دهید");
        }
    }

    public function validateBotConnection() {
        $this->log("بررسی اتصال به ربات جدید...");
        
        $url = "https://api.telegram.org/bot{$this->newBotToken}/getMe";
        $response = file_get_contents($url);
        $result = json_decode($response, true);
        
        if ($result['ok']) {
            $botInfo = $result['result'];
            $this->log("اتصال به ربات موفق - @{$botInfo['username']}");
            return true;
        } else {
            $this->log("خطا در اتصال به ربات: " . $result['description']);
            return false;
        }
    }

    public function ensureTablesExist() {
        $this->log("بررسی وجود جداول در دیتابیس جدید...");
        
        // جدول file
        $createFileTable = "CREATE TABLE IF NOT EXISTS `file` (
            `row` int(11) AUTO_INCREMENT PRIMARY KEY,
            `id` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,
            `type` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL,
            `file_id` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
            `caption` text COLLATE utf8mb4_bin,
            `password` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
            `user_id` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,
            `file_size` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,
            `downloads` int(11) NOT NULL DEFAULT '0',
            `date` char(200) COLLATE utf8mb4_bin DEFAULT NULL,
            `time` char(200) COLLATE utf8mb4_bin DEFAULT NULL,
            UNIQUE KEY `unique_id` (`id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin";

        if ($this->newDb->query($createFileTable)) {
            $this->log("جدول file آماده است");
        } else {
            $this->log("خطا در ایجاد جدول file: " . $this->newDb->error);
            return false;
        }

        // جدول user
        $createUserTable = "CREATE TABLE IF NOT EXISTS `user` (
            `row` int(11) AUTO_INCREMENT PRIMARY KEY,
            `from_id` varchar(20) COLLATE utf8mb4_bin NOT NULL,
            `step` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL,
            `downloads` int(20) NOT NULL DEFAULT '0',
            `getFile` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
            `block` int(11) NOT NULL DEFAULT '0',
            `spam` text COLLATE utf8mb4_bin,
            `update_at` int(20) DEFAULT '0',
            `create_at` int(20) DEFAULT '0',
            UNIQUE KEY `unique_user` (`from_id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin";

        if ($this->newDb->query($createUserTable)) {
            $this->log("جدول user آماده است");
        } else {
            $this->log("خطا در ایجاد جدول user: " . $this->newDb->error);
            return false;
        }

        return true;
    }

    public function analyzeOldDatabase() {
        $this->log("تجزیه و تحلیل دیتابیس قدیمی...");
        
        // شمارش فایل‌ها
        $result = $this->oldDb->query("SELECT COUNT(*) as total FROM `file`");
        if ($result) {
            $row = $result->fetch_assoc();
            $this->stats['total_files'] = $row['total'];
            $this->log("تعداد کل فایل‌ها: " . $this->stats['total_files']);
        }

        // آمار انواع فایل‌ها
        $result = $this->oldDb->query("SELECT type, COUNT(*) as count FROM `file` GROUP BY type");
        if ($result) {
            $this->log("توزیع انواع فایل‌ها:");
            while ($row = $result->fetch_assoc()) {
                $this->log("  - {$row['type']}: {$row['count']} فایل");
            }
        }

        // بررسی وجود فایل‌های رمزدار
        $result = $this->oldDb->query("SELECT COUNT(*) as count FROM `file` WHERE password IS NOT NULL AND password != ''");
        if ($result) {
            $row = $result->fetch_assoc();
            $this->log("فایل‌های رمزدار: " . $row['count']);
        }
    }

    public function migrateFiles($batchSize = 100) {
        $this->log("شروع انتقال فایل‌ها...");
        
        $offset = 0;
        $migrated = 0;
        
        while (true) {
            $query = "SELECT * FROM `file` ORDER BY `row` LIMIT $batchSize OFFSET $offset";
            $result = $this->oldDb->query($query);
            
            if (!$result || $result->num_rows == 0) {
                break;
            }
            
            $this->log("پردازش دسته " . ($offset + 1) . " تا " . ($offset + $result->num_rows));
            
            while ($file = $result->fetch_assoc()) {
                if ($this->migrateFile($file)) {
                    $migrated++;
                    $this->stats['migrated_files']++;
                } else {
                    $this->stats['errors']++;
                }
            }
            
            $offset += $batchSize;
            
            // نمایش پیشرفت
            $progress = min(100, ($migrated / $this->stats['total_files']) * 100);
            $this->log("پیشرفت: " . number_format($progress, 1) . "% ($migrated از {$this->stats['total_files']})");
        }
        
        $this->log("انتقال فایل‌ها تکمیل شد. تعداد منتقل شده: $migrated");
    }

    private function migrateFile($file) {
        try {
            // بررسی وجود فایل در دیتابیس جدید
            $checkQuery = "SELECT id FROM `file` WHERE id = ?";
            $stmt = $this->newDb->prepare($checkQuery);
            $stmt->bind_param('s', $file['id']);
            $stmt->execute();
            $result = $stmt->get_result();
            
            if ($result->num_rows > 0) {
                $this->log("فایل {$file['id']} قبلاً وجود دارد - رد شد");
                $this->stats['skipped_files']++;
                return true;
            }

            // وارد کردن فایل جدید
            $insertQuery = "INSERT INTO `file` (id, type, file_id, caption, password, user_id, file_size, downloads, date, time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
            $stmt = $this->newDb->prepare($insertQuery);
            
            $stmt->bind_param('ssssssssss',
                $file['id'],
                $file['type'],
                $file['file_id'],
                $file['caption'],
                $file['password'],
                $file['user_id'],
                $file['file_size'],
                $file['downloads'],
                $file['date'],
                $file['time']
            );
            
            if ($stmt->execute()) {
                return true;
            } else {
                $this->log("خطا در وارد کردن فایل {$file['id']}: " . $this->newDb->error);
                return false;
            }
            
        } catch (Exception $e) {
            $this->log("خطا در پردازش فایل {$file['id']}: " . $e->getMessage());
            return false;
        }
    }

    public function migrateUsers($batchSize = 100) {
        $this->log("شروع انتقال کاربران...");
        
        $offset = 0;
        $migrated = 0;
        
        while (true) {
            $query = "SELECT * FROM `user` ORDER BY `row` LIMIT $batchSize OFFSET $offset";
            $result = $this->oldDb->query($query);
            
            if (!$result || $result->num_rows == 0) {
                break;
            }
            
            $this->log("پردازش کاربران دسته " . ($offset + 1) . " تا " . ($offset + $result->num_rows));
            
            while ($user = $result->fetch_assoc()) {
                if ($this->migrateUser($user)) {
                    $migrated++;
                }
            }
            
            $offset += $batchSize;
        }
        
        $this->log("انتقال کاربران تکمیل شد. تعداد منتقل شده: $migrated");
    }

    private function migrateUser($user) {
        try {
            // بررسی وجود کاربر در دیتابیس جدید
            $checkQuery = "SELECT from_id FROM `user` WHERE from_id = ?";
            $stmt = $this->newDb->prepare($checkQuery);
            $stmt->bind_param('s', $user['from_id']);
            $stmt->execute();
            $result = $stmt->get_result();
            
            if ($result->num_rows > 0) {
                // بروزرسانی اطلاعات کاربر موجود
                $updateQuery = "UPDATE `user` SET downloads = downloads + ?, update_at = ?, create_at = LEAST(create_at, ?) WHERE from_id = ?";
                $stmt = $this->newDb->prepare($updateQuery);
                $stmt->bind_param('iiis', $user['downloads'], $user['update_at'], $user['create_at'], $user['from_id']);
                return $stmt->execute();
            } else {
                // وارد کردن کاربر جدید
                $insertQuery = "INSERT INTO `user` (from_id, step, downloads, getFile, block, spam, update_at, create_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
                $stmt = $this->newDb->prepare($insertQuery);
                
                $stmt->bind_param('ssisisii',
                    $user['from_id'],
                    $user['step'],
                    $user['downloads'],
                    $user['getFile'],
                    $user['block'],
                    $user['spam'],
                    $user['update_at'],
                    $user['create_at']
                );
                
                return $stmt->execute();
            }
            
        } catch (Exception $e) {
            $this->log("خطا در پردازش کاربر {$user['from_id']}: " . $e->getMessage());
            return false;
        }
    }

    public function generateLinkConversionReport() {
        $this->log("تولید گزارش تبدیل لینک‌ها...");
        
        $reportFile = 'link_conversion_report_' . date('Y-m-d_H-i-s') . '.txt';
        $report = "گزارش تبدیل لینک‌ها\n";
        $report .= "=" . str_repeat("=", 50) . "\n\n";
        $report .= "ربات قدیمی: @{$this->oldBotUsername}\n";
        $report .= "ربات جدید: @{$this->newBotUsername}\n\n";
        
        $query = "SELECT id, type, caption FROM `file` ORDER BY `row` LIMIT 20";
        $result = $this->newDb->query($query);
        
        if ($result) {
            $report .= "نمونه لینک‌های تبدیل شده:\n";
            $report .= str_repeat("-", 50) . "\n";
            
            while ($file = $result->fetch_assoc()) {
                $oldLink = "https://t.me/{$this->oldBotUsername}?start=get_{$file['id']}";
                $newLink = "https://t.me/{$this->newBotUsername}?start=get_{$file['id']}";
                
                $fileType = $file['type'] ?: 'نامشخص';
                $caption = $file['caption'] ? mb_substr($file['caption'], 0, 30) . '...' : 'بدون کپشن';
                
                $report .= "شناسه: {$file['id']} | نوع: $fileType\n";
                $report .= "قدیمی: $oldLink\n";
                $report .= "جدید: $newLink\n";
                $report .= "کپشن: $caption\n\n";
            }
        }
        
        file_put_contents($reportFile, $report);
        $this->log("گزارش در فایل $reportFile ذخیره شد");
    }

    public function printStats() {
        $this->log("\n" . str_repeat("=", 60));
        $this->log("آمار نهایی انتقال:");
        $this->log("تعداد کل فایل‌ها: " . $this->stats['total_files']);
        $this->log("فایل‌های منتقل شده: " . $this->stats['migrated_files']);
        $this->log("فایل‌های رد شده: " . $this->stats['skipped_files']);
        $this->log("خطاها: " . $this->stats['errors']);
        
        if ($this->stats['total_files'] > 0) {
            $successRate = ($this->stats['migrated_files'] / $this->stats['total_files']) * 100;
            $this->log("نرخ موفقیت: " . number_format($successRate, 1) . "%");
        }
        
        $this->log("انتقال دیتابیس با موفقیت تکمیل شد!");
        $this->log("تمام فایل‌ها با همان شناسه قبلی در ربات جدید کار خواهند کرد");
        $this->log(str_repeat("=", 60));
    }

    public function __destruct() {
        if ($this->oldDb) {
            $this->oldDb->close();
        }
        if ($this->newDb) {
            $this->newDb->close();
        }
    }
}

// ==================================================================================
// اجرای اسکریپت
// ==================================================================================

try {
    echo "شروع ابزار انتقال دیتابیس ربات آپلودک\n";
    echo str_repeat("=", 60) . "\n";
    
    // ایجاد نمونه از کلاس انتقال
    $migration = new DatabaseMigrationTool(
        $OLD_DB_CONFIG,
        $NEW_DB_CONFIG,
        $OLD_BOT_USERNAME,
        $NEW_BOT_USERNAME,
        $NEW_BOT_TOKEN
    );
    
    // 1. بررسی اتصال به ربات جدید
    if (!$migration->validateBotConnection()) {
        throw new Exception("اتصال به ربات جدید موفق نبود");
    }
    
    // 2. ایجاد بک‌آپ
    $migration->createBackup();
    
    // 3. اطمینان از وجود جداول
    if (!$migration->ensureTablesExist()) {
        throw new Exception("ایجاد جداول موفق نبود");
    }
    
    // 4. تجزیه و تحلیل دیتابیس قدیمی
    $migration->analyzeOldDatabase();
    
    // تأیید از کاربر
    echo "\nآیا میخواهید انتقال را شروع کنید؟ (y/n): ";
    $confirmation = trim(fgets(STDIN));
    
    if (strtolower($confirmation) !== 'y') {
        echo "عملیات لغو شد.\n";
        exit;
    }
    
    // 5. انتقال فایل‌ها
    $migration->migrateFiles();
    
    // 6. انتقال کاربران
    $migration->migrateUsers();
    
    // 7. تولید گزارش
    $migration->generateLinkConversionReport();
    
    // 8. نمایش آمار نهایی
    $migration->printStats();
    
} catch (Exception $e) {
    echo "خطای کلی: " . $e->getMessage() . "\n";
    exit(1);
}

?> 