<?php
// admin/voucher_redeem.php
// صفحة عامة (بدون تسجيل دخول) لقراءة QR وتفعيل الكرت بعد الدفع.

require_once __DIR__ . '/db_bootstrap.php';
require_once __DIR__ . '/helpers.php';
require_once __DIR__ . '/vouchers_lib.php';
require_once __DIR__ . '/mikrotik_lib.php';

$conn = ensure_db(true);
vouchers_ensure_tables($conn);


if (!function_exists('voucher_public_shell')) {
    function voucher_public_shell(string $title, string $html, int $status = 200): void {
        http_response_code($status);
        echo '<!doctype html><html lang="ar" dir="rtl"><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>' . h($title) . '</title>';
        $ua_public_css_v = @filemtime(__DIR__ . '/assets/css/ua_program_unified.css') ?: 1;
        echo '<link rel="stylesheet" href="assets/css/ua_program_unified.css?v=' . (int)$ua_public_css_v . '">';
        echo '<body class="public-entry-page ua-public-special-page ua-voucher-redeem-page"><div class="ua-public-shell">' . $html . '</div></body></html>';
        exit;
    }
}

$t = trim((string)($_GET['t'] ?? ''));
if ($t === '') {
    voucher_public_shell('Voucher', '<h2>رمز QR غير صالح.</h2><div class="muted">الرابط أو الرمز المرسل غير مكتمل.</div>', 400);
}

$stmt = $conn->prepare("SELECT * FROM vouchers WHERE qr_token=? LIMIT 1");
$stmt->bind_param('s', $t);
$stmt->execute();
$res = $stmt->get_result();
$v = $res ? $res->fetch_assoc() : null;
$stmt->close();

if (!$v) {
    voucher_public_shell('Voucher', '<h2>الكرت غير موجود.</h2><div class="muted">تحقق من الرابط أو أعد طلب الكرت من نقطة البيع.</div>', 404);
}

$paid_only = get_app_setting($conn,'voucher_qr_paid_only','1');
$paid = (!empty($v['payment_id']) || (($v['status'] ?? '') === 'used') || (($v['status'] ?? '') === 'sold' && $paid_only !== '1'));

// إذا المطلوب: لا يعمل قبل الدفع
if ($paid_only === '1' && empty($v['payment_id']) && (($v['status'] ?? '') !== 'used')) {
    voucher_public_shell(
        'Voucher',
        '<h2>هذا الكرت غير مُفعّل بعد</h2>'
        . '<div class="notice notice-danger">يرجى الدفع في نقطة البيع ليصبح الكرت فعّالاً.</div>'
        . '<div class="muted ua-u-mt-12">الكود: <b>' . h($v['code']) . '</b></div>'
    );
}

// سجل أول Scan (مرة واحدة)
if (empty($v['qr_redeemed_at'])) {
    $up = $conn->prepare("UPDATE vouchers SET qr_redeemed_at=NOW() WHERE id=? AND qr_redeemed_at IS NULL");
    $id = (int)$v['id'];
    $up->bind_param('i', $id);
    @$up->execute();
    @$up->close();
    vouchers_log($conn, (int)$v['id'], 'qr_redeem', ['ip'=>($_SERVER['REMOTE_ADDR'] ?? '')]);
}

// خيار: تفعيل تلقائي على MikroTik عند أول Scan بعد الدفع
$auto_mt_on_redeem = get_app_setting($conn,'voucher_auto_mt_on_redeem','1');
$single_device = get_app_setting($conn,'voucher_single_device','1');
$profile_name = get_app_setting($conn,'voucher_hotspot_profile','voucher');
$device_lock_enabled = get_app_setting($conn,'voucher_device_lock_enabled','1');
$device_lock_steps = get_app_setting($conn,'voucher_device_lock_steps','1,5,10,30');
$wallclock_enabled = (get_app_setting($conn,'voucher_time_wallclock','1') === '1');

function mt_build_on_login_script(bool $wallclock_enabled, bool $single_device, bool $device_lock_enabled, string $steps_csv): string {
    if (!$wallclock_enabled && !$single_device) return '';

    // sanitize steps (minutes) for device lock
    $steps = array_values(array_filter(array_map('trim', explode(',', $steps_csv)), fn($x)=>$x!==''));
    $mins = [];
    foreach ($steps as $s) {
        if (preg_match('/^\d+$/', $s)) {
            $n = (int)$s;
            if ($n > 0 && $n <= 240) $mins[] = (string)$n;
        }
    }
    if (!$mins) $mins = ['1','5','10','30'];
    $arr = '{"' . implode('";"', $mins) . '"}';

    // RouterOS on-login script:
    // - Wallclock validity for vouchers: uses comment tags "durm=<minutes> start=1 rem=<minutes>"
    //   Creates scheduler vexp-<user> that decrements rem each minute even if user disconnects.
    // - Single device bind: binds first MAC; if mismatch and device_lock_enabled -> temporary disable with escalating minutes.
    $script = ':local u $user; :local m $mac; :local id [/ip hotspot user find name=$u];'
        . ' :if ([:len $id] = 0) do={ :return; }'
        . ' :local c [/ip hotspot user get $id comment];';

    if ($wallclock_enabled) {
        $script .= ' :local pd [:find $c "durm="];'
            . ' :if ($pd != nil) do={'
            . '   :local started ([:find $c "start=1"] != nil);'
            . '   :if (!$started) do={'
            . '     :local rest [:pick $c ($pd+5) [:len $c]]; :local sp [:find $rest " "]; :if ($sp != nil) do={ :set rest [:pick $rest 0 $sp]; }'
            . '     :local dur [:tonum $rest];'
            . '     :if ($dur > 0) do={'
            . '       /ip hotspot user set $id comment=($c . " start=1 rem=" . $dur);'
            . '       :local s ("vexp-" . $u);'
            . '       /system scheduler remove [find name=$s];'
            . '       /system scheduler add name=$s interval=1m on-event=('
            . '         ":local u \\"".$u."\\"; :local s \\"vexp-".$u."\\"; :local id [/ip hotspot user find name=$u];'
            . '          :if ([:len $id]=0) do={ /system scheduler remove [find name=$s]; :return; };'
            . '          :local c [/ip hotspot user get $id comment]; :local pr [:find $c \\"rem=\\"];'
            . '          :if ($pr = nil) do={ /system scheduler remove [find name=$s]; :return; };'
            . '          :local r [:pick $c ($pr+4) [:len $c]]; :local sp [:find $r \\" \\\"]; :if ($sp != nil) do={ :set r [:pick $r 0 $sp]; };'
            . '          :local rem [:tonum $r]; :set rem ($rem-1);'
            . '          :if ($rem <= 0) do={ /ip hotspot active remove [find user=$u]; /ip hotspot cookie remove [find user=$u]; /ip hotspot user disable $id; /system scheduler remove [find name=$s]; }'
            . '          else={'
            . '            :local pre [:pick $c 0 ($pr+4)]; :local rest2 [:pick $c ($pr+4) [:len $c]]; :local sp2 [:find $rest2 \\" \\\"]; :local suf \\"\\"; :if ($sp2 != nil) do={ :set suf [:pick $rest2 $sp2 [:len $rest2]]; };'
            . '            /ip hotspot user set $id comment=($pre . $rem . $suf);'
            . '          }"'
            . '       );'
            . '     }'
            . '   }'
            . ' };';
    }

    if ($single_device) {
        $script .= ' :local cur [/ip hotspot user get $id mac-address];'
            . ' :if ([:len $cur] = 0) do={ /ip hotspot user set $id mac-address=$m; }';
        if ($device_lock_enabled) {
            $script .= ' else={ :if ($cur != $m) do={'
                . ' :local c [/ip hotspot user get $id comment]; :local v 0;'
                . ' :local p [:find $c "viol="];'
                . ' :if ($p != nil) do={ :local rest [:pick $c ($p+5) [:len $c]]; :local sp [:find $rest " "]; :if ($sp != nil) do={ :set rest [:pick $rest 0 $sp]; } :set v [:tonum $rest]; }'
                . ' :set v ($v+1);'
                . ' :local pre $c;'
                . ' :if ($p != nil) do={ :set pre [:pick $c 0 $p]; :local rest2 [:pick $c ($p+5) [:len $c]]; :local sp2 [:find $rest2 " "]; :local suf ""; :if ($sp2 != nil) do={ :set suf [:pick $rest2 $sp2 [:len $rest2]]; } :set c ($pre . "viol=" . $v . $suf); } else={ :set c ($c . " viol=" . $v); }'
                . ' /ip hotspot user set $id comment=$c;'
                . ' :local steps ' . $arr . ';'
                . ' :local idx ($v-1); :if ($idx < 0) do={ :set idx 0; } :if ($idx >= [:len $steps]) do={ :set idx ([:len $steps]-1); }'
                . ' :local mins ($steps->$idx); :local mm $mins; :if ([:len $mm] = 1) do={ :set mm ("0".$mm); }'
                . ' :local interval ("00:".$mm.":00"); :local s ("unlock-".$u);'
                . ' /system scheduler remove [find name=$s];'
                . ' /ip hotspot active remove [find user=$u]; /ip hotspot cookie remove [find user=$u];'
                . ' /ip hotspot user disable $id;'
                . ' /system scheduler add name=$s interval=$interval on-event=("/ip hotspot user enable [find name=\\\"".$u."\\\"]; /system scheduler remove [find name=\\\"".$s."\\\"]; ");'
                . ' } };';
        }
        $script .= ' };';
    }

    return $script;
}

function mt_ensure_voucher_profile($api, string $profile_name, bool $wallclock_enabled, bool $single_device, bool $device_lock_enabled, string $steps_csv): void {
    $profile_name = trim($profile_name);
    if ($profile_name === '') $profile_name = 'voucher';

    $onLogin = mt_build_on_login_script($wallclock_enabled, $single_device, $device_lock_enabled, $steps_csv);

    $exists = $api->command(['/ip/hotspot/user/profile/print', '?name=' . $profile_name]);
    $found_id = null;
    foreach ($exists as $r) {
        if (($r['.type'] ?? '') === '!re' && isset($r['.id'])) { $found_id = $r['.id']; break; }
    }

    if ($found_id !== null) {
        $cmd = ['/ip/hotspot/user/profile/set', '=.id=' . $found_id];
        if ($single_device) {
            $cmd[] = '=shared-users=1';
            if ($onLogin !== '') $cmd[] = '=on-login=' . $onLogin;
        }
        $api->command($cmd);
        return;
    }

    $cmd = ['/ip/hotspot/user/profile/add', '=name=' . $profile_name];
    if ($single_device) $cmd[] = '=shared-users=1';
    if ($onLogin !== '') $cmd[] = '=on-login=' . $onLogin;
    $api->command($cmd);
}

// إنشاء مستخدم Hotspot إن لم يكن موجود
if ($auto_mt_on_redeem === '1') {
    $username = $v['mt_username'] ?: $v['code'];
    $password = $v['mt_password'] ?: $v['passcode'];
    try {
        $api = mt_api_connect($conn);
        try {
            mt_ensure_voucher_profile($api, $profile_name, $wallclock_enabled, ($single_device==='1'), ($device_lock_enabled==='1'), (string)$device_lock_steps);

            $exists = $api->command(['/ip/hotspot/user/print', '?name=' . $username]);
            $found = false;
            foreach ($exists as $r) { if (($r['.type'] ?? '') === '!re') { $found = true; break; } }

            if (!$found) {
                $comment = 'voucher:' . $v['code'];
                $rate = trim((string)$v['rate_limit']);
                $limit_uptime = null;
                if (!empty($v['duration_minutes'])) {
                    $mins = (int)$v['duration_minutes'];
                    $days = intdiv($mins, 1440); $mins -= $days*1440;
                    $hours = intdiv($mins, 60); $mins -= $hours*60;
                    $parts = [];
                    if ($days>0) $parts[] = $days . 'd';
                    if ($hours>0) $parts[] = $hours . 'h';
                    if ($mins>0) $parts[] = $mins . 'm';
                    $limit_uptime = $parts ? implode('', $parts) : null;
                }
                $limit_bytes = null;
                if (!empty($v['data_bytes'])) $limit_bytes = (string)((int)$v['data_bytes']);

                $cmd = ['/ip/hotspot/user/add', '=name=' . $username, '=password=' . $password, '=comment=' . $comment, '=profile=' . $profile_name];
                if ($rate !== '') $cmd[] = '=rate-limit=' . $rate;
                if ($limit_uptime) $cmd[] = '=limit-uptime=' . $limit_uptime;
                if ($limit_bytes) $cmd[] = '=limit-bytes-total=' . $limit_bytes;
                $api->command($cmd);
                vouchers_log($conn, (int)$v['id'], 'mt_hotspot_user', ['username'=>$username,'profile'=>$profile_name,'via'=>'redeem']);
            }
        } finally {
            $api->disconnect();
        }
    } catch (Throwable $e) {
        // لا نمنع المستخدم من رؤية البيانات لو فشل الربط
        vouchers_log($conn, (int)$v['id'], 'mt_error', ['msg'=>$e->getMessage()]);
    }

    // حفظ mt_username/mt_password لو لم تكن محفوظة
    if (empty($v['mt_username']) || empty($v['mt_password'])) {
        $u = $conn->prepare("UPDATE vouchers SET mt_username=?, mt_password=? WHERE id=?");
        $uid = (int)$v['id'];
        $un = $v['mt_username'] ?: $v['code'];
        $pw = $v['mt_password'] ?: $v['passcode'];
        $u->bind_param('ssi', $un, $pw, $uid);
        @$u->execute();
        @$u->close();
    }
}

// محتوى QR بعد الدفع: يظهر بيانات الدخول أو يوجه لرابط الهوتسبوت
$qr_mode = get_app_setting($conn,'voucher_qr_mode','code_pass');
$qr_hotspot_url = get_app_setting($conn,'voucher_qr_hotspot_url','');

$username = h($v['mt_username'] ?: $v['code']);
$password = h($v['mt_password'] ?: $v['passcode']);

$hotspotLink = '';
if ($qr_mode === 'hotspot_url' && trim($qr_hotspot_url) !== '') {
    $sep = (strpos($qr_hotspot_url,'?') !== false) ? '&' : '?';
    $hotspotLink = trim($qr_hotspot_url) . $sep . 'username=' . rawurlencode($v['code']) . '&password=' . rawurlencode($v['passcode']);
}

$voucherHtml = '';
$voucherHtml .= '<h2>الكرت فعّال ✅</h2>';
$voucherHtml .= '<div class="notice notice-success">يمكنك الآن تسجيل الدخول على شبكة الهوتسبوت.</div>';
$voucherHtml .= '<div class="ua-voucher-result-data">';
$voucherHtml .= 'Username: <b><code>' . $username . '</code></b><br>';
$voucherHtml .= 'Password: <b><code>' . $password . '</code></b>';
$voucherHtml .= '</div>';
if ($single_device === '1') {
    $voucherHtml .= '<div class="muted ua-u-mt-10">ملاحظة: هذا الكرت يعمل على <b>جهاز واحد فقط</b> (يُربط بأول جهاز يسجل الدخول تلقائيًا).</div>';
}
if ($hotspotLink) {
    $voucherHtml .= '<div class="ua-voucher-link-row"><a href="' . h($hotspotLink) . '" class="ua-voucher-login-link">فتح صفحة الدخول</a></div>';
}
voucher_public_shell('Voucher', $voucherHtml);
