<?php
/**
 * Accurate admin member statistics for Telegram.
 * Old code used melat.json['members'] as active members; that value was the
 * success count of the last broadcast. This file tracks real known-inactive
 * users only when Telegram returns permanent delivery errors.
 */

if(!function_exists('bot_stats_abs_path')){
function bot_stats_abs_path($path){
    $path = (string)$path;
    if($path !== '' && $path[0] === '/') return $path;
    $root = defined('BOT_ROOT_DIR') ? BOT_ROOT_DIR : getcwd();
    return rtrim((string)$root, '/').'/'.$path;
}
}

if(!function_exists('bot_stats_status_file')){
function bot_stats_status_file(){ return 'lib/kodam/user_status.json'; }
}

if(!function_exists('bot_stats_load_status')){
function bot_stats_load_status(){
    if(function_exists('bot_data_get_json')){
        $data = bot_data_get_json(bot_stats_status_file(), []);
    }else{
        $p = bot_stats_abs_path(bot_stats_status_file());
        $data = is_file($p) ? json_decode((string)@file_get_contents($p), true) : [];
    }
    return is_array($data) ? $data : [];
}
}

if(!function_exists('bot_stats_save_status')){
function bot_stats_save_status($data){
    if(!is_array($data)) $data = [];
    if(function_exists('bot_data_put_json')) return bot_data_put_json(bot_stats_status_file(), $data);
    $p = bot_stats_abs_path(bot_stats_status_file());
    $dir = dirname($p);
    if($dir && !is_dir($dir)) @mkdir($dir, 0775, true);
    return @file_put_contents($p, json_encode($data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT), LOCK_EX) !== false;
}
}

if(!function_exists('bot_stats_clean_user_id')){
function bot_stats_clean_user_id($id){
    $id = preg_replace('/[^0-9]/', '', (string)$id);
    return $id === '' ? '' : $id;
}
}

if(!function_exists('bot_stats_mark_active')){
function bot_stats_mark_active($userId, $source='interaction'){
    $uid = bot_stats_clean_user_id($userId);
    if($uid === '' || $uid === '0') return false;
    $data = bot_stats_load_status();
    if(!isset($data['users']) || !is_array($data['users'])) $data['users'] = [];
    $old = isset($data['users'][$uid]) && is_array($data['users'][$uid]) ? $data['users'][$uid] : [];
    $data['users'][$uid] = array_merge($old, [
        'status' => 'active',
        'last_ok_at' => time(),
        'last_seen_at' => time(),
        'last_source' => (string)$source,
        'last_error' => '',
    ]);
    $data['updated_at'] = time();
    return bot_stats_save_status($data);
}
}

if(!function_exists('bot_stats_mark_inactive')){
function bot_stats_mark_inactive($userId, $reason='delivery_failed'){
    $uid = bot_stats_clean_user_id($userId);
    if($uid === '' || $uid === '0') return false;
    $data = bot_stats_load_status();
    if(!isset($data['users']) || !is_array($data['users'])) $data['users'] = [];
    $old = isset($data['users'][$uid]) && is_array($data['users'][$uid]) ? $data['users'][$uid] : [];
    $data['users'][$uid] = array_merge($old, [
        'status' => 'inactive',
        'inactive_at' => time(),
        'last_error' => (string)$reason,
        'last_source' => 'telegram_delivery',
    ]);
    $data['updated_at'] = time();
    return bot_stats_save_status($data);
}
}

if(!function_exists('bot_stats_is_permanent_delivery_failure')){
function bot_stats_is_permanent_delivery_failure($res){
    if(!is_object($res) || !isset($res->ok) || $res->ok) return false;
    $desc = strtolower((string)($res->description ?? ''));
    if($desc === '') return false;
    $needles = [
        'bot was blocked by the user',
        'user is deactivated',
        'chat not found',
        'forbidden: bot was blocked',
        'forbidden: user is deactivated',
        'forbidden: bot can\'t initiate conversation',
        'forbidden: bot cannot initiate conversation',
        'forbidden: user not found',
    ];
    foreach($needles as $n){ if(strpos($desc, $n) !== false) return true; }
    return false;
}
}

if(!function_exists('bot_stats_user_ids_from_sql')){
function bot_stats_user_ids_from_sql(){
    if(!function_exists('bot_sql_pdo')) return [];
    $pdo = bot_sql_pdo();
    if(!$pdo) return [];
    try{
        $rows = $pdo->query("SELECT user_id FROM bot_users WHERE user_id REGEXP '^[0-9]+$' AND user_id <> '0'")->fetchAll(PDO::FETCH_COLUMN);
        $out = [];
        foreach((array)$rows as $id){ $id = bot_stats_clean_user_id($id); if($id !== '') $out[] = $id; }
        return array_values(array_unique($out));
    }catch(Throwable $e){ return []; }
}
}

if(!function_exists('bot_stats_user_ids_from_files')){
function bot_stats_user_ids_from_files(){
    $pattern = bot_stats_abs_path('melat/*.json');
    $files = glob($pattern) ?: [];
    $out = [];
    foreach($files as $f){
        $base = basename((string)$f, '.json');
        $id = bot_stats_clean_user_id($base);
        if($id !== '') $out[] = $id;
    }
    return array_values(array_unique($out));
}
}

if(!function_exists('bot_stats_all_user_ids')){
function bot_stats_all_user_ids(){
    $ids = bot_stats_user_ids_from_sql();
    $fileIds = bot_stats_user_ids_from_files();
    if($fileIds) $ids = array_merge($ids, $fileIds);
    return array_values(array_unique(array_filter(array_map('bot_stats_clean_user_id', $ids))));
}
}

if(!function_exists('bot_stats_summary')){
function bot_stats_summary(){
    $ids = bot_stats_all_user_ids();
    $total = count($ids);
    $idSet = array_fill_keys($ids, true);
    $status = bot_stats_load_status();
    $users = isset($status['users']) && is_array($status['users']) ? $status['users'] : [];
    $inactive = 0;
    $inactiveIds = [];
    foreach($users as $uid=>$row){
        $uid = bot_stats_clean_user_id($uid);
        if($uid === '' || !isset($idSet[$uid])) continue;
        if(is_array($row) && ($row['status'] ?? '') === 'inactive'){
            $inactive++;
            $inactiveIds[] = $uid;
        }
    }
    $active = max(0, $total - $inactive);
    return [
        'total' => $total,
        'active' => $active,
        'inactive' => $inactive,
        'inactive_ids' => $inactiveIds,
        'status_updated_at' => (int)($status['updated_at'] ?? 0),
    ];
}
}

if(!function_exists('bot_stats_admin_text')){
function bot_stats_admin_text(){
    $s = bot_stats_summary();
    return "👤تعداد ممبر ها : ".number_format((int)$s['total'])."\n".
           "✅اعضای فعال : ".number_format((int)$s['active'])."\n".
           "☑️اعضای غیر فعال : ".number_format((int)$s['inactive'])."\n\n".
           "ℹ️ اعضای غیرفعال فقط کسانی هستند که تلگرام برایشان خطای قطعی مثل بلاک‌کردن ربات، حذف حساب یا chat not found داده است. عدد ارسال همگانی ناقص دیگر غیرفعال حساب نمی‌شود.";
}
}
