<?php
// Web admin bootstrap for the Telegram bot. Works on normal cPanel/PHP hosting.
// The session must be started from a writable local folder; some shared hosts
// have a broken/default session path and login looks successful but returns to login.
if (!ob_get_level()) { @ob_start(); }

$WEB_ROOT = realpath(__DIR__ . '/..');
if (!$WEB_ROOT) { $WEB_ROOT = dirname(__DIR__); }
if (!$WEB_ROOT) { http_response_code(500); exit('Root path not found'); }
chdir($WEB_ROOT);

define('WEB_ADMIN_ROOT', $WEB_ROOT);

if (session_status() !== PHP_SESSION_ACTIVE) {
    $sessionDir = WEB_ADMIN_ROOT . '/lib/sessions';
    if (!is_dir($sessionDir)) { @mkdir($sessionDir, 0775, true); }
    if (is_dir($sessionDir) && is_writable($sessionDir)) {
        @ini_set('session.save_path', $sessionDir);
    }
    @ini_set('session.use_strict_mode', '1');
    @ini_set('session.cookie_httponly', '1');
    @ini_set('session.cookie_samesite', 'Lax');
    @session_name('TELEGRAM_WEB_ADMIN');
    $secureCookie = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
    $scriptDir = str_replace('\\', '/', dirname((string)($_SERVER['SCRIPT_NAME'] ?? '/admin/login.php')));
    $cookiePath = rtrim($scriptDir, '/');
    if ($cookiePath === '' || $cookiePath === '.') { $cookiePath = '/'; }
    if (PHP_VERSION_ID >= 70300) {
        @session_set_cookie_params(['lifetime'=>0,'path'=>$cookiePath,'secure'=>$secureCookie,'httponly'=>true,'samesite'=>'Lax']);
    } else {
        @session_set_cookie_params(0, $cookiePath, '', $secureCookie, true);
    }
    @session_start();
}

if (!function_exists('web_h')) {
    function web_h($v){ return htmlspecialchars((string)$v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }
}
if (!function_exists('web_int')) {
    function web_int($v, $min = null, $max = null){ $n = (int)preg_replace('/[^0-9\-]/', '', (string)$v); if($min!==null && $n<$min)$n=$min; if($max!==null && $n>$max)$n=$max; return $n; }
}
if (!function_exists('web_redirect')) {
    function web_redirect($url){ if(!headers_sent()) header('Location: '.$url); echo '<!doctype html><meta charset="utf-8"><meta http-equiv="refresh" content="0;url='.web_h($url).'"><script>location.href='.json_encode($url).';</script>'; exit; }
}
if (!function_exists('web_flash')) {
    function web_flash($type, $msg){ $_SESSION['flash'][] = ['type'=>$type, 'msg'=>$msg]; }
}
if (!function_exists('web_take_flash')) {
    function web_take_flash(){ $f = $_SESSION['flash'] ?? []; unset($_SESSION['flash']); return is_array($f) ? $f : []; }
}

if (!is_file(WEB_ADMIN_ROOT . '/config.php')) {
    $GLOBALS['WEB_BOOT_ERROR'] = 'config.php پیدا نشد. اول install.php را اجرا کن.';
} else {
    require_once WEB_ADMIN_ROOT . '/config.php';
    if (is_file(WEB_ADMIN_ROOT . '/config_db.php')) require_once WEB_ADMIN_ROOT . '/config_db.php';
    if (is_file(WEB_ADMIN_ROOT . '/lib/db_storage.php')) require_once WEB_ADMIN_ROOT . '/lib/db_storage.php';
    if (is_file(WEB_ADMIN_ROOT . '/app/Bootstrap.php')) require_once WEB_ADMIN_ROOT . '/app/Bootstrap.php';
    if (is_file(WEB_ADMIN_ROOT . '/app/Support/TextFormatting.php')) require_once WEB_ADMIN_ROOT . '/app/Support/TextFormatting.php';
    if (is_file(WEB_ADMIN_ROOT . '/app/Legacy/CoreApi.php')) require_once WEB_ADMIN_ROOT . '/app/Legacy/CoreApi.php';
    foreach([
        '/app/Legacy/ChannelHelpers.php',
        '/app/Services/StateService.php',
        '/app/Services/CannedReplyService.php',
        '/app/Services/AdminToolsService.php',
        '/app/Services/AdvancedToolsService.php',
        '/app/Services/TicketMiniAppService.php',
        '/app/Services/GiftCodeService.php',
        '/app/Services/TextSettingsService.php',
        '/app/Services/DailyRewardService.php',
        '/app/Services/FraudGuardService.php',
        '/app/Services/ReferralService.php',
        '/app/Services/AntiSpamService.php',
        '/app/Services/ViolationReportService.php',
        '/app/Services/PaymentReportService.php',
        '/app/Services/AccountingService.php',
        '/app/Services/SponsorService.php',
        '/app/Services/ReactionService.php',
        '/app/Services/SimpleShopService.php',
        '/app/Services/HomeKeyboardService.php',
        '/app/Services/ChannelButtonService.php',
        '/app/Services/JoinGiftService.php',
        '/app/Services/RewardSettingsService.php',
        '/app/Services/SettingsBackupService.php',
        '/lib/button_defaults.php',
        '/lib/class.php',
        '/lib/broadcast_queue.php',
    ] as $file){ $p = WEB_ADMIN_ROOT.$file; if(is_file($p)) require_once $p; }
}

function web_pdo(){
    if (function_exists('bot_sql_pdo')) return bot_sql_pdo();
    return null;
}

function web_admin_hash_sources(){
    $hashes = [];

    // اولویت با فایل داخلی پنل است، چون install_web_panel.php همیشه این فایل را می‌نویسد.
    // روی بعضی هاست‌ها config.php به دلیل کش یا تعریف تکراری ثابت‌ها، مقدار قدیمی را نگه می‌دارد.
    $dataFile = WEB_ADMIN_ROOT . '/lib/kodam/data-web-admin.json';
    if (is_file($dataFile)) {
        $raw = @file_get_contents($dataFile);
        $j = is_string($raw) ? json_decode($raw, true) : null;
        if (is_array($j) && !empty($j['password_hash'])) $hashes[] = (string)$j['password_hash'];
    }
    if (function_exists('bot_data_get_json')) {
        $s = bot_data_get_json('lib/kodam/data-web-admin.json', []);
        if (is_array($s) && !empty($s['password_hash'])) $hashes[] = (string)$s['password_hash'];
    }
    if (($pdo = web_pdo())) {
        try {
            $st=$pdo->prepare("SELECT storage_value FROM bot_settings WHERE setting_key='web_admin_password_hash' LIMIT 1");
            $st->execute();
            $h=$st->fetchColumn();
            if($h) $hashes[] = (string)$h;
        } catch(Throwable $e) {}
    }
    if (defined('WEB_ADMIN_PASSWORD_HASH') && trim((string)WEB_ADMIN_PASSWORD_HASH) !== '') $hashes[] = (string)WEB_ADMIN_PASSWORD_HASH;
    if (defined('BACKUP_DOWNLOAD_PASSWORD_HASH') && trim((string)BACKUP_DOWNLOAD_PASSWORD_HASH) !== '') $hashes[] = (string)BACKUP_DOWNLOAD_PASSWORD_HASH;

    $out = [];
    foreach ($hashes as $h) {
        $h = trim((string)$h);
        if ($h !== '' && !in_array($h, $out, true)) $out[] = $h;
    }
    return $out;
}

function web_admin_accounts_file(){ return WEB_ADMIN_ROOT . '/lib/kodam/data-web-admins.json'; }
function web_admin_accounts_load(){
    $file = web_admin_accounts_file();
    $raw = is_file($file) ? @file_get_contents($file) : '';
    $data = is_string($raw) && $raw !== '' ? json_decode($raw, true) : [];
    if(!is_array($data)) $data = [];
    if(!isset($data['admins']) || !is_array($data['admins'])) $data['admins'] = [];
    return $data;
}
function web_admin_accounts_save(array $data){
    if(!isset($data['admins']) || !is_array($data['admins'])) $data['admins'] = [];
    $dir = dirname(web_admin_accounts_file());
    if(!is_dir($dir)) @mkdir($dir, 0775, true);
    $data['updated_at'] = date('c');
    $data['version'] = 'v41';
    return @file_put_contents(web_admin_accounts_file(), json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), LOCK_EX) !== false;
}
function web_admin_account($uid){
    $uid = preg_replace('/[^0-9]/', '', (string)$uid);
    if($uid === '') return null;
    $data = web_admin_accounts_load();
    return isset($data['admins'][$uid]) && is_array($data['admins'][$uid]) ? $data['admins'][$uid] : null;
}
function web_admin_account_active($uid){
    $acc = web_admin_account($uid);
    return is_array($acc) && (($acc['active'] ?? true) ? true : false) && !empty($acc['password_hash']);
}
function web_admin_password_verify_for($uid, $password){
    $uid = preg_replace('/[^0-9]/', '', (string)$uid);
    $pass = (string)$password;
    $passTrim = trim($pass);
    $acc = web_admin_account($uid);
    if(is_array($acc) && !empty($acc['password_hash']) && (($acc['active'] ?? true) ? true : false)){
        $hash = trim((string)$acc['password_hash']);
        if(function_exists('password_verify') && (password_verify($pass, $hash) || ($passTrim !== $pass && password_verify($passTrim, $hash)))) return true;
        if(hash_equals($hash, hash('sha256', $pass)) || ($passTrim !== $pass && hash_equals($hash, hash('sha256', $passTrim)))) return true;
    }
    // ادمین اصلی همچنان با رمز اصلی پنل وارد می‌شود.
    if($uid !== '' && web_is_owner($uid)) return web_admin_password_verify($pass);
    // سازگاری با نسخه‌های قبلی: اگر هنوز برای ادمین‌های دیگر رمز جدا ساخته نشده بود، رمز اصلی پنل هم قبول می‌شود.
    if($uid !== '' && web_is_bot_admin_legacy($uid)) return web_admin_password_verify($pass);
    return false;
}
function web_admin_accounts_ids($activeOnly = true){
    $data = web_admin_accounts_load();
    $ids = [];
    foreach(($data['admins'] ?? []) as $id=>$acc){
        $id = preg_replace('/[^0-9]/', '', (string)$id);
        if($id === '') continue;
        if($activeOnly && is_array($acc) && array_key_exists('active', $acc) && !$acc['active']) continue;
        $ids[] = $id;
    }
    return array_values(array_unique($ids));
}

function web_admin_hash(){
    $sources = web_admin_hash_sources();
    return $sources[0] ?? '';
}

function web_admin_password_verify($password){
    $pass = (string)$password;
    $passTrim = trim($pass);
    foreach (web_admin_hash_sources() as $hash) {
        $hash = trim((string)$hash);
        if ($hash === '') continue;
        if (function_exists('password_verify') && (password_verify($pass, $hash) || ($passTrim !== $pass && password_verify($passTrim, $hash)))) return true;
        if (hash_equals($hash, hash('sha256', $pass)) || ($passTrim !== $pass && hash_equals($hash, hash('sha256', $passTrim)))) return true;
        // سازگاری با نصب‌های خیلی قدیمی که رمز را اشتباهی ساده ذخیره کرده باشند.
        if (strpos($hash, '$2y$') !== 0 && strpos($hash, '$argon') !== 0 && hash_equals($hash, $passTrim)) return true;
    }
    return false;
}

function web_owner_admin_id(){
    global $admin;
    $ids = function_exists('bot_config_master_admin_ids') ? bot_config_master_admin_ids() : [];
    if(!$ids && !empty($admin)) $ids[] = preg_replace('/[^0-9]/', '', (string)$admin);
    return $ids[0] ?? '';
}
function web_master_admin_list(){
    global $admin;
    $ids = function_exists('bot_config_master_admin_ids') ? bot_config_master_admin_ids() : [];
    if(!$ids && !empty($admin)) $ids[] = preg_replace('/[^0-9]/', '', (string)$admin);
    return array_values(array_unique(array_filter($ids, fn($x)=>$x!=='')));
}

function web_admin_list_legacy(){
    $ids = web_master_admin_list();
    if (function_exists('bot_data_get_json')) {
        $list = bot_data_get_json('lib/kodam/list.json', []);
        if (is_array($list) && isset($list['admins']) && is_array($list['admins'])) foreach($list['admins'] as $id) $ids[]=preg_replace('/[^0-9]/','',(string)$id);
    }
    return array_values(array_unique(array_filter($ids, fn($x)=>$x!=='')));
}
function web_admin_list(){
    return array_values(array_unique(array_merge(web_admin_list_legacy(), web_admin_accounts_ids(true))));
}
function web_is_bot_admin_legacy($uid){ return in_array((string)preg_replace('/[^0-9]/','',(string)$uid), web_admin_list_legacy(), true); }
function web_is_bot_admin($uid){ return in_array((string)preg_replace('/[^0-9]/','',(string)$uid), web_admin_list(), true); }
function web_is_owner($uid=null){ $uid = $uid===null ? ($_SESSION['web_admin_id'] ?? '') : (string)$uid; $uid = preg_replace('/[^0-9]/','',$uid); return $uid !== '' && in_array($uid, web_master_admin_list(), true); }
function web_require_owner(){ if(!web_is_owner()){ http_response_code(403); exit('این بخش فقط برای ادمین اصلی است.'); } }
function web_is_logged_in(){ return !empty($_SESSION['web_admin_logged_in']) && !empty($_SESSION['web_admin_id']) && web_is_bot_admin($_SESSION['web_admin_id']); }
function web_require_login(){ if(!web_is_logged_in()) web_redirect('login.php'); }

function web_permission_catalog(){
    return [
        'dashboard'=>'داشبورد',
        'users'=>'مدیریت کاربران',
        'orders'=>'مشاهده سفارش‌ها',
        'orders_manage'=>'تغییر/حذف سفارش‌ها',
        'tickets'=>'تیکت‌ها و پشتیبانی',
        'gift_codes'=>'کد هدیه',
        'settings'=>'تنظیمات اصلی',
        'texts'=>'تنظیم متن‌ها',
        'broadcast'=>'ارسال همگانی',
        'backups'=>'بکاپ و دانلود فایل',
        'health'=>'سلامت سیستم',
        'logs'=>'مشاهده لاگ‌ها',
        'admins'=>'مدیریت ادمین‌ها',
        'keyboards'=>'مدیریت کیبوردها',
        'channels'=>'مدیریت کانال‌ها',
    ];
}
function web_default_admin_permissions(){
    return ['dashboard','users','orders','tickets','gift_codes','texts','broadcast','health','logs'];
}
function web_admin_permissions($uid=null){
    $uid = $uid===null ? ($_SESSION['web_admin_id'] ?? '') : (string)$uid;
    $uid = preg_replace('/[^0-9]/','',$uid);
    if($uid !== '' && web_is_owner($uid)) return array_keys(web_permission_catalog());
    $acc = web_admin_account($uid);
    if(is_array($acc) && isset($acc['permissions']) && is_array($acc['permissions'])){
        $valid = array_keys(web_permission_catalog());
        return array_values(array_intersect($valid, array_map('strval', $acc['permissions'])));
    }
    return web_default_admin_permissions();
}
function web_can($perm, $uid=null){
    $perm = (string)$perm;
    $uid = $uid===null ? ($_SESSION['web_admin_id'] ?? '') : (string)$uid;
    if(web_is_owner($uid)) return true;
    return in_array($perm, web_admin_permissions($uid), true);
}
function web_require_perm($perm){
    web_require_login();
    if(!web_can($perm)){
        http_response_code(403);
        exit('به این بخش دسترسی نداری.');
    }
}
function web_nav_items(){
    return [
        'index.php'=>['داشبورد','dashboard'],
        'analytics.php'=>['آمار حرفه‌ای','dashboard'],
        'search.php'=>['جستجوی سریع','dashboard'],
        'users.php'=>['کاربران','users'],
        'orders.php'=>['سفارش‌ها','orders'],
        'payments-report.php'=>['گزارش پرداخت‌ها','orders'],
        'accounting.php'=>['حسابداری','orders'],
        'sponsor.php'=>['اسپانسر جوین','settings'],
        'reactions.php'=>['فروش ری‌اکشن','settings'],
        'forcedjoin-buttons.php'=>['دکمه‌های جوین','settings'],
        'tickets.php'=>['تیکت‌ها','tickets'],
        'canned-replies.php'=>['پاسخ‌های آماده','tickets'],
        'referrals.php'=>['گزارش رفرال','users'],
        'fraud.php'=>['ضدتقلب','users'],
        'left-penalty.php'=>['جریمه لفت','settings'],
        'gift-codes.php'=>['کد هدیه','gift_codes'],
        'keyboards.php'=>['کیبوردها','keyboards'],
        'channel-buttons.php'=>['دکمه‌های کانال','keyboards'],
        'channels.php'=>['کانال‌ها','channels'],
        'settings.php'=>['تنظیمات','settings'],
        'texts.php'=>['متن‌ها','texts'],
        'broadcast.php'=>['ارسال همگانی','broadcast'],
        'backups.php'=>['بکاپ','backups'],
        'health.php'=>['سلامت','health'],
        'logs.php'=>['لاگ‌ها','logs'],
        'admins.php'=>['ادمین‌ها','admins'],
    ];
}
function web_csrf(){ if(empty($_SESSION['csrf'])) $_SESSION['csrf'] = bin2hex(random_bytes(16)); return $_SESSION['csrf']; }

if (!function_exists('web_csrf_input')) {
    function web_csrf_input(){ echo '<input type="hidden" name="csrf" value="'.web_h(web_csrf()).'">'; }
}
function web_check_csrf(){ if($_SERVER['REQUEST_METHOD'] === 'POST'){ $ok = isset($_POST['csrf']) && hash_equals((string)($_SESSION['csrf'] ?? ''), (string)$_POST['csrf']); if(!$ok){ http_response_code(419); exit('درخواست معتبر نیست. صفحه را رفرش کن.'); } } }

function web_setting_get($key, $default=''){
    if(function_exists('bot_data_get_text')) return bot_data_get_text($key, $default);
    return is_file($key) ? (string)file_get_contents($key) : $default;
}
function web_setting_put($key, $value){
    if(function_exists('bot_data_put_raw') && function_exists('bot_storage_is_managed_path') && bot_storage_is_managed_path($key)) return bot_data_put_raw($key, (string)$value);
    $d=dirname($key); if($d && $d!=='.' && !is_dir($d)) @mkdir($d,0775,true); return file_put_contents($key, (string)$value, LOCK_EX) !== false;
}
function web_data_json($path, $default=[]){
    if(function_exists('bot_data_get_json')) return bot_data_get_json($path, $default);
    return is_file($path) ? (json_decode((string)file_get_contents($path), true) ?: $default) : $default;
}
function web_data_put_json($path, array $data){
    if(function_exists('bot_data_put_json')) return bot_data_put_json($path, $data);
    $d=dirname($path); if($d && $d!=='.' && !is_dir($d)) @mkdir($d,0775,true); return file_put_contents($path, json_encode($data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT), LOCK_EX)!==false;
}
function web_user_json($uid){
    $uid = preg_replace('/[^0-9]/','',(string)$uid);
    if($uid==='') return [];
    if(function_exists('bot_sql_user_get')) { $u = bot_sql_user_get($uid); if(is_array($u)) return $u; }
    if(function_exists('bot_data_get_json')) return bot_data_get_json('melat/'.$uid.'.json', []);
    return [];
}
function web_user_save($uid, array $data){
    if(function_exists('saveJson')) { saveJson('melat/'.preg_replace('/[^0-9]/','',(string)$uid).'.json', $data); return true; }
    return web_data_put_json('melat/'.preg_replace('/[^0-9]/','',(string)$uid).'.json', $data);
}
function web_points($u){ return (int)($u['Points'] ?? $u['points'] ?? $u['coin'] ?? 0); }
function web_set_points($uid, $points, $reason='web_admin', $actor=null){
    $before = 0; $after=(int)$points;
    if(function_exists('bot_wallet_add')){
        $u = web_user_json($uid); $before = web_points($u); return bot_wallet_add($uid, $after-$before, $reason, ['actor_id'=>$actor ?: ($_SESSION['web_admin_id'] ?? '')]);
    }
    $u=web_user_json($uid); $before=web_points($u); $u['Points']=$after; $u['points']=$after; web_user_save($uid,$u);
    if(function_exists('bot_ledger_record')) bot_ledger_record($uid,'diamond',$after-$before,$before,$after,$reason,['actor_id'=>$actor ?: ($_SESSION['web_admin_id'] ?? '')]);
    return ['ok'=>true,'before'=>$before,'after'=>$after];
}
function web_send_message($chatId, $text){
    if(function_exists('bot_adv_send_message_safe')){
        $r = bot_adv_send_message_safe($chatId, (string)$text, 'HTML');
        if(isset($r['response']) && is_object($r['response'])) return $r['response'];
        return (object)['ok'=>!empty($r['ok']), 'description'=>$r['error'] ?? 'unknown'];
    }
    if(function_exists('bot')){
        $res = bot('sendMessage', ['chat_id'=>(string)$chatId, 'text'=>(string)$text, 'parse_mode'=>'MarkDown']);
        if(is_object($res) && !empty($res->ok)) return $res;
        return bot('sendMessage', ['chat_id'=>(string)$chatId, 'text'=>(string)$text]);
    }
    return (object)['ok'=>false];
}

function web_admin_log($action, $targetType=null, $targetId=null, $desc='', $data=[]){
    if(function_exists('bot_admin_log')) return bot_admin_log($_SESSION['web_admin_id'] ?? '', $action, $targetType, $targetId, $desc, is_array($data)?$data:[]);
    return true;
}

web_check_csrf();
?>
