<?php

/**
 * Load / save customizable bot messages (mainValues, buttonValues).
 * Defaults live in settings/values.php; overrides in setting.type = BOT_TEXTS.
 */
class BotTexts
{
    public const SETTING_TYPE = 'BOT_TEXTS';

    /** @var array{mainValues:array<string,string>,buttonValues:array<string,string>}|null */
    private static $defaults;

    /** @param array<string, string> $mainValues @param array<string, string> $buttonValues */
    public static function apply(array &$mainValues, array &$buttonValues, mysqli $connection): void
    {
        $custom = self::load($connection);
        if (!empty($custom['mainValues']) && is_array($custom['mainValues'])) {
            $mainValues = array_merge($mainValues, $custom['mainValues']);
        }
        if (!empty($custom['buttonValues']) && is_array($custom['buttonValues'])) {
            foreach ($custom['buttonValues'] as $key => $value) {
                if (trim((string) $value) !== '') {
                    $buttonValues[$key] = (string) $value;
                }
            }
        }
    }

    /** @return array{mainValues:array<string,string>,buttonValues:array<string,string>} */
    public static function load(mysqli $connection): array
    {
        $stmt = $connection->prepare('SELECT `value` FROM `setting` WHERE `type` = ? LIMIT 1');
        $type = self::SETTING_TYPE;
        $stmt->bind_param('s', $type);
        $stmt->execute();
        $row = $stmt->get_result()->fetch_assoc();
        $stmt->close();
        if (!$row || empty($row['value'])) {
            return ['mainValues' => [], 'buttonValues' => []];
        }
        $decoded = json_decode($row['value'], true);
        if (!is_array($decoded)) {
            return ['mainValues' => [], 'buttonValues' => []];
        }
        return [
            'mainValues' => is_array($decoded['mainValues'] ?? null) ? $decoded['mainValues'] : [],
            'buttonValues' => is_array($decoded['buttonValues'] ?? null) ? $decoded['buttonValues'] : [],
        ];
    }

    /** @return array{mainValues:array<string,string>,buttonValues:array<string,string>} */
    public static function defaults(): array
    {
        if (self::$defaults !== null) {
            return self::$defaults;
        }
        $mainValues = [];
        $buttonValues = [];
        include __DIR__ . '/../settings/values.php';
        self::$defaults = [
            'mainValues' => is_array($mainValues) ? $mainValues : [],
            'buttonValues' => is_array($buttonValues) ? $buttonValues : [],
        ];
        return self::$defaults;
    }

    /** @return array<string, array{title:string,group:string,keys:array<string,string>}> */
    public static function categories(): array
    {
        return require __DIR__ . '/../settings/bot_text_labels.php';
    }

    public static function groupToField(string $groupCode): string
    {
        return $groupCode === 'b' ? 'buttonValues' : 'mainValues';
    }

    public static function getText(mysqli $connection, string $groupCode, string $key): string
    {
        $field = self::groupToField($groupCode);
        $custom = self::load($connection);
        if (isset($custom[$field][$key])) {
            return (string) $custom[$field][$key];
        }
        $defaults = self::defaults();
        return (string) ($defaults[$field][$key] ?? '');
    }

    public static function saveText(mysqli $connection, string $groupCode, string $key, string $value): void
    {
        $field = self::groupToField($groupCode);
        $data = self::load($connection);
        $data[$field][$key] = $value;
        self::persist($connection, $data);
    }

    public static function resetText(mysqli $connection, string $groupCode, string $key): void
    {
        $field = self::groupToField($groupCode);
        $data = self::load($connection);
        unset($data[$field][$key]);
        self::persist($connection, $data);
    }

    public static function resetAll(mysqli $connection): void
    {
        $stmt = $connection->prepare('DELETE FROM `setting` WHERE `type` = ?');
        $type = self::SETTING_TYPE;
        $stmt->bind_param('s', $type);
        $stmt->execute();
        $stmt->close();
    }

    /** @param array{mainValues:array<string,string>,buttonValues:array<string,string>} $data */
    private static function persist(mysqli $connection, array $data): void
    {
        $data['mainValues'] = array_filter($data['mainValues'] ?? [], static function ($v) {
            return $v !== null && $v !== '';
        });
        $data['buttonValues'] = array_filter($data['buttonValues'] ?? [], static function ($v) {
            return $v !== null && $v !== '';
        });
        $json = json_encode($data, JSON_UNESCAPED_UNICODE);
        $stmt = $connection->prepare('SELECT id FROM `setting` WHERE `type` = ? LIMIT 1');
        $type = self::SETTING_TYPE;
        $stmt->bind_param('s', $type);
        $stmt->execute();
        $exists = $stmt->get_result()->num_rows > 0;
        $stmt->close();
        if ($exists) {
            $stmt = $connection->prepare('UPDATE `setting` SET `value` = ? WHERE `type` = ?');
            $stmt->bind_param('ss', $json, $type);
        } else {
            $stmt = $connection->prepare('INSERT INTO `setting` (`type`, `value`) VALUES (?, ?)');
            $stmt->bind_param('ss', $type, $json);
        }
        $stmt->execute();
        $stmt->close();
    }

    public static function labelFor(string $categoryId, string $key): string
    {
        $cats = self::categories();
        if (isset($cats[$categoryId]['keys'][$key])) {
            return $cats[$categoryId]['keys'][$key];
        }
        return str_replace('_', ' ', $key);
    }

    /** @return array<int, array{key:string,group:string,label:string}> */
    public static function itemsForCategory(string $categoryId): array
    {
        $cats = self::categories();
        if (!isset($cats[$categoryId])) {
            return [];
        }
        $cat = $cats[$categoryId];
        $group = $cat['group'] === 'button' ? 'b' : 'm';
        $items = [];
        foreach ($cat['keys'] as $key => $label) {
            $items[] = ['key' => $key, 'group' => $group, 'label' => $label];
        }
        return $items;
    }

    /** @return string JSON inline keyboard */
    public static function categoryMenuKeyboard(): string
    {
        global $buttonValues;
        $rows = [];
        $row = [];
        foreach (self::categories() as $id => $cat) {
            $row[] = ['text' => $cat['title'], 'callback_data' => 'botTxtCat_' . $id . '_0'];
            if (count($row) === 2) {
                $rows[] = $row;
                $row = [];
            }
        }
        if (!empty($row)) {
            $rows[] = $row;
        }
        $rows[] = [
            ['text' => '♻️ بازنشانی همه متن‌ها', 'callback_data' => 'botTxtResetAll'],
            ['text' => '❓ راهنمای placeholders', 'callback_data' => 'botTxtHelp'],
        ];
        $rows[] = [['text' => $buttonValues['back_button'] ?? 'برگشت 🔙', 'callback_data' => 'managePanel']];
        return json_encode(['inline_keyboard' => $rows], JSON_UNESCAPED_UNICODE);
    }

    /** @return string JSON inline keyboard */
    public static function listKeyboard(string $categoryId, int $page): string
    {
        global $buttonValues;
        $items = self::itemsForCategory($categoryId);
        $perPage = 8;
        $total = count($items);
        $pages = max(1, (int) ceil($total / $perPage));
        $page = max(0, min($page, $pages - 1));
        $slice = array_slice($items, $page * $perPage, $perPage);
        $rows = [];
        foreach ($slice as $item) {
            $short = mb_strlen($item['label']) > 28 ? mb_substr($item['label'], 0, 26) . '…' : $item['label'];
            $rows[] = [[
                'text' => $short,
                'callback_data' => 'edTxt_' . $item['group'] . '_' . $item['key'],
            ]];
        }
        $nav = [];
        if ($page > 0) {
            $nav[] = ['text' => '◀️ قبلی', 'callback_data' => 'botTxtCat_' . $categoryId . '_' . ($page - 1)];
        }
        $nav[] = ['text' => ($page + 1) . '/' . $pages, 'callback_data' => 'wizwizch'];
        if ($page < $pages - 1) {
            $nav[] = ['text' => 'بعدی ▶️', 'callback_data' => 'botTxtCat_' . $categoryId . '_' . ($page + 1)];
        }
        $rows[] = $nav;
        $rows[] = [['text' => $buttonValues['back_button'] ?? 'برگشت 🔙', 'callback_data' => 'botTextsMenu']];
        return json_encode(['inline_keyboard' => $rows], JSON_UNESCAPED_UNICODE);
    }

    public static function editKeyboard(string $groupCode, string $key): string
    {
        return json_encode(['inline_keyboard' => [
            [['text' => '♻️ بازگشت به پیش‌فرض', 'callback_data' => 'rsTxt_' . $groupCode . '_' . $key]],
            [['text' => '🔙 لیست متن‌ها', 'callback_data' => 'botTextsMenu']],
        ]], JSON_UNESCAPED_UNICODE);
    }

    public static function helpText(): string
    {
        return "📖 راهنمای placeholders\n\n"
            . "در متن‌ها می‌توانید از این متغیرها استفاده کنید:\n"
            . "• REMARK — نام سرویس\n"
            . "• SUB-LINK — لینک سابسکریپشن\n"
            . "• USER-ID — آیدی عددی کاربر\n"
            . "• USERNAME — نام کاربری\n"
            . "• NAME — نام کاربر\n"
            . "• PRICE — مبلغ\n"
            . "• VOLUME — حجم (گیگ)\n"
            . "• DAYS — تعداد روز\n"
            . "• SERVERNAME — نام سرور\n"
            . "• ACCOUNT-NUMBER — شماره کارت\n"
            . "• HOLDER-NAME — نام صاحب حساب\n"
            . "• CHANNEL-ID — آیدی کانال\n\n"
            . "برای HTML از <code>متن</code> استفاده کنید.";
    }
}
