<?php
declare(strict_types=1);

if (!function_exists('cms_platform_root')) {
    function cms_platform_root(): string
    {
        return defined('CMS_ROOT') ? CMS_ROOT : dirname(__DIR__);
    }
}

if (!function_exists('cms_platform_ensure_schema')) {
    function cms_platform_ensure_schema(): void
    {
        static $ready = false;
        $pdo = db_connection();

        if ($ready || !$pdo instanceof PDO) {
            return;
        }

        $pdo->exec("
            CREATE TABLE IF NOT EXISTS settings (
                setting_key VARCHAR(191) PRIMARY KEY,
                setting_value LONGTEXT NULL,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
            )
        ");

        $pdo->exec("
            CREATE TABLE IF NOT EXISTS pages (
                id INT AUTO_INCREMENT PRIMARY KEY,
                title VARCHAR(255) NOT NULL,
                slug VARCHAR(191) NOT NULL UNIQUE,
                content LONGTEXT NULL,
                status VARCHAR(32) NOT NULL DEFAULT 'publish',
                header_content LONGTEXT NULL,
                footer_content LONGTEXT NULL,
                hidden_blocks_json LONGTEXT NULL,
                meta_title VARCHAR(255) NULL,
                meta_description TEXT NULL,
                schema_json LONGTEXT NULL,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
            )
        ");

        $pdo->exec("
            CREATE TABLE IF NOT EXISTS users (
                id INT AUTO_INCREMENT PRIMARY KEY,
                username VARCHAR(191) NOT NULL UNIQUE,
                password VARCHAR(255) NOT NULL,
                role VARCHAR(32) NOT NULL DEFAULT 'editor',
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ");

        $pdo->exec("
            CREATE TABLE IF NOT EXISTS plugins (
                slug VARCHAR(191) PRIMARY KEY,
                status VARCHAR(32) NOT NULL DEFAULT 'inactive',
                settings_json LONGTEXT NULL,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
            )
        ");

        $pdo->exec("
            CREATE TABLE IF NOT EXISTS themes (
                name VARCHAR(191) PRIMARY KEY,
                active TINYINT(1) NOT NULL DEFAULT 0,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
            )
        ");

        $pdo->exec("
            CREATE TABLE IF NOT EXISTS menu_items (
                id INT AUTO_INCREMENT PRIMARY KEY,
                label VARCHAR(255) NOT NULL,
                url VARCHAR(255) NOT NULL,
                sort_order INT NOT NULL DEFAULT 0,
                status VARCHAR(32) NOT NULL DEFAULT 'active',
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ");

        $pdo->exec("
            CREATE TABLE IF NOT EXISTS media (
                id INT AUTO_INCREMENT PRIMARY KEY,
                file_name VARCHAR(255) NOT NULL,
                file_path VARCHAR(255) NOT NULL,
                mime_type VARCHAR(191) NULL,
                file_size INT NOT NULL DEFAULT 0,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ");

        $legacySettings = $pdo->query("SHOW TABLES LIKE 'cms_settings'");
        if ($legacySettings instanceof PDOStatement && $legacySettings->fetch()) {
            $count = (int) ($pdo->query('SELECT COUNT(*) FROM settings')->fetchColumn() ?: 0);
            if ($count === 0) {
                $pdo->exec("
                    INSERT INTO settings (setting_key, setting_value, updated_at)
                    SELECT setting_key, setting_value, updated_at
                    FROM cms_settings
                ");
            }
        }

        $legacyPages = $pdo->query("SHOW TABLES LIKE 'cms_pages'");
        if ($legacyPages instanceof PDOStatement && $legacyPages->fetch()) {
            $count = (int) ($pdo->query('SELECT COUNT(*) FROM pages')->fetchColumn() ?: 0);
            if ($count === 0) {
                $pdo->exec("
                    INSERT INTO pages (id, title, slug, content, status, created_at, updated_at)
                    SELECT id, title, slug, content, 'publish', created_at, updated_at
                    FROM cms_pages
                ");
            }
        }

        cms_platform_ensure_table_columns();

        $ready = true;
    }
}

if (!function_exists('cms_table_columns')) {
    function cms_table_columns(string $table): array
    {
        $pdo = db_connection();
        if (!$pdo instanceof PDO) {
            return [];
        }

        try {
            $statement = $pdo->query('SHOW COLUMNS FROM `' . str_replace('`', '', $table) . '`');
            $columns = [];
            foreach ($statement ? $statement->fetchAll(PDO::FETCH_ASSOC) : [] as $row) {
                $columns[] = (string) ($row['Field'] ?? '');
            }

            return array_values(array_filter($columns));
        } catch (Throwable $exception) {
            return [];
        }
    }
}

if (!function_exists('cms_platform_ensure_table_columns')) {
    function cms_platform_ensure_table_columns(): void
    {
        $pdo = db_connection();
        if (!$pdo instanceof PDO) {
            return;
        }

        $settingsColumns = cms_table_columns('settings');
        if ($settingsColumns !== []) {
            if (!in_array('setting_key', $settingsColumns, true) && in_array('key', $settingsColumns, true)) {
                $pdo->exec('ALTER TABLE settings CHANGE `key` setting_key VARCHAR(191) NOT NULL');
            }
            if (!in_array('setting_value', $settingsColumns, true) && in_array('value', $settingsColumns, true)) {
                $pdo->exec('ALTER TABLE settings CHANGE `value` setting_value LONGTEXT NULL');
            }
            if (!in_array('updated_at', cms_table_columns('settings'), true)) {
                $pdo->exec('ALTER TABLE settings ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP');
            }
        }

        $pagesColumns = cms_table_columns('pages');
        if ($pagesColumns !== []) {
            if (!in_array('status', $pagesColumns, true)) {
                $pdo->exec("ALTER TABLE pages ADD COLUMN status VARCHAR(32) NOT NULL DEFAULT 'publish'");
            }
            if (!in_array('meta_title', $pagesColumns, true)) {
                $pdo->exec('ALTER TABLE pages ADD COLUMN meta_title VARCHAR(255) NULL');
            }
            if (!in_array('meta_description', $pagesColumns, true)) {
                $pdo->exec('ALTER TABLE pages ADD COLUMN meta_description TEXT NULL');
            }
            if (!in_array('header_content', $pagesColumns, true)) {
                $pdo->exec('ALTER TABLE pages ADD COLUMN header_content LONGTEXT NULL');
            }
            if (!in_array('footer_content', $pagesColumns, true)) {
                $pdo->exec('ALTER TABLE pages ADD COLUMN footer_content LONGTEXT NULL');
            }
            if (!in_array('hidden_blocks_json', $pagesColumns, true)) {
                $pdo->exec('ALTER TABLE pages ADD COLUMN hidden_blocks_json LONGTEXT NULL');
            }
            if (!in_array('schema_json', $pagesColumns, true)) {
                $pdo->exec('ALTER TABLE pages ADD COLUMN schema_json LONGTEXT NULL');
            }
            if (!in_array('updated_at', $pagesColumns, true)) {
                $pdo->exec('ALTER TABLE pages ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP');
            }
        }

        $pluginsColumns = cms_table_columns('plugins');
        if ($pluginsColumns !== []) {
            if (!in_array('settings_json', $pluginsColumns, true)) {
                $pdo->exec('ALTER TABLE plugins ADD COLUMN settings_json LONGTEXT NULL');
            }
            if (!in_array('updated_at', $pluginsColumns, true)) {
                $pdo->exec('ALTER TABLE plugins ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP');
            }
        }

        $themesColumns = cms_table_columns('themes');
        if ($themesColumns !== [] && !in_array('updated_at', $themesColumns, true)) {
            $pdo->exec('ALTER TABLE themes ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP');
        }
    }
}

if (!function_exists('cms_db_setting')) {
    function cms_db_setting(string $key, $default = null)
    {
        cms_platform_ensure_schema();
        $keyColumn = cms_setting_key_column();
        $valueColumn = cms_setting_value_column();
        $row = db_fetch(db_query(
            'SELECT ' . $valueColumn . ' AS setting_value FROM settings WHERE ' . $keyColumn . ' = :key LIMIT 1',
            [':key' => $key],
            30
        ));

        return $row['setting_value'] ?? $default;
    }
}

if (!function_exists('cms_set_db_setting')) {
    function cms_set_db_setting(string $key, string $value): bool
    {
        cms_platform_ensure_schema();
        $pdo = db_connection();
        if (!$pdo instanceof PDO) {
            return false;
        }
        $keyColumn = cms_setting_key_column();
        $valueColumn = cms_setting_value_column();

        $statement = $pdo->prepare("
            INSERT INTO settings ({$keyColumn}, {$valueColumn})
            VALUES (:key, :value)
            ON DUPLICATE KEY UPDATE {$valueColumn} = VALUES({$valueColumn})
        ");

        return $statement->execute([
            ':key' => $key,
            ':value' => $value,
        ]);
    }
}

if (!function_exists('cms_setting_key_column')) {
    function cms_setting_key_column(): string
    {
        $columns = cms_table_columns('settings');

        if (in_array('setting_key', $columns, true)) {
            return 'setting_key';
        }
        if (in_array('name', $columns, true)) {
            return 'name';
        }
        if (in_array('key', $columns, true)) {
            return '`key`';
        }

        return 'setting_key';
    }
}

if (!function_exists('cms_setting_value_column')) {
    function cms_setting_value_column(): string
    {
        $columns = cms_table_columns('settings');

        if (in_array('setting_value', $columns, true)) {
            return 'setting_value';
        }
        if (in_array('value', $columns, true)) {
            return '`value`';
        }

        return 'setting_value';
    }
}

if (!function_exists('cms_sync_themes')) {
    function cms_sync_themes(array $availableThemes, string $activeTheme): void
    {
        cms_platform_ensure_schema();
        $pdo = db_connection();
        if (!$pdo instanceof PDO) {
            return;
        }

        $pdo->exec('UPDATE themes SET active = 0');
        $statement = $pdo->prepare("
            INSERT INTO themes (name, active)
            VALUES (:name, :active)
            ON DUPLICATE KEY UPDATE active = VALUES(active)
        ");

        foreach ($availableThemes as $themeName) {
            $statement->execute([
                ':name' => $themeName,
                ':active' => $themeName === $activeTheme ? 1 : 0,
            ]);
        }
    }
}

if (!function_exists('cms_active_theme')) {
    function cms_active_theme(array $config = []): string
    {
        cms_platform_ensure_schema();
        $theme = (string) cms_db_setting('active_theme', (string) ($config['active_theme'] ?? 'default'));
        $availableThemes = cms_available_themes(cms_platform_root());

        if ($theme === '' || ($availableThemes !== [] && !in_array($theme, $availableThemes, true))) {
            $theme = $availableThemes[0] ?? ((string) ($config['active_theme'] ?? 'default'));
        }

        cms_sync_themes($availableThemes, $theme);

        return $theme;
    }
}

if (!function_exists('cms_site_title_value')) {
    function cms_site_title_value(array $config = []): string
    {
        cms_platform_ensure_schema();

        return (string) cms_db_setting('site_title', (string) ($config['site_title'] ?? 'Satta4uMatka'));
    }
}

if (!function_exists('cms_normalize_route_slug')) {
    function cms_normalize_route_slug(string $slug, string $default = 'info-chart'): string
    {
        $slug = strtolower(trim($slug));
        $slug = preg_replace('/[^a-z0-9\-]/', '-', $slug) ?: $default;
        $slug = trim($slug, '-');

        return $slug !== '' ? $slug : $default;
    }
}

if (!function_exists('cms_info_chart_base_slug')) {
    function cms_info_chart_base_slug(array $config = []): string
    {
        cms_platform_ensure_schema();

        $fallback = (string) ($config['info_chart_base_slug'] ?? 'info-chart');
        $value = (string) cms_db_setting('info_chart_base_slug', $fallback);

        return cms_normalize_route_slug($value, 'info-chart');
    }
}

if (!function_exists('cms_set_info_chart_base_slug')) {
    function cms_set_info_chart_base_slug(string $slug): bool
    {
        $slug = cms_normalize_route_slug($slug, 'info-chart');
        return cms_set_db_setting('info_chart_base_slug', $slug);
    }
}

if (!function_exists('cms_info_chart_url')) {
    function cms_info_chart_url(string $alias, string $type = 'jodi', array $config = []): string
    {
        $alias = cms_normalize_route_slug($alias, '');
        $type = strtolower(trim($type)) === 'panel' ? 'panel' : 'jodi';
        $baseSlug = cms_info_chart_base_slug($config);

        return '/' . $baseSlug . '/' . $alias . '-' . $type . '/';
    }
}

if (!function_exists('cms_get_pages_wp')) {
    function cms_get_pages_wp(?string $status = null): array
    {
        cms_platform_ensure_schema();
        $params = [];
        $sql = 'SELECT id, title, slug, content, status, header_content, footer_content, hidden_blocks_json, meta_title, meta_description, schema_json, updated_at, created_at FROM pages';

        if ($status !== null && $status !== '') {
            $sql .= ' WHERE status = :status';
            $params[':status'] = $status;
        }

        $sql .= ' ORDER BY updated_at DESC';

        return db_all($sql, $params, 15);
    }
}

if (!function_exists('cms_get_page_by_slug_wp')) {
    function cms_get_page_by_slug_wp(string $slug, string $status = 'publish'): ?array
    {
        cms_platform_ensure_schema();
        $slug = strtolower(trim($slug));

        return db_fetch(db_query(
            'SELECT id, title, slug, content, status, header_content, footer_content, hidden_blocks_json, meta_title, meta_description, schema_json FROM pages WHERE slug = :slug AND status = :status LIMIT 1',
            [':slug' => $slug, ':status' => $status],
            30
        ));
    }
}

if (!function_exists('cms_get_page_by_id_wp')) {
    function cms_get_page_by_id_wp(int $id): ?array
    {
        cms_platform_ensure_schema();

        return db_fetch(db_query(
            'SELECT id, title, slug, content, status, header_content, footer_content, hidden_blocks_json, meta_title, meta_description, schema_json FROM pages WHERE id = :id LIMIT 1',
            [':id' => $id]
        ));
    }
}

if (!function_exists('cms_normalize_page_hidden_blocks')) {
    function cms_normalize_page_hidden_blocks($value): array
    {
        if (is_string($value) && $value !== '') {
            $decoded = json_decode($value, true);
            if (is_array($decoded)) {
                $value = $decoded;
            }
        }

        if (!is_array($value)) {
            return [];
        }

        return array_values(array_unique(array_filter(array_map(static function ($block): string {
            return strtolower(trim((string) $block));
        }, $value))));
    }
}

if (!function_exists('cms_save_page_wp')) {
    function cms_save_page_wp(array $page): bool
    {
        cms_platform_ensure_schema();
        $pdo = db_connection();
        if (!$pdo instanceof PDO) {
            return false;
        }

        $id = (int) ($page['id'] ?? 0);
        $title = trim((string) ($page['title'] ?? ''));
        $slug = strtolower(trim((string) ($page['slug'] ?? '')));
        $slug = preg_replace('/[^a-z0-9\-]/', '-', $slug) ?: '';
        $content = (string) ($page['content'] ?? '');
        $status = in_array((string) ($page['status'] ?? 'publish'), ['publish', 'draft'], true) ? (string) $page['status'] : 'publish';
        $headerContent = (string) ($page['header_content'] ?? '');
        $footerContent = (string) ($page['footer_content'] ?? '');
        $hiddenBlocks = cms_normalize_page_hidden_blocks($page['hidden_blocks'] ?? ($page['hidden_blocks_json'] ?? []));
        $metaTitle = trim((string) ($page['meta_title'] ?? ''));
        $metaDescription = trim((string) ($page['meta_description'] ?? ''));
        $schemaJson = trim((string) ($page['schema_json'] ?? ''));
        $hiddenBlocksJson = $hiddenBlocks !== [] ? json_encode($hiddenBlocks, JSON_UNESCAPED_SLASHES) : null;

        if ($title === '' || $slug === '') {
            return false;
        }

        if ($id > 0) {
            $statement = $pdo->prepare("
                UPDATE pages
                SET title = :title, slug = :slug, content = :content, status = :status,
                    header_content = :header_content, footer_content = :footer_content,
                    hidden_blocks_json = :hidden_blocks_json,
                    meta_title = :meta_title, meta_description = :meta_description, schema_json = :schema_json
                WHERE id = :id
            ");
            $result = $statement->execute([
                ':id' => $id,
                ':title' => $title,
                ':slug' => $slug,
                ':content' => $content,
                ':status' => $status,
                ':header_content' => $headerContent !== '' ? $headerContent : null,
                ':footer_content' => $footerContent !== '' ? $footerContent : null,
                ':hidden_blocks_json' => $hiddenBlocksJson,
                ':meta_title' => $metaTitle !== '' ? $metaTitle : null,
                ':meta_description' => $metaDescription !== '' ? $metaDescription : null,
                ':schema_json' => $schemaJson !== '' ? $schemaJson : null,
            ]);
        } else {
            $statement = $pdo->prepare("
                INSERT INTO pages (title, slug, content, status, header_content, footer_content, hidden_blocks_json, meta_title, meta_description, schema_json)
                VALUES (:title, :slug, :content, :status, :header_content, :footer_content, :hidden_blocks_json, :meta_title, :meta_description, :schema_json)
            ");
            $result = $statement->execute([
                ':title' => $title,
                ':slug' => $slug,
                ':content' => $content,
                ':status' => $status,
                ':header_content' => $headerContent !== '' ? $headerContent : null,
                ':footer_content' => $footerContent !== '' ? $footerContent : null,
                ':hidden_blocks_json' => $hiddenBlocksJson,
                ':meta_title' => $metaTitle !== '' ? $metaTitle : null,
                ':meta_description' => $metaDescription !== '' ? $metaDescription : null,
                ':schema_json' => $schemaJson !== '' ? $schemaJson : null,
            ]);
        }

        cms_generate_sitemap();

        return $result;
    }
}

if (!function_exists('cms_delete_page_wp')) {
    function cms_delete_page_wp(int $id): bool
    {
        cms_platform_ensure_schema();
        $pdo = db_connection();
        if (!$pdo instanceof PDO) {
            return false;
        }

        $statement = $pdo->prepare('DELETE FROM pages WHERE id = :id');
        $result = $statement->execute([':id' => $id]);
        cms_generate_sitemap();

        return $result;
    }
}

if (!function_exists('cms_get_menu_items')) {
    function cms_get_menu_items(): array
    {
        cms_platform_ensure_schema();

        return db_all('SELECT id, label, url, sort_order, status FROM menu_items ORDER BY sort_order ASC, id ASC', [], 15);
    }
}

if (!function_exists('cms_render_menu')) {
    function cms_render_menu(): string
    {
        $items = array_values(array_filter(cms_get_menu_items(), static fn(array $item): bool => ($item['status'] ?? 'active') === 'active'));
        if ($items === []) {
            return '';
        }

        $html = '<nav class="cms-menu"><ul>';
        foreach ($items as $item) {
            $html .= '<li><a href="' . htmlspecialchars((string) $item['url'], ENT_QUOTES, 'UTF-8') . '">'
                . htmlspecialchars((string) $item['label'], ENT_QUOTES, 'UTF-8')
                . '</a></li>';
        }
        $html .= '</ul></nav>';

        return $html;
    }
}

if (!function_exists('cms_save_menu_items')) {
    function cms_save_menu_items(array $items): bool
    {
        cms_platform_ensure_schema();
        $pdo = db_connection();
        if (!$pdo instanceof PDO) {
            return false;
        }

        $pdo->beginTransaction();

        try {
            $pdo->exec('TRUNCATE TABLE menu_items');
            $statement = $pdo->prepare("
                INSERT INTO menu_items (label, url, sort_order, status)
                VALUES (:label, :url, :sort_order, :status)
            ");

            $order = 0;
            foreach ($items as $item) {
                $label = trim((string) ($item['label'] ?? ''));
                $url = trim((string) ($item['url'] ?? ''));
                $status = !empty($item['enabled']) ? 'active' : 'inactive';

                if ($label === '' || $url === '') {
                    continue;
                }

                $statement->execute([
                    ':label' => $label,
                    ':url' => $url,
                    ':sort_order' => $order++,
                    ':status' => $status,
                ]);
            }

            $pdo->commit();
            return true;
        } catch (Throwable $exception) {
            if ($pdo->inTransaction()) {
                $pdo->rollBack();
            }
            return false;
        }
    }
}

if (!function_exists('cms_sync_plugins_registry')) {
    function cms_sync_plugins_registry(array $pluginSlugs, array $activePlugins): void
    {
        cms_platform_ensure_schema();
        $pdo = db_connection();
        if (!$pdo instanceof PDO) {
            return;
        }

        $statement = $pdo->prepare("
            INSERT INTO plugins (slug, status)
            VALUES (:slug, :status)
            ON DUPLICATE KEY UPDATE status = VALUES(status)
        ");

        foreach ($pluginSlugs as $slug) {
            $statement->execute([
                ':slug' => $slug,
                ':status' => in_array($slug, $activePlugins, true) ? 'active' : 'inactive',
            ]);
        }
    }
}

if (!function_exists('cms_get_active_plugins')) {
    function cms_get_active_plugins(array $config = []): array
    {
        cms_platform_ensure_schema();
        if (!function_exists('cms_get_plugins')) {
            $pluginLoader = cms_platform_root() . '/core/plugins.php';
            if (is_file($pluginLoader)) {
                require_once $pluginLoader;
            }
        }

        if (!function_exists('cms_get_plugins')) {
            $active = is_array($config['active_plugins'] ?? null) ? $config['active_plugins'] : [];

            return array_values(array_unique(array_filter(array_map(static fn($slug): string => strtolower(trim((string) $slug)), $active))));
        }

        $pluginsPath = cms_platform_root() . '/content/plugins';
        $allPlugins = cms_get_plugins($pluginsPath, []);
        $discovered = array_keys($allPlugins);
        $dbRows = db_all("SELECT slug FROM plugins WHERE status = 'active'", [], 15);
        $active = array_values(array_filter(array_map(static fn(array $row): string => strtolower(trim((string) ($row['slug'] ?? ''))), $dbRows)));

        if ($active === []) {
            $active = is_array($config['active_plugins'] ?? null) ? $config['active_plugins'] : [];
        }

        $active = array_values(array_unique(array_filter($active, static fn(string $slug): bool => in_array($slug, $discovered, true))));
        cms_sync_plugins_registry($discovered, $active);

        return $active;
    }
}

if (!function_exists('cms_set_plugin_status')) {
    function cms_set_plugin_status(string $slug, bool $active): bool
    {
        cms_platform_ensure_schema();
        $slug = strtolower(trim($slug));
        $pdo = db_connection();
        if (!$pdo instanceof PDO || $slug === '') {
            return false;
        }

        $statement = $pdo->prepare("
            INSERT INTO plugins (slug, status)
            VALUES (:slug, :status)
            ON DUPLICATE KEY UPDATE status = VALUES(status)
        ");

        return $statement->execute([
            ':slug' => $slug,
            ':status' => $active ? 'active' : 'inactive',
        ]);
    }
}

if (!function_exists('cms_get_plugin_settings')) {
    function cms_get_plugin_settings(string $slug): array
    {
        cms_platform_ensure_schema();
        $row = db_fetch(db_query('SELECT settings_json FROM plugins WHERE slug = :slug LIMIT 1', [':slug' => strtolower(trim($slug))]));
        $decoded = json_decode((string) ($row['settings_json'] ?? '[]'), true);

        return is_array($decoded) ? $decoded : [];
    }
}

if (!function_exists('cms_set_plugin_settings')) {
    function cms_set_plugin_settings(string $slug, array $settings): bool
    {
        cms_platform_ensure_schema();
        $pdo = db_connection();
        if (!$pdo instanceof PDO) {
            return false;
        }

        $statement = $pdo->prepare("
            INSERT INTO plugins (slug, status, settings_json)
            VALUES (:slug, :status, :settings_json)
            ON DUPLICATE KEY UPDATE settings_json = VALUES(settings_json)
        ");

        return $statement->execute([
            ':slug' => strtolower(trim($slug)),
            ':status' => 'inactive',
            ':settings_json' => json_encode($settings, JSON_UNESCAPED_SLASHES),
        ]);
    }
}

if (!function_exists('cms_get_homepage_blocks_wp')) {
    function cms_get_homepage_blocks_wp(array $config = []): array
    {
        $saved = (string) cms_db_setting('homepage_blocks', '');
        $blocks = $saved !== '' ? json_decode($saved, true) : null;

        if (!is_array($blocks)) {
            $blocks = is_array($config['homepage_blocks'] ?? null) ? $config['homepage_blocks'] : [];
        }

        return array_values(array_unique(array_filter(array_map(static fn($block): string => strtolower(trim((string) $block)), $blocks))));
    }
}

if (!function_exists('cms_save_homepage_blocks_wp')) {
    function cms_save_homepage_blocks_wp(array $blocks): bool
    {
        $blocks = array_values(array_unique(array_filter(array_map(static fn($block): string => strtolower(trim((string) $block)), $blocks))));
        return cms_set_db_setting('homepage_blocks', json_encode($blocks, JSON_UNESCAPED_SLASHES));
    }
}

if (!function_exists('cms_get_media_items')) {
    function cms_get_media_items(): array
    {
        cms_platform_ensure_schema();
        return db_all('SELECT id, file_name, file_path, mime_type, file_size, created_at FROM media ORDER BY created_at DESC', [], 15);
    }
}

if (!function_exists('cms_save_media_upload')) {
    function cms_save_media_upload(array $file): array
    {
        cms_platform_ensure_schema();
        if (!isset($file['tmp_name'], $file['name']) || !is_uploaded_file((string) $file['tmp_name'])) {
            return ['ok' => false, 'message' => 'Invalid upload.'];
        }

        $uploadsDir = cms_platform_root() . '/uploads';
        if (!is_dir($uploadsDir)) {
            @mkdir($uploadsDir, 0775, true);
        }

        $name = preg_replace('/[^a-zA-Z0-9._-]/', '-', (string) $file['name']) ?: ('upload-' . time());
        $target = $uploadsDir . '/' . date('Ymd-His') . '-' . $name;

        if (!move_uploaded_file((string) $file['tmp_name'], $target)) {
            return ['ok' => false, 'message' => 'Upload failed.'];
        }

        $pdo = db_connection();
        if ($pdo instanceof PDO) {
            $statement = $pdo->prepare("
                INSERT INTO media (file_name, file_path, mime_type, file_size)
                VALUES (:file_name, :file_path, :mime_type, :file_size)
            ");
            $statement->execute([
                ':file_name' => basename($target),
                ':file_path' => '/uploads/' . basename($target),
                ':mime_type' => (string) ($file['type'] ?? ''),
                ':file_size' => (int) ($file['size'] ?? 0),
            ]);
        }

        return ['ok' => true, 'message' => 'Media uploaded.', 'path' => '/uploads/' . basename($target)];
    }
}

if (!function_exists('cms_generate_sitemap')) {
    function cms_generate_sitemap(): bool
    {
        $root = cms_platform_root();
        $pages = cms_get_pages_wp('publish');
        $baseUrl = rtrim((string) cms_db_setting('site_url', ''), '/');
        $urls = [];

        if ($baseUrl !== '') {
            $urls[] = $baseUrl . '/';
            foreach ($pages as $page) {
                $urls[] = $baseUrl . '/' . ltrim((string) ($page['slug'] ?? ''), '/');
            }
        }

        $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
        $xml .= "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n";
        foreach ($urls as $url) {
            $xml .= "  <url><loc>" . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . "</loc></url>\n";
        }
        $xml .= "</urlset>\n";

        return file_put_contents($root . '/sitemap.xml', $xml, LOCK_EX) !== false;
    }
}

if (!function_exists('cms_generate_robots')) {
    function cms_generate_robots(): bool
    {
        $root = cms_platform_root();
        $robots = (string) cms_db_setting('robots_txt', "User-agent: *\nAllow: /\n");

        return file_put_contents($root . '/robots.txt', $robots, LOCK_EX) !== false;
    }
}

if (!function_exists('cms_current_user')) {
    function cms_current_user(): ?array
    {
        return isset($_SESSION['cms_user']) && is_array($_SESSION['cms_user']) ? $_SESSION['cms_user'] : null;
    }
}

if (!function_exists('cms_user_id_column')) {
    function cms_user_id_column(): string
    {
        $columns = cms_table_columns('users');

        if (in_array('id', $columns, true)) {
            return 'id';
        }
        if (in_array('user_id', $columns, true)) {
            return 'user_id';
        }

        return 'id';
    }
}

if (!function_exists('cms_user_role_expression')) {
    function cms_user_role_expression(): string
    {
        $columns = cms_table_columns('users');

        if (in_array('role', $columns, true)) {
            return 'role';
        }
        if (in_array('admin', $columns, true)) {
            return "CASE WHEN admin = 1 OR admin = '1' THEN 'admin' ELSE 'editor' END";
        }

        return "'editor'";
    }
}

if (!function_exists('cms_authenticate_user')) {
    function cms_authenticate_user(string $username, string $password): ?array
    {
        cms_platform_ensure_schema();
        $columns = cms_table_columns('users');
        $idColumn = cms_user_id_column();
        $roleExpression = cms_user_role_expression();
        $sql = 'SELECT ' . $idColumn . ' AS id, username, password, ' . $roleExpression . ' AS role FROM users WHERE username = :username';
        $params = [':username' => trim($username)];

        if (in_array('is_active', $columns, true)) {
            $sql .= ' AND is_active = :is_active';
            $params[':is_active'] = 1;
        }
        if (in_array('status', $columns, true)) {
            $sql .= ' AND status = :status';
            $params[':status'] = 'active';
        }

        $sql .= ' LIMIT 1';
        $user = db_fetch(db_query(
            $sql,
            $params
        ));

        if (!is_array($user)) {
            return null;
        }

        $storedPassword = (string) ($user['password'] ?? '');
        $passwordMatches = false;

        if ($storedPassword !== '') {
            $passwordMatches = password_verify($password, $storedPassword)
                || hash_equals($storedPassword, $password)
                || hash_equals($storedPassword, md5($password))
                || hash_equals($storedPassword, sha1($password));
        }

        if (!$passwordMatches) {
            return null;
        }

        if ($storedPassword !== '' && !password_get_info($storedPassword)['algo']) {
            $pdo = db_connection();
            if ($pdo instanceof PDO) {
                $update = $pdo->prepare('UPDATE users SET password = :password WHERE ' . $idColumn . ' = :id');
                $update->execute([
                    ':password' => password_hash($password, PASSWORD_DEFAULT),
                    ':id' => (int) $user['id'],
                ]);
            }
        }

        return [
            'id' => (int) $user['id'],
            'username' => (string) $user['username'],
            'role' => (string) $user['role'],
        ];
    }
}

if (!function_exists('cms_boot_default_users')) {
    function cms_boot_default_users(array $config = []): void
    {
        cms_platform_ensure_schema();
        $pdo = db_connection();
        if (!$pdo instanceof PDO) {
            return;
        }

        $count = (int) ($pdo->query('SELECT COUNT(*) FROM users')->fetchColumn() ?: 0);
        if ($count > 0) {
            return;
        }

        $username = (string) (($config['admin']['username'] ?? 'admin'));
        $passwordHash = (string) (($config['admin']['password_hash'] ?? password_hash('admin123', PASSWORD_DEFAULT)));
        $statement = $pdo->prepare('INSERT INTO users (username, password, role) VALUES (:username, :password, :role)');
        $statement->execute([
            ':username' => $username !== '' ? $username : 'admin',
            ':password' => $passwordHash,
            ':role' => 'admin',
        ]);
    }
}

if (!function_exists('cms_platform_boot')) {
    function cms_platform_boot(array $config = []): void
    {
        cms_platform_ensure_schema();
        cms_boot_default_users($config);
        if ((string) cms_db_setting('site_title', '') === '') {
            cms_set_db_setting('site_title', (string) ($config['site_title'] ?? 'Satta4uMatka'));
        }
        if ((string) cms_db_setting('active_theme', '') === '') {
            cms_set_db_setting('active_theme', (string) ($config['active_theme'] ?? 'default'));
        }
        cms_active_theme($config);
        cms_generate_robots();
        cms_generate_sitemap();
    }
}
