<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;

function Mirai_levelEnabled() {
    $options = Mirai_opt();
    return isset($options->levelEnable) && $options->levelEnable === '1';
}

function Mirai_levelGetMax() {
    $options = Mirai_opt();
    return isset($options->levelMax) ? min(30, max(3, (int)$options->levelMax)) : 10;
}

function Mirai_levelGet($uid = 0) {
    if (!$uid) {
        $user = Mirai_user();
        if (!$user->hasLogin()) return 1;
        $uid = $user->uid;
    }
    $db = \Typecho\Db::get();
    $row = $db->fetchRow($db->select('level')->from('table.users')->where('uid = ?', $uid));
    $level = (int)($row['level'] ?? 1);
    $max = Mirai_levelGetMax();
    return min($level, $max);
}

function Mirai_levelSet($uid, $level) {
    $db = \Typecho\Db::get();
    $max = Mirai_levelGetMax();
    $level = min(max(1, $level), $max);
    $db->query($db->update('table.users')->rows(['level' => $level])->where('uid = ?', $uid));
    return $level;
}

function Mirai_levelGetName($level) {
    $options = Mirai_opt();
    $prefix = isset($options->levelNamePrefix) && $options->levelNamePrefix !== '' ? $options->levelNamePrefix : 'LV';
    return $prefix . $level;
}

function Mirai_levelGetIcon($level) {
    return '';
}

function Mirai_levelGetExpThreshold($level) {
    if ($level <= 1) return 0;
    $options = Mirai_opt();
    $field = 'levelExp_' . $level;
    if (isset($options->$field) && (int)$options->$field > 0) {
        return (int)$options->$field;
    }
    return ($level - 1) * 500 * $level;
}

function Mirai_levelGetAllLevels() {
    $max = Mirai_levelGetMax();
    $levels = [];
    for ($i = 1; $i <= $max; $i++) {
        $levels[$i] = [
            'level' => $i,
            'name' => Mirai_levelGetName($i),
            'icon' => Mirai_levelGetIcon($i),
            'exp_threshold' => Mirai_levelGetExpThreshold($i),
        ];
    }
    return $levels;
}

function Mirai_levelCheckUpgrade($uid) {
    $db = \Typecho\Db::get();
    $row = $db->fetchRow($db->select('level', 'exp')->from('table.users')->where('uid = ?', $uid));
    if (!$row) return ['upgraded' => false];

    $currentLevel = (int)$row['level'];
    $currentExp = (int)$row['exp'];
    $max = Mirai_levelGetMax();
    $newLevel = $currentLevel;

    if ($currentExp >= Mirai_levelGetExpThreshold($max)) {
        $newLevel = $max;
    } else {
        for ($i = $currentLevel; $i <= $max; $i++) {
            $threshold = Mirai_levelGetExpThreshold($i);
            $nextThreshold = Mirai_levelGetExpThreshold($i + 1);
            if ($currentExp >= $threshold && ($nextThreshold == 0 || $currentExp < $nextThreshold)) {
                $newLevel = $i;
                break;
            }
        }
    }

    $upgraded = $newLevel > $currentLevel;
    if ($upgraded) {
        Mirai_levelSet($uid, $newLevel);
    }

    return [
        'upgraded' => $upgraded,
        'level_before' => $currentLevel,
        'level_after' => $newLevel,
        'exp' => $currentExp,
    ];
}
