<?php
/**
 * iTzAYDiN-BOT Text Studio
 *
 * Telegram-native searchable text editor. It deliberately lives outside the
 * legacy elseif chain so adding/editing a text does not require another hard
 * coded handler for every textbot key.
 */

if (!function_exists('itz_textstudio_h')) {
    function itz_textstudio_h($v): string
    {
        return htmlspecialchars((string)$v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
    }
}

if (!function_exists('itz_textstudio_token')) {
    function itz_textstudio_token(string $key): string
    {
        return substr(hash('sha256', $key), 0, 18);
    }
}

if (!function_exists('itz_textstudio_resolve_key')) {
    function itz_textstudio_resolve_key(PDO $pdo, string $token): ?string
    {
        try {
            $stmt = $pdo->query("SELECT id_text FROM textbot");
            if (!$stmt) return null;
            while ($key = $stmt->fetchColumn()) {
                $key = (string)$key;
                if (hash_equals(itz_textstudio_token($key), $token)) return $key;
            }
        } catch (Throwable $e) {
            @error_log('[TextStudio resolve] ' . $e->getMessage());
        }
        return null;
    }
}

if (!function_exists('itz_textstudio_label')) {
    function itz_textstudio_label(string $key, string $value = ''): string
    {
        $labels = [
            'text_start' => 'پیام شروع',
            'text_usertest' => 'دکمه سرویس آزمایشی',
            'text_Purchased_services' => 'دکمه اشتراک‌های من',
            'text_support' => 'دکمه پشتیبانی',
            'text_help' => 'دکمه آموزش',
            'text_sell' => 'دکمه خرید اشتراک',
            'text_Add_Balance' => 'دکمه افزایش اعتبار',
            'text_Discount' => 'دکمه کد هدیه',
            'text_Tariff_list' => 'دکمه تعرفه‌ها',
            'text_dec_Tariff_list' => 'توضیحات تعرفه‌ها',
            'text_affiliates' => 'دکمه زیرمجموعه',
            'text_pishinvoice' => 'متن پیش‌فاکتور',
            'textafterpay' => 'پیام بعد از خرید',
            'textselectlocation' => 'پیام انتخاب لوکیشن',
            'text_cart' => 'متن کارت‌به‌کارت',
            'text_cart_auto' => 'متن کارت‌به‌کارت خودکار',
            'text_extend' => 'دکمه تمدید اشتراک',
            'text_wheel_luck' => 'دکمه گردونه شانس',
            'text_request_agent_dec' => 'توضیحات درخواست نمایندگی',
        ];
        if (isset($labels[$key])) return $labels[$key];

        $pretty = preg_replace('/^(text_|text)/i', '', $key);
        $pretty = str_replace(['_', '-'], ' ', (string)$pretty);
        $pretty = trim((string)preg_replace('/\s+/u', ' ', $pretty));
        if ($pretty === '') $pretty = $key;
        return $pretty;
    }
}

if (!function_exists('itz_textstudio_search')) {
    function itz_textstudio_search(PDO $pdo, string $query, int $limit = 18): array
    {
        $query = trim($query);
        $limit = max(1, min(30, $limit));
        try {
            if ($query === '' || $query === '*' || $query === 'همه') {
                $stmt = $pdo->query("SELECT id_text, text FROM textbot ORDER BY id_text ASC LIMIT {$limit}");
                return $stmt ? $stmt->fetchAll(PDO::FETCH_ASSOC) : [];
            }

            // Search the whole phrase and each meaningful token. This makes a
            // search like «خرید سرویس» find both purchase button and after-pay
            // messages even when the literal phrase is not present.
            $normalized = preg_replace('/[^\p{L}\p{N}_]+/u', ' ', $query);
            $tokens = preg_split('/\s+/u', trim((string)$normalized)) ?: [];
            $tokens = array_values(array_unique(array_filter($tokens, static fn($t) => mb_strlen($t, 'UTF-8') >= 2)));
            array_unshift($tokens, $query);
            $tokens = array_slice(array_values(array_unique($tokens)), 0, 6);

            $where = [];
            $params = [];
            foreach ($tokens as $i => $token) {
                // Do not reuse a named placeholder twice: native MySQL PDO
                // prepares reject duplicate names on some hosts.
                $phKey = ':qk' . $i;
                $phText = ':qt' . $i;
                $where[] = "(id_text LIKE {$phKey} OR text LIKE {$phText})";
                $params[$phKey] = '%' . $token . '%';
                $params[$phText] = '%' . $token . '%';
            }
            if (!$where) return [];
            $sql = "SELECT id_text, text FROM textbot WHERE " . implode(' OR ', $where)
                 . " ORDER BY CASE WHEN id_text LIKE :exact THEN 0 ELSE 1 END, id_text ASC LIMIT {$limit}";
            $params[':exact'] = '%' . $query . '%';
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
        } catch (Throwable $e) {
            @error_log('[TextStudio search] ' . $e->getMessage());
            return [];
        }
    }
}

if (!function_exists('itz_textstudio_utf16_slice')) {
    function itz_textstudio_utf16_slice(string $text, int $offset, int $length): string
    {
        if ($length <= 0) return '';
        try {
            if (function_exists('mb_convert_encoding')) {
                $u16 = mb_convert_encoding($text, 'UTF-16LE', 'UTF-8');
                $part = substr($u16, max(0, $offset) * 2, $length * 2);
                return (string)mb_convert_encoding($part, 'UTF-8', 'UTF-16LE');
            }
            if (function_exists('iconv')) {
                $u16 = iconv('UTF-8', 'UTF-16LE//IGNORE', $text);
                $part = substr((string)$u16, max(0, $offset) * 2, $length * 2);
                return (string)iconv('UTF-16LE', 'UTF-8//IGNORE', $part);
            }
        } catch (Throwable $e) {}
        return '';
    }
}

if (!function_exists('itz_textstudio_custom_emoji_pairs')) {
    function itz_textstudio_custom_emoji_pairs(array $message): array
    {
        $source = '';
        $entities = [];
        if (isset($message['text']) && is_string($message['text'])) {
            $source = $message['text'];
            $entities = is_array($message['entities'] ?? null) ? $message['entities'] : [];
        } elseif (isset($message['caption']) && is_string($message['caption'])) {
            $source = $message['caption'];
            $entities = is_array($message['caption_entities'] ?? null) ? $message['caption_entities'] : [];
        }
        if ($source === '' || !$entities) return [];

        $pairs = [];
        foreach ($entities as $entity) {
            if (!is_array($entity) || ($entity['type'] ?? '') !== 'custom_emoji') continue;
            $cid = trim((string)($entity['custom_emoji_id'] ?? ''));
            $offset = (int)($entity['offset'] ?? -1);
            $length = (int)($entity['length'] ?? 0);
            if ($cid === '' || $offset < 0 || $length <= 0) continue;
            $fallback = trim(itz_textstudio_utf16_slice($source, $offset, $length));
            if ($fallback === '') continue;
            $pairs[$fallback . '|' . $cid] = ['emoji' => $fallback, 'custom_emoji_id' => $cid];
        }
        return array_values($pairs);
    }
}

if (!function_exists('itz_textstudio_store_custom_emojis')) {
    function itz_textstudio_store_custom_emojis(PDO $pdo, array $pairs, string $label = ''): int
    {
        if (!$pairs) return 0;
        $saved = 0;
        try {
            $exists = $pdo->query("SHOW TABLES LIKE 'premium_emojis'");
            if (!$exists || $exists->fetchColumn() === false) return 0;
            $now = time();
            $sql = "INSERT INTO premium_emojis (emoji, custom_emoji_id, label, created_at, updated_at)
                    VALUES (:e,:c,:l,:t,:t)
                    ON DUPLICATE KEY UPDATE label=VALUES(label), updated_at=VALUES(updated_at)";
            $stmt = $pdo->prepare($sql);
            foreach ($pairs as $pair) {
                $emoji = trim((string)($pair['emoji'] ?? ''));
                $cid = trim((string)($pair['custom_emoji_id'] ?? ''));
                if ($emoji === '' || $cid === '') continue;
                $stmt->execute([':e' => $emoji, ':c' => $cid, ':l' => $label, ':t' => $now]);
                $saved++;
            }
            if ($saved > 0) {
                // "Send it and use it" behavior: detecting a custom emoji while
                // editing text automatically enables premium-emoji rendering.
                try { $pdo->exec("UPDATE setting SET premium_emoji_status='1'"); } catch (Throwable $e) {}
                if (function_exists('getPremiumEmojiMap')) getPremiumEmojiMap(true);
            }
        } catch (Throwable $e) {
            @error_log('[TextStudio premium emoji] ' . $e->getMessage());
        }
        return $saved;
    }
}

if (!function_exists('itz_textstudio_keyboard')) {
    function itz_textstudio_keyboard(array $rows, string $query = ''): string
    {
        $kb = ['inline_keyboard' => []];
        foreach ($rows as $row) {
            $key = (string)($row['id_text'] ?? '');
            if ($key === '') continue;
            $label = itz_textstudio_label($key, (string)($row['text'] ?? ''));
            $preview = trim(strip_tags((string)($row['text'] ?? '')));
            $preview = preg_replace('/\s+/u', ' ', (string)$preview);
            if (mb_strlen($preview, 'UTF-8') > 28) $preview = mb_substr($preview, 0, 28, 'UTF-8') . '…';
            $caption = '✏️ ' . $label . ($preview !== '' ? ' · ' . $preview : '');
            if (mb_strlen($caption, 'UTF-8') > 58) $caption = mb_substr($caption, 0, 58, 'UTF-8') . '…';
            $kb['inline_keyboard'][] = [[
                'text' => $caption,
                'callback_data' => 'itz_text_edit_' . itz_textstudio_token($key),
            ]];
        }
        $kb['inline_keyboard'][] = [
            ['text' => '🔎 جستجوی تازه', 'callback_data' => 'itz_text_search'],
            ['text' => '🌟 ایموجی‌های پریمیوم', 'callback_data' => 'premium_emoji_settings'],
        ];
        $kb['inline_keyboard'][] = [[
            'text' => '🏠 بازگشت به مدیریت', 'callback_data' => 'backadmin',
        ]];
        return json_encode($kb, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    }
}

if (!function_exists('itz_textstudio_home')) {
    function itz_textstudio_home($fromId): void
    {
        $kb = json_encode(['inline_keyboard' => [
            [['text' => '🔎 جستجو بین همه متن‌ها', 'callback_data' => 'itz_text_search']],
            [['text' => '📚 نمایش متن‌های اصلی', 'callback_data' => 'itz_text_all']],
            [['text' => '🌟 مدیریت ایموجی پریمیوم', 'callback_data' => 'premium_emoji_settings']],
            [['text' => '🏠 بازگشت به مدیریت', 'callback_data' => 'backadmin']],
        ]], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        nm_adminInstantReply($fromId,
            "🪄 <b>iTz Text Studio</b>\n\n"
            . "اسم یا موضوع متن را بفرست؛ مثلاً <code>خرید</code>، <code>پشتیبانی</code>، <code>تمدید</code> یا بخشی از خود جمله.\n\n"
            . "اگر هنگام ویرایش، <b>Premium Emoji</b> بفرستی، ربات آیدی همان ایموجی را از Entity تلگرام می‌خواند، ذخیره می‌کند و همان لحظه استفاده‌اش را فعال می‌کند. ✨",
            $kb, 'HTML');
    }
}

if (!function_exists('itz_textstudio_dispatch')) {
    /** Return true when this module consumed the current admin update. */
    function itz_textstudio_dispatch(): bool
    {
        global $pdo, $from_id, $datain, $text, $user, $update, $adminrulecheck, $callback_query_id;
        if (!isset($pdo) || !($pdo instanceof PDO) || !isset($from_id)) return false;
        if (isset($adminrulecheck) && is_array($adminrulecheck) && ($adminrulecheck['rule'] ?? '') !== 'administrator') return false;

        $cb = isset($datain) ? (string)$datain : '';
        $msgText = is_string($text ?? null) ? trim((string)$text) : '';
        $stepNow = is_array($user ?? null) ? (string)($user['step'] ?? '') : '';

        // Replace the legacy hard-coded text menu with the searchable studio.
        if ($msgText === '✍️ iTz Text Studio' || $cb === 'set_text' || $cb === 'itz_text_home') {
            if (function_exists('step')) step('home', $from_id);
            itz_textstudio_home($from_id);
            return true;
        }

        if ($cb === 'itz_text_search') {
            nm_adminInstantReply($from_id,
                "🔎 <b>جستجوی متن</b>\n\nموضوع، بخشی از متن یا کلید فنی را بفرست.\nمثال: <code>خرید</code> یا <code>textafterpay</code>",
                json_encode(['inline_keyboard' => [[['text' => '🔙 برگشت', 'callback_data' => 'itz_text_home']]]], JSON_UNESCAPED_UNICODE),
                'HTML');
            if (function_exists('step')) step('itz_text_search', $from_id);
            return true;
        }

        if ($cb === 'itz_text_all') {
            $rows = itz_textstudio_search($pdo, '*', 18);
            nm_adminInstantReply($from_id,
                "📚 <b>متن‌های اصلی ربات</b>\n\nیکی را برای ویرایش انتخاب کن؛ برای پیدا کردن موارد بیشتر از جستجو استفاده کن.",
                itz_textstudio_keyboard($rows, '*'), 'HTML');
            return true;
        }

        if (preg_match('/^itz_text_edit_([a-f0-9]{18})$/', $cb, $m)) {
            $key = itz_textstudio_resolve_key($pdo, $m[1]);
            if ($key === null) {
                nm_adminInstantReply($from_id, "❌ این متن پیدا نشد؛ یک‌بار دوباره جستجو کن.", null, 'HTML');
                return true;
            }
            $stmt = $pdo->prepare("SELECT text FROM textbot WHERE id_text=:k LIMIT 1");
            $stmt->execute([':k' => $key]);
            $current = (string)($stmt->fetchColumn() ?: '');
            if (function_exists('update')) update('user', 'Processing_value', $key, 'id', $from_id);
            if (function_exists('step')) step('itz_text_update', $from_id);
            $label = itz_textstudio_label($key, $current);
            nm_adminInstantReply($from_id,
                "✏️ <b>ویرایش {$label}</b>\n"
                . "<code>" . itz_textstudio_h($key) . "</code>\n\n"
                . "<b>نسخه فعلی:</b>\n<blockquote>" . itz_textstudio_h($current) . "</blockquote>\n"
                . "نسخه جدید را همین‌جا بفرست. HTML و متغیرهای داخل <code>{ }</code> حفظ می‌شوند. Premium Emoji هم مستقیم قابل ارسال است.",
                json_encode(['inline_keyboard' => [[['text' => '❌ لغو', 'callback_data' => 'itz_text_home']]]], JSON_UNESCAPED_UNICODE),
                'HTML');
            return true;
        }

        if ($stepNow === 'itz_text_search' && $cb === '' && $msgText !== '') {
            $rows = itz_textstudio_search($pdo, $msgText, 22);
            if (!$rows) {
                nm_adminInstantReply($from_id,
                    "چیزی با موضوع <b>" . itz_textstudio_h($msgText) . "</b> پیدا نکردم. یک کلمه کوتاه‌تر امتحان کن؛ مثلاً «خرید» یا «پشتیبانی».",
                    json_encode(['inline_keyboard' => [[['text' => '🔎 جستجوی دوباره', 'callback_data' => 'itz_text_search'], ['text' => '🔙 برگشت', 'callback_data' => 'itz_text_home']]]], JSON_UNESCAPED_UNICODE),
                    'HTML');
                return true;
            }
            if (function_exists('step')) step('home', $from_id);
            nm_adminInstantReply($from_id,
                "🔎 برای <b>" . itz_textstudio_h($msgText) . "</b>، <b>" . count($rows) . "</b> نتیجه پیدا شد:\n\nمتنی را که می‌خواهی تغییر بدهی انتخاب کن.",
                itz_textstudio_keyboard($rows, $msgText), 'HTML');
            return true;
        }

        if ($stepNow === 'itz_text_update' && $cb === '') {
            $key = is_array($user ?? null) ? trim((string)($user['Processing_value'] ?? '')) : '';
            $message = is_array($update['message'] ?? null) ? $update['message'] : [];
            $newText = '';
            if (isset($message['text']) && is_string($message['text'])) $newText = $message['text'];
            elseif (isset($message['caption']) && is_string($message['caption'])) $newText = $message['caption'];
            elseif (is_string($text ?? null)) $newText = (string)$text;

            if ($key === '' || $newText === '') {
                nm_adminInstantReply($from_id, "❌ متن خالی ذخیره نمی‌شود. متن جدید را بفرست یا لغو کن.", null, 'HTML');
                return true;
            }
            try {
                $check = $pdo->prepare("SELECT 1 FROM textbot WHERE id_text=:k LIMIT 1");
                $check->execute([':k' => $key]);
                if (!$check->fetchColumn()) throw new RuntimeException('کلید متن دیگر وجود ندارد.');
                $save = $pdo->prepare("UPDATE textbot SET text=:v WHERE id_text=:k");
                $save->execute([':v' => $newText, ':k' => $key]);
                $pairs = itz_textstudio_custom_emoji_pairs($message);
                $emojiCount = itz_textstudio_store_custom_emojis($pdo, $pairs, $key);
                if (function_exists('step')) step('home', $from_id);
                $extra = $emojiCount > 0
                    ? "\n\n🌟 <b>{$emojiCount} Premium Emoji</b> هم خودکار ذخیره و فعال شد."
                    : '';
                nm_adminInstantReply($from_id,
                    "✅ <b>متن ذخیره شد.</b>\n\n"
                    . "بخش: <b>" . itz_textstudio_h(itz_textstudio_label($key, $newText)) . "</b>"
                    . $extra,
                    json_encode(['inline_keyboard' => [[['text' => '🔎 ویرایش متن دیگر', 'callback_data' => 'itz_text_search']], [['text' => '🪄 Text Studio', 'callback_data' => 'itz_text_home']]]], JSON_UNESCAPED_UNICODE),
                    'HTML');
            } catch (Throwable $e) {
                @error_log('[TextStudio save] ' . $e->getMessage());
                nm_adminInstantReply($from_id, "❌ ذخیره انجام نشد: <code>" . itz_textstudio_h($e->getMessage()) . "</code>", null, 'HTML');
            }
            return true;
        }

        return false;
    }
}
