<?php
/**
 * Settings backup service.
 * Exports/restores only non-sensitive admin-editable settings.
 * It intentionally excludes config.php, config_db.php, admin passwords, sessions,
 * users, orders, payments, tickets, logs and cache runtime data.
 */

if(!function_exists('bot_settings_backup_normalize_path')){
function bot_settings_backup_normalize_path($path){
    if(function_exists('bot_storage_normalize_path')) return bot_storage_normalize_path($path);
    $path = str_replace('\\', '/', (string)$path);
    $path = preg_replace('~^/+~', '', $path);
    $path = preg_replace('~^\./+~', '', $path);
    $parts = [];
    foreach(explode('/', $path) as $part){
        if($part === '' || $part === '.') continue;
        if($part === '..'){ array_pop($parts); continue; }
        $parts[] = $part;
    }
    return implode('/', $parts);
}}

if(!function_exists('bot_settings_backup_add_item')){
function bot_settings_backup_add_item(&$items, $path, $category, $label, $storageType = 'text'){
    $path = bot_settings_backup_normalize_path($path);
    if($path === '') return;
    // Hard deny sensitive/runtime paths even if called by mistake.
    $deny = [
        'config.php','config_db.php','install.lock',
        'lib/kodam/data-web-admin.json','lib/kodam/data-web-admins.json',
    ];
    if(in_array($path, $deny, true)) return;
    if(preg_match('~^(melat|ads|cache|lib/sessions|lib/spam|photos|lib/photos)/~', $path)) return;
    $items[$path] = [
        'path'=>$path,
        'category'=>(string)$category,
        'label'=>(string)$label,
        'storage_type'=>in_array($storageType, ['json','text','raw'], true) ? $storageType : 'text',
    ];
}}

if(!function_exists('bot_settings_backup_catalog')){
function bot_settings_backup_catalog(){
    static $catalog = null;
    if(is_array($catalog)) return $catalog;
    $items = [];

    // Home keyboard layout and visibility.
    if(function_exists('bot_home_slot_keys')){
        foreach(bot_home_slot_keys() as $slot){
            bot_settings_backup_add_item($items, 'lib/keyboard/home/'.$slot.'.txt', 'keyboard_layout', 'چینش دکمه '.$slot, 'text');
        }
    }else{
        for($r=1; $r<=8; $r++) for($c=1; $c<=4; $c++) bot_settings_backup_add_item($items, 'lib/keyboard/home/line'.$r.$c.'.txt', 'keyboard_layout', 'چینش دکمه line'.$r.$c, 'text');
    }
    bot_settings_backup_add_item($items, 'lib/keyboard/home/disabled.json', 'keyboard_layout', 'دکمه‌های خاموش منوی کاربران', 'json');
    bot_settings_backup_add_item($items, 'lib/keyboard/home/styles.json', 'button_styles', 'رنگ دکمه‌های منوی کاربران', 'json');
    bot_settings_backup_add_item($items, 'lib/keyboard/channelkey.txt', 'keyboard_layout', 'تعداد دکمه‌های کانال در هر ردیف', 'text');
    bot_settings_backup_add_item($items, 'lib/keyboard/channel/styles.json', 'button_styles', 'رنگ دکمه‌های پست کانال', 'json');
    bot_settings_backup_add_item($items, 'lib/keyboard/channel/layout.json', 'keyboard_layout', 'چینش دکمه‌های پست کانال', 'json');

    // Button labels and editable button texts.
    $buttonPaths = [];
    if(function_exists('bot_button_default_values')){
        foreach(bot_button_default_values() as $path=>$value){
            if(strpos((string)$path, 'lib/Button/') === 0) $buttonPaths[] = (string)$path;
        }
    }
    foreach(glob('lib/Button/*.txt') ?: [] as $path) $buttonPaths[] = $path;
    $buttonPaths = array_values(array_unique(array_map('bot_settings_backup_normalize_path', $buttonPaths)));
    sort($buttonPaths, SORT_NATURAL);
    foreach($buttonPaths as $path){
        bot_settings_backup_add_item($items, $path, 'button_texts', 'متن/نام دکمه: '.basename($path), 'text');
    }

    // Rewards and starting balances.
    bot_settings_backup_add_item($items, 'lib/kodam/join_gift_diamonds.txt', 'reward_settings', 'موجودی اولیه / هدیه استارت کاربر جدید', 'text');
    bot_settings_backup_add_item($items, 'lib/Button/coinamount1.txt', 'reward_settings', 'پاداش جمع‌آوری الماس کاربر عادی', 'text');
    bot_settings_backup_add_item($items, 'lib/Button/coinamount2.txt', 'reward_settings', 'پاداش جمع‌آوری الماس کاربر حرفه‌ای', 'text');
    bot_settings_backup_add_item($items, 'lib/Button/coinamount3.txt', 'reward_settings', 'پاداش جمع‌آوری الماس کاربر ویژه', 'text');
    bot_settings_backup_add_item($items, 'lib/kodam/data-daily.json', 'reward_settings', 'تنظیمات الماس روزانه', 'json');
    bot_settings_backup_add_item($items, 'lib/kodam/data-zirmjmae.json', 'reward_settings', 'تنظیمات زیرمجموعه‌گیری و رفرال', 'json');
    bot_settings_backup_add_item($items, 'lib/kodam/data-left.json', 'reward_settings', 'تنظیمات لفت و جریمه', 'json');
    bot_settings_backup_add_item($items, 'lib/kodam/reward_cooldown.json', 'reward_settings', 'فاصله دریافت مجدد از هر کانال', 'json');
    bot_settings_backup_add_item($items, 'lib/kodam/self_reward.json', 'reward_settings', 'دریافت الماس از کانال خود سفارش‌دهنده', 'json');

    // Channels.
    bot_settings_backup_add_item($items, 'lib/kodam/channel.txt', 'channel_settings', 'جوین اجباری اول', 'text');
    bot_settings_backup_add_item($items, 'lib/kodam/channel2.txt', 'channel_settings', 'جوین اجباری دوم', 'text');
    bot_settings_backup_add_item($items, 'lib/kodam/forced_join_channels.json', 'channel_settings', 'لیست چندکاناله قفل عضویت اجباری', 'json');
    bot_settings_backup_add_item($items, 'lib/kodam/cht.txt', 'channel_settings', 'کانال تبلیغات', 'text');
    bot_settings_backup_add_item($items, 'lib/kodam/giftch.txt', 'channel_settings', 'کانال کد هدیه', 'text');
    bot_settings_backup_add_item($items, 'lib/kodam/channel_map.json', 'channel_settings', 'نگاشت شناسه کانال‌ها', 'json');
    bot_settings_backup_add_item($items, 'lib/kodam/blocked_channels.json', 'channel_settings', 'لیست چنل‌های مسدود', 'json');

    // Feature toggles and text settings which are edited from panels.
    $featureJson = [
        'lib/kodam/data-ads.json'=>'تنظیمات ثبت سفارش/تبلیغات',
        'lib/kodam/data-Cancellads.json'=>'تنظیمات لغو سفارش',
        'lib/kodam/data-transfer.json'=>'تنظیمات انتقال',
        'lib/kodam/data-violation.json'=>'تنظیمات گزارش تخلف',
        'lib/kodam/data-antispam.json'=>'تنظیمات ضداسپم',
        'lib/kodam/data-fraud.json'=>'تنظیمات ضدتقلب پیشرفته',
        'lib/kodam/data-power.json'=>'روشن/خاموشی ربات و متن خاموشی',
        'lib/kodam/data-admin-tools.json'=>'تنظیمات ابزارهای مدیریتی',
        'lib/kodam/data-advanced-tools.json'=>'تنظیمات امکانات پیشرفته',
    ];
    foreach($featureJson as $path=>$label) bot_settings_backup_add_item($items, $path, 'feature_settings', $label, 'json');

    $catalog = $items;
    return $catalog;
}}

if(!function_exists('bot_settings_backup_read_raw')){
function bot_settings_backup_read_raw($path){
    $path = bot_settings_backup_normalize_path($path);
    if(function_exists('bot_data_get_raw')) return (string)bot_data_get_raw($path, '');
    if(is_file($path)) return (string)@file_get_contents($path);
    return '';
}}

if(!function_exists('bot_settings_backup_write_raw')){
function bot_settings_backup_write_raw($path, $raw, $storageType = 'raw'){
    $path = bot_settings_backup_normalize_path($path);
    $storageType = in_array($storageType, ['json','text','raw'], true) ? $storageType : 'raw';
    if(function_exists('bot_data_put_raw')) return bot_data_put_raw($path, (string)$raw, $storageType);
    $dir = dirname($path);
    if($dir && $dir !== '.' && !is_dir($dir)) @mkdir($dir, 0775, true);
    return @file_put_contents($path, (string)$raw, LOCK_EX) !== false;
}}

if(!function_exists('bot_settings_backup_export_array')){
function bot_settings_backup_export_array($source = 'web_panel'){
    $catalog = bot_settings_backup_catalog();
    $items = [];
    foreach($catalog as $path=>$meta){
        $raw = bot_settings_backup_read_raw($path);
        $item = $meta;
        $item['value'] = $raw;
        $item['sha1'] = sha1($raw);
        $item['bytes'] = strlen($raw);
        if(($item['storage_type'] ?? '') === 'json'){
            $decoded = json_decode($raw, true);
            $item['json_valid'] = ($raw === '' || is_array($decoded));
        }
        $items[$path] = $item;
    }
    $versionFile = 'VERSION.txt';
    $botVersion = is_file($versionFile) ? trim((string)@file_get_contents($versionFile)) : '';
    return [
        '_meta' => [
            'type' => 'telegram_bot_panel_settings_backup',
            'schema_version' => 1,
            'created_at' => date('c'),
            'source' => (string)$source,
            'bot_version' => $botVersion,
            'items_count' => count($items),
            'excluded' => ['config.php','config_db.php','admin passwords','sessions','users','orders','payments','tickets','logs','runtime cache'],
        ],
        'items' => $items,
    ];
}}

if(!function_exists('bot_settings_backup_json')){
function bot_settings_backup_json($source = 'web_panel'){
    return json_encode(bot_settings_backup_export_array($source), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
}}

if(!function_exists('bot_settings_backup_create_file')){
function bot_settings_backup_create_file($source = 'web_panel'){
    $dir = 'cache/backups';
    if(!is_dir($dir)) @mkdir($dir, 0775, true);
    $name = 'panel-settings-backup-' . date('Ymd-His') . '-' . substr(bin2hex(random_bytes(4)), 0, 8) . '.json';
    $file = $dir . '/' . $name;
    $ok = @file_put_contents($file, bot_settings_backup_json($source), LOCK_EX);
    return $ok === false ? ['ok'=>false, 'error'=>'write_failed'] : ['ok'=>true, 'file'=>$file, 'count'=>count(bot_settings_backup_catalog())];
}}

if(!function_exists('bot_settings_backup_restore_array')){
function bot_settings_backup_restore_array($backup, $actor = 'admin'){
    if(is_string($backup)){
        $backup = json_decode($backup, true);
    }
    if(!is_array($backup) || !isset($backup['items']) || !is_array($backup['items'])){
        return ['ok'=>false, 'error'=>'فرمت فایل بکاپ تنظیمات معتبر نیست.'];
    }
    $type = (string)($backup['_meta']['type'] ?? '');
    if($type !== '' && $type !== 'telegram_bot_panel_settings_backup'){
        return ['ok'=>false, 'error'=>'این فایل برای بکاپ تنظیمات این ربات نیست.'];
    }
    $catalog = bot_settings_backup_catalog();
    $restored = 0; $skipped = 0; $errors = [];
    foreach($backup['items'] as $path=>$item){
        $path = bot_settings_backup_normalize_path(is_array($item) && isset($item['path']) ? $item['path'] : $path);
        if(!isset($catalog[$path])){ $skipped++; continue; }
        if(!is_array($item) || !array_key_exists('value', $item)){ $skipped++; continue; }
        $raw = (string)$item['value'];
        $storageType = (string)($catalog[$path]['storage_type'] ?? ($item['storage_type'] ?? 'raw'));
        if($storageType === 'json'){
            $trim = trim($raw);
            if($trim !== ''){
                $decoded = json_decode($raw, true);
                if(!is_array($decoded)){
                    $errors[] = $path . ': json_invalid';
                    $skipped++;
                    continue;
                }
                $raw = json_encode($decoded, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
            }else{
                $raw = '{}';
            }
        }
        if(bot_settings_backup_write_raw($path, $raw, $storageType)) $restored++; else { $errors[] = $path . ': write_failed'; $skipped++; }
    }
    if(function_exists('bot_home_normalize_layout')) bot_home_normalize_layout();
    if(function_exists('bot_home_purge_removed_menu_tokens')) bot_home_purge_removed_menu_tokens();
    if(function_exists('bot_cache_clear_all')) @bot_cache_clear_all();
    if(function_exists('bot_admin_log')) @bot_admin_log((string)$actor, 'settings_backup_restore', 'settings', null, 'بازگردانی بکاپ تنظیمات پنل', ['restored'=>$restored,'skipped'=>$skipped,'errors'=>$errors]);
    return ['ok'=>empty($errors), 'restored'=>$restored, 'skipped'=>$skipped, 'errors'=>$errors];
}}

if(!function_exists('bot_settings_backup_category_labels')){
function bot_settings_backup_category_labels(){
    return [
        'keyboard_layout'=>'چینش و خاموش/روشن دکمه‌ها',
        'button_styles'=>'رنگ دکمه‌ها',
        'button_texts'=>'متن دکمه‌ها',
        'reward_settings'=>'تنظیمات الماس و هدیه‌ها',
        'channel_settings'=>'کانال‌ها و مسدودی چنل‌ها',
        'feature_settings'=>'سایر تنظیمات پنل',
    ];
}}
?>
