<?php
// 功能：安装程序专用文件
// 作者：启肯科技
// Q Q：328493711
// 微信：13738373177（同手机）
// 官网：http://www.qiken.com
// 说明：QKCMS-轻量级AI智能内容管理建站系统
// 版权：© 2025 温州启肯网络有限公司 保留所有权利，盗版必究。


// - 首次初始化：保持 DB_INIT_STATUS 为 'init' ，执行install.php
// - 防止重复初始化：程序安装完成后，会自动将 DB_INIT_STATUS 改为 'done
const DB_INIT_STATUS = 'init';
if (DB_INIT_STATUS === 'done') {
    header('Location: index.php');
    exit;
}

session_start();

class Installer
{
    private $conn;
    private $steps = [];

    public function handleRequest()
    {
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $this->handlePostRequest();
        }
    }

    private function handlePostRequest()
    {
        $action = isset($_POST['action']) ? $_POST['action'] : '';

        if ($action === 'validate_database') {
            $this->validateDatabase();
        } elseif ($action === 'start_installation') {
            $this->startInstallation();
        }
    }

    private function validateDatabase()
    {
        $required = ['db_host', 'db_username', 'db_name'];
        foreach ($required as $field) {
            if (empty($_POST[$field])) {
                $this->jsonResponse(false, "缺少必要字段: $field");
                return;
            }
        }

        $db_config = [
            'host' => $_POST['db_host'],
            'username' => $_POST['db_username'],
            'password' => $_POST['db_password'],
            'name' => $_POST['db_name']
        ];

        $connection = @new mysqli($db_config['host'], $db_config['username'], $db_config['password'], $db_config['name']);

        if ($connection->connect_error) {
            $this->jsonResponse(false, "数据库连接失败: " . $connection->connect_error);
        } else {
            $_SESSION['db_config'] = $db_config;
            $this->jsonResponse(true, "数据库连接成功");
        }
    }

    private function startInstallation()
    {
        if (empty($_SESSION['db_config'])) {
            $this->jsonResponse(false, '请先配置并验证数据库连接');
            return;
        }

        $admin_username = isset($_POST['admin_username']) ? $_POST['admin_username'] : '';
        $admin_password = isset($_POST['admin_password']) ? $_POST['admin_password'] : '';

        if (empty($admin_username) || empty($admin_password)) {
            $this->jsonResponse(false, '管理员用户名和密码不能为空');
            return;
        }

        $db_config = $_SESSION['db_config'];
        $enable_sql_import = (isset($_POST['enable_sql_import']) && $_POST['enable_sql_import'] === 'on') ? true : false;

        $result = $this->performInstallation(
            $db_config['host'],
            $db_config['username'],
            $db_config['password'],
            $db_config['name'],
            $admin_username,
            $admin_password,
            $enable_sql_import
        );

        $this->jsonResponse($result['success'], '', $result);
    }

    private function performInstallation($db_host, $db_username, $db_password, $db_name, $admin_username, $admin_password, $enable_sql_import)
    {
        $this->addStep('连接数据库', '开始', '尝试连接到数据库服务器');

        $this->conn = @new mysqli($db_host, $db_username, $db_password);
        if ($this->conn->connect_error) {
            $this->addStep('连接数据库', '失败', '连接错误: ' . $this->conn->connect_error);
            return ['success' => false, 'steps' => $this->steps];
        }
        $this->addStep('连接数据库', '成功', '已成功连接到数据库服务器');

        $this->addStep('创建数据库', '开始', "尝试创建数据库: $db_name");
        if (!$this->conn->query("CREATE DATABASE IF NOT EXISTS `$db_name` CHARACTER SET utf8 COLLATE utf8_unicode_ci")) {
            $this->addStep('创建数据库', '失败', '创建错误: ' . $this->conn->error);
            return ['success' => false, 'steps' => $this->steps];
        }
        $this->addStep('创建数据库', '成功', "数据库 $db_name 创建成功");

        $this->conn->select_db($db_name);

        $this->addStep('创建数据表结构', '开始', '开始创建系统所需的数据表结构');
        if (!$this->createTables()) {
            return ['success' => false, 'steps' => $this->steps];
        }
        $this->addStep('创建数据表结构', '成功', '所有数据表结构创建完成');

        $this->addStep('创建管理员', '开始', "创建管理员账户: $admin_username");
        $this->createAdminUser($admin_username, $admin_password);

        if ($enable_sql_import) {
            $this->importSQLData();
        } else {
            $this->addStep('导入SQL数据', '跳过', '未启用SQL导入功能');
        }

        $this->addStep('确认管理员', '开始', "最终确认管理员账户: $admin_username");
        $this->ensureAdminUser($admin_username, $admin_password);

        // 强制设置管理员密码，确保使用用户输入的密码
        $this->forceAdminPassword($admin_username, $admin_password);

        $this->addStep('更新配置', '开始', '更新系统配置文件');
        if (!$this->updateConfigFiles($db_host, $db_username, $db_password, $db_name, false)) {
            $this->addStep('更新配置', '失败', '配置文件写入失败，请检查根目录写入权限');
            return ['success' => false, 'steps' => $this->steps];
        }
        $this->addStep('更新配置', '成功', '配置文件更新完成');

        $this->addStep('完成安装', '成功', '系统安装已完成');
        if (!$this->updateConfigFiles($db_host, $db_username, $db_password, $db_name, true)) {
            $this->addStep('完成安装', '警告', '安装完成，但安装状态写入失败，请检查 templates/install.php 写入权限');
        }

        return [
            'success' => true,
            'steps' => $this->steps,
            'admin_username' => $admin_username,
            'db_name' => $db_name
        ];
    }

    private function createTables()
    {
        $tables = [
            "carts" => "CREATE TABLE IF NOT EXISTS `carts` (`id` int(11) NOT NULL AUTO_INCREMENT,`user_id` int(11) NOT NULL,`product_id` int(11) NOT NULL,`specs` text,`bundle_ids` text,`quantity` int(11) NOT NULL DEFAULT '1',`price` decimal(10,2) NOT NULL DEFAULT '0.00',`added_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`is_checkout` tinyint(1) NOT NULL DEFAULT '0',PRIMARY KEY (`id`),KEY `idx_user_id` (`user_id`),KEY `idx_product_id` (`product_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "categories" => "CREATE TABLE IF NOT EXISTS `categories` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',`seo_title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,`description` text COLLATE utf8_unicode_ci,`thumbnail` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,`keywords` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',`template` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'list.html' COMMENT '列表模板绑定',`status` tinyint(4) DEFAULT '1',`display` tinyint(1) NOT NULL DEFAULT '1',`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`custom_url` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,`archiveid` int(11) NOT NULL DEFAULT '0',`sort` int(11) NOT NULL DEFAULT '0',`virtual_top` tinyint(1) NOT NULL DEFAULT '0',`virtual_top_anchor` int(11) NOT NULL DEFAULT '0',PRIMARY KEY (`id`),UNIQUE KEY `name` (`name`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;",
            "catgroup" => "CREATE TABLE IF NOT EXISTS `catgroup` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) NOT NULL DEFAULT '',`color` varchar(20) NOT NULL DEFAULT '#64748b',`custom_url` varchar(255) DEFAULT NULL,`seo_title` varchar(255) DEFAULT NULL,`seo_keywords` text,`seo_description` text,`template` varchar(50) NOT NULL DEFAULT 'catgroup.html',`sort` int(11) NOT NULL DEFAULT '0',`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`),UNIQUE KEY `uniq_catgroup_custom_url` (`custom_url`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "comments" => "CREATE TABLE IF NOT EXISTS `comments` (`id` int(11) NOT NULL AUTO_INCREMENT,`post_id` int(11) NOT NULL DEFAULT '0',`user_id` int(11) NOT NULL DEFAULT '0',`content` text NOT NULL,`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`status` int(11) DEFAULT '0',`report_count` int(11) DEFAULT '0',`dislike_count` int(11) DEFAULT '0',`likes` int(11) DEFAULT '0',`parent_id` int(11) NOT NULL DEFAULT '0',`reply_to` varchar(50) NOT NULL DEFAULT '',`content_type` varchar(20) NOT NULL DEFAULT 'post',PRIMARY KEY (`id`),KEY `idx_post_id` (`post_id`),KEY `idx_user_id` (`user_id`),KEY `idx_parent_id` (`parent_id`),KEY `idx_content_type` (`content_type`),KEY `idx_ct_post_status_parent` (`content_type`,`post_id`,`status`,`parent_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "counter" => "CREATE TABLE IF NOT EXISTS `counter` (`id` int(11) NOT NULL AUTO_INCREMENT,`stat_date` date NOT NULL,`page_title` varchar(255) NOT NULL DEFAULT '',`page_url` varchar(500) NOT NULL DEFAULT '',`entry_url` varchar(500) NOT NULL DEFAULT '',`os_name` varchar(60) NOT NULL DEFAULT '',`browser` varchar(80) NOT NULL DEFAULT '',`language` varchar(20) NOT NULL DEFAULT '',`timezone` varchar(80) NOT NULL DEFAULT '',`resolution` varchar(40) NOT NULL DEFAULT '',`pv` int(11) NOT NULL DEFAULT '0',`uv` int(11) NOT NULL DEFAULT '0',`ip_count` int(11) NOT NULL DEFAULT '0',`spider_count` int(11) NOT NULL DEFAULT '0',`speed_ms` decimal(10,2) NOT NULL DEFAULT '0.00',`avg_time_ms` decimal(10,2) NOT NULL DEFAULT '0.00',`bounce_rate` decimal(6,2) NOT NULL DEFAULT '0.00',`session_count` int(11) NOT NULL DEFAULT '0',`bounce_count` int(11) NOT NULL DEFAULT '0',`sum_speed_ms` bigint(20) NOT NULL DEFAULT '0',`sum_time_ms` bigint(20) NOT NULL DEFAULT '0',`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`uv_keys` mediumtext,`ip_keys` mediumtext,`session_keys` mediumtext,`bounce_keys` mediumtext,PRIMARY KEY (`id`),UNIQUE KEY `uniq_stat_page` (`stat_date`,`page_url`(191)),KEY `idx_stat_date` (`stat_date`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "goods" => "CREATE TABLE IF NOT EXISTS `goods` (`id` int(11) NOT NULL AUTO_INCREMENT,`title` varchar(255) NOT NULL DEFAULT '',`image` text,`price` decimal(10,2) NOT NULL DEFAULT '0.00',`stock` int(11) NOT NULL DEFAULT '0',`sales` int(11) NOT NULL DEFAULT '0',`parent_id` text,`keywords` varchar(255) DEFAULT NULL,`description` varchar(500) DEFAULT NULL,`status` tinyint(1) DEFAULT '0',`category_id` int(11) NOT NULL DEFAULT '0',`content` longtext NOT NULL,`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`specs` text,`mp4url` text,`template` varchar(50) DEFAULT 'goods.php',`stamp_config` text COMMENT '盖章配置',PRIMARY KEY (`id`),KEY `idx_category_status` (`category_id`,`status`,`id`),KEY `idx_status_create_time` (`status`,`create_time`,`id`),KEY `idx_status_sales` (`status`,`sales`,`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "levels" => "CREATE TABLE IF NOT EXISTS `levels` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) NOT NULL DEFAULT '',`icon` varchar(255) DEFAULT NULL,`permissions` text,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "likes" => "CREATE TABLE IF NOT EXISTS `likes` (`id` int(11) NOT NULL AUTO_INCREMENT,`content_type` varchar(20) NOT NULL DEFAULT '',`content_id` int(11) NOT NULL DEFAULT '0',`user_id` int(11) NOT NULL DEFAULT '0',`type` enum('like','dislike') NOT NULL DEFAULT 'like',`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`id`),UNIQUE KEY `unique_like` (`content_type`,`content_id`,`user_id`,`type`),KEY `user_id` (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "navigation" => "CREATE TABLE IF NOT EXISTS `navigation` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) NOT NULL DEFAULT '',`url` varchar(255) NOT NULL DEFAULT '',`target` varchar(20) DEFAULT '_self',`display_order` int(11) DEFAULT '0',`status` int(11) DEFAULT '1',`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`parent_id` int(11) DEFAULT '0',`category_id` int(11) DEFAULT '0',PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "order" => "CREATE TABLE IF NOT EXISTS `order` (`id` int(11) NOT NULL AUTO_INCREMENT,`order_no` varchar(32) NOT NULL,`user_id` int(11) NOT NULL,`amount` decimal(10,2) NOT NULL,`points` int(11) NOT NULL,`pay_type` varchar(20) NOT NULL,`type` varchar(20) NOT NULL,`goods_id` int(11) DEFAULT '0',`goods_info` text,`address` text,`message` text,`shipping_status` tinyint(1) NOT NULL DEFAULT '0',`created_at` datetime NOT NULL,`pay_time` datetime NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `order_no` (`order_no`),KEY `user_id` (`user_id`),KEY `goods_id` (`goods_id`),KEY `idx_created_at` (`created_at`),KEY `idx_pay_type` (`pay_type`),KEY `idx_order_type` (`type`),KEY `idx_shipping_status` (`shipping_status`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "plugin" => "CREATE TABLE IF NOT EXISTS `plugin` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`plugin` varchar(60) NOT NULL DEFAULT '',`event` varchar(60) NOT NULL DEFAULT '',`payload` text,`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`id`),KEY `idx_plugin_created` (`plugin`,`created_at`),KEY `idx_plugin_event_created` (`plugin`,`event`,`created_at`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "posts" => "CREATE TABLE IF NOT EXISTS `posts` (`id` int(11) NOT NULL AUTO_INCREMENT,`title` varchar(255) NOT NULL DEFAULT '',`content` longtext NOT NULL,`category_id` int(11) NOT NULL DEFAULT '0',`user_id` int(11) NOT NULL DEFAULT '0',`keywords` text,`description` text,`thumbnail` text,`property` tinyint(1) DEFAULT '0',`template` varchar(50) NOT NULL DEFAULT 'post.php' COMMENT '文章模板绑定',`custom_url` varchar(255) DEFAULT NULL,`status` tinyint(1) DEFAULT '0',`views` int(11) DEFAULT '0',`top_type` tinyint(1) NOT NULL DEFAULT '0',`likes` int(11) DEFAULT '0',`points` int(11) DEFAULT '0',`mp4url` text,`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`tool_url` varchar(255) DEFAULT NULL,`status_switch` tinyint(1) DEFAULT '0',`price` decimal(10,2) DEFAULT '0.00',`redirect_url` varchar(255) DEFAULT NULL,`function_type` varchar(20) DEFAULT 'tool',`custom_field_1` varchar(255) DEFAULT NULL,`custom_field_2` varchar(255) DEFAULT NULL,`custom_field_3` varchar(255) DEFAULT NULL,`stamp_config` text COMMENT '盖章配置',`bind_domain` varchar(255) DEFAULT NULL,`access_password` varchar(100) NOT NULL DEFAULT '',PRIMARY KEY (`id`),KEY `idx_category_id` (`category_id`),KEY `idx_user_id` (`user_id`),KEY `idx_created_at` (`created_at`),KEY `idx_updated_at` (`updated_at`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "properties" => "CREATE TABLE IF NOT EXISTS `properties` (`id` int(11) NOT NULL,`name` varchar(50) NOT NULL DEFAULT '',`is_system` tinyint(1) NOT NULL DEFAULT '0',`is_enabled` tinyint(1) NOT NULL DEFAULT '1',`sort_order` int(11) NOT NULL DEFAULT '0',`color` varchar(20) NOT NULL DEFAULT '#999999',PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "publish" => "CREATE TABLE IF NOT EXISTS `publish` (`id` int(11) NOT NULL AUTO_INCREMENT,`category_id` int(11) NOT NULL DEFAULT '0',`user_id` int(11) NOT NULL DEFAULT '0',`title` varchar(255) NOT NULL DEFAULT '',`keywords` text,`description` text,`content` longtext NOT NULL,`thumbnail` text,`status` tinyint(1) NOT NULL DEFAULT '0',`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`post_id` int(11) NOT NULL DEFAULT '0',`scheduled_at` datetime DEFAULT NULL,`task_id` varchar(64) DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_status_created_at` (`status`,`created_at`),KEY `idx_category_id` (`category_id`),KEY `idx_user_id` (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "reports" => "CREATE TABLE IF NOT EXISTS `reports` (`id` int(11) NOT NULL AUTO_INCREMENT,`content_type` varchar(20) NOT NULL DEFAULT '',`content_id` int(11) NOT NULL DEFAULT '0',`user_id` int(11) NOT NULL DEFAULT '0',`reason` text NOT NULL,`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`status` int(11) DEFAULT '0',PRIMARY KEY (`id`),KEY `user_id` (`user_id`),KEY `idx_content_id` (`content_id`),KEY `idx_status_created` (`status`,`created_at`),KEY `idx_content_type_id` (`content_type`,`content_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "search" => "CREATE TABLE IF NOT EXISTS `search` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(50) DEFAULT NULL,`search_term` varchar(100) NOT NULL DEFAULT '',`search_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`id`),KEY `idx_search_term` (`search_term`),KEY `idx_search_time` (`search_time`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "settings" => "CREATE TABLE IF NOT EXISTS `settings` (`id` int(11) NOT NULL AUTO_INCREMENT,`site_name` varchar(255) DEFAULT NULL,`logo` varchar(255) DEFAULT NULL,`site_title` varchar(255) NOT NULL DEFAULT '',`site_keywords` varchar(255) DEFAULT NULL,`site_description` text,`site_copyright` varchar(255) DEFAULT NULL,`primary_color` varchar(20) DEFAULT NULL,`home_template` varchar(50) NOT NULL DEFAULT 'index.php',`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`comment_check` tinyint(1) DEFAULT '0',`debug_mode` tinyint(1) DEFAULT '0',`status` int(11) DEFAULT '0',`close_reason` varchar(255) DEFAULT NULL,`Prohw` varchar(255) DEFAULT '垃圾垃圾，骗子，去死',PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "shares" => "CREATE TABLE IF NOT EXISTS `shares` (`id` int(11) NOT NULL AUTO_INCREMENT,`content_type` varchar(20) NOT NULL DEFAULT '',`content_id` int(11) NOT NULL DEFAULT '0',`user_id` int(11) DEFAULT NULL,`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`id`),KEY `user_id` (`user_id`),KEY `idx_content` (`content_type`,`content_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "tplmark" => "CREATE TABLE IF NOT EXISTS `tplmark` (`id` int(11) NOT NULL AUTO_INCREMENT,`name_cn` varchar(50) NOT NULL DEFAULT '',`code` varchar(50) NOT NULL DEFAULT '',`category` varchar(20) NOT NULL DEFAULT '',`type` varchar(10) NOT NULL DEFAULT '',`example` text,`description` text,`description_html` longtext,`sort_order` int(11) DEFAULT NULL COMMENT '排序',PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "users" => "CREATE TABLE IF NOT EXISTS `users` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(50) NOT NULL DEFAULT '',`password` varchar(255) NOT NULL DEFAULT '',`email` varchar(100) DEFAULT NULL,`levels_id` int(11) DEFAULT '1',`avatar` varchar(255) DEFAULT NULL,`last_login` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`status` varchar(20) DEFAULT NULL,`points` int(11) DEFAULT '0',`bio` text,`bought` text,`tool_bought` text,`address` text,PRIMARY KEY (`id`),UNIQUE KEY `username` (`username`),UNIQUE KEY `email` (`email`),KEY `idx_levels_id` (`levels_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "usvisits" => "CREATE TABLE IF NOT EXISTS `usvisits` (`id` int(11) NOT NULL AUTO_INCREMENT,`visitorid` int(11) NOT NULL,`visitedid` int(11) NOT NULL,`visittime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`),UNIQUE KEY `unique_visit` (`visitorid`,`visitedid`),KEY `idx_visitorid` (`visitorid`),KEY `idx_visitedid` (`visitedid`),KEY `idx_visittime` (`visittime`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;",
            "visit" => "CREATE TABLE IF NOT EXISTS `visit` (`id` int(11) NOT NULL AUTO_INCREMENT,`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`ip` varchar(50) NOT NULL DEFAULT '',PRIMARY KEY (`id`),KEY `idx_time` (`time`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;"
        ];

        foreach ($tables as $tableName => $sql) {
            $okCreate = $this->conn->query($sql);
            if (!$okCreate) {
                $this->addStep('创建数据表', '失败', "创建表 `$tableName` 失败: " . $this->conn->error);
                return false;
            }

            if ($tableName === 'settings') {
                $default_settings_sql = "INSERT IGNORE INTO `settings` (`id`, `site_name`, `logo`, `site_title`, `site_keywords`, `site_description`, `site_copyright`, `primary_color`, `updated_at`, `comment_check`, `debug_mode`, `status`, `close_reason`, `Prohw`) VALUES 
                ('1', 'QKCMS', '', 'QKCMS', '建站程序,社区,网站', 'AI助力,零门槛建站 启肯科技官网www.qiken.com', '© 2025 QKCMS.  <a href=\'http://www.qiken.com\' target=\'_blank\'>温州启肯科技有限公司</a> 版权所有', '#10b981', CURRENT_TIMESTAMP, '0', '0', '0', '网站维护中..', '垃圾，骗子，去死，傻逼，脑瘫，杂种，操蛋，滚蛋，色情，赌博，毒品，诈骗，翻墙，传销，造谣，举报，微信，QQ, 广告，代购');";
                $this->conn->query($default_settings_sql);
            }

            // 插入默认会员级别数据，确保网站有必要的权限级别
            if ($tableName === 'levels') {
                $default_levels_sql = "INSERT IGNORE INTO `levels` (`id`, `name`, `icon`, `permissions`) VALUES 
                ('1', '游客', '', '{\"view\":1}'),
                ('2', 'VIP会员', '', '{\"view\":1,\"post\":1}'),
                ('3', '管理员', '', '{\"view\":1,\"post\":1,\"admin\":1}');";
                $this->conn->query($default_levels_sql);
            }

            if ($tableName === 'categories') {
                $this->conn->query("INSERT IGNORE INTO `categories` (`id`,`name`,`description`,`thumbnail`,`keywords`,`template`,`custom_url`,`status`,`display`,`archiveid`,`sort`,`created_at`,`updated_at`) VALUES (1,'默认分类','',NULL,'','list.html',NULL,1,1,0,0,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)");
            }

            // 插入订单模拟数据，仅在首次创建表时执行
            if ($tableName === 'order') {
                $default_order_sql = "INSERT IGNORE INTO `order` (`order_no`, `user_id`, `amount`, `points`, `pay_type`, `created_at`, `pay_time`) VALUES 
                ('ORD20250101001', 1, 100.00, 1000, '微信', '2025-01-01 10:00:00', '2025-01-01 10:05:00'),
                ('ORD20250102002', 1, 200.00, 2000, '支付宝', '2025-01-02 14:30:00', '2025-01-02 14:35:00');";
                $this->conn->query($default_order_sql);
            }

            // 插入默认文章属性数据
            if ($tableName === 'properties') {
                $default_properties_sql = "INSERT IGNORE INTO `properties` (`id`, `name`, `color`, `is_system`, `is_enabled`, `sort_order`) VALUES 
                (0, '普通', '#999999', 1, 1, 0),
                (1, '头条', '#ff0000', 1, 1, 1),
                (2, '热门', '#ff6600', 1, 1, 2),
                (3, '推荐', '#009900', 1, 1, 3),
                (4, '公告', '#0066cc', 1, 1, 4),
                (5, '给力', '#9900cc', 1, 1, 5);";
                $this->conn->query($default_properties_sql);
            }
        }

        return true;
    }

    private function createAdminUser($username, $password)
    {
        try {
            $password_hash = password_hash($password, PASSWORD_DEFAULT);
            $email = 'admin@example.com';

            // 查询是否已存在管理员账号
            $check_stmt = $this->conn->prepare("SELECT id FROM users WHERE username = ? AND levels_id = 3");
            $check_stmt->bind_param("s", $username);
            $check_stmt->execute();
            $result = $check_stmt->get_result();
            $check_stmt->close();

            if ($result->num_rows > 0) {
                // 管理员账号已存在，但仅记录信息，实际密码验证和更新在ensureAdminUser方法中处理
                $this->addStep('创建管理员', '信息', "管理员账户 '$username' 已存在");
                return;
            }

            // 管理员账号不存在，创建新账号
            $insert_stmt = $this->conn->prepare("INSERT IGNORE INTO users (username, password, email, levels_id, status, avatar) VALUES (?, ?, ?, 3, 1, '/assets/images/admin.jpg')");
            $insert_stmt->bind_param("sss", $username, $password_hash, $email);

            if ($insert_stmt->execute()) {
                $this->addStep('创建管理员', '成功', "管理员账户 '$username' 创建完成");
            } else {
                $this->addStep('创建管理员', '警告', "管理员账户 '$username' 创建遇到问题，将在后续步骤中验证并修复");
            }
            $insert_stmt->close();
        } catch (Exception $e) {
            $this->addStep('创建管理员', '警告', '管理员账户处理过程中出现异常，但安装将继续');
        }
    }

    private function ensureAdminUser($username, $password)
    {
        // 查询是否存在该管理员账号
        $stmt = $this->conn->prepare("SELECT id, password FROM users WHERE username = ? AND levels_id = 3");
        $stmt->bind_param("s", $username);
        $stmt->execute();
        $result = $stmt->get_result();
        $stmt->close();

        if ($result->num_rows > 0) {
            $user = $result->fetch_assoc();
            $existing_password_hash = $user['password'];
            $user_id = $user['id'];

            // 验证密码是否匹配
            if (!password_verify($password, $existing_password_hash)) {
                // 密码不匹配，更新密码
                $password_hash = password_hash($password, PASSWORD_DEFAULT);

                $update_stmt = $this->conn->prepare("UPDATE users SET password = ? WHERE id = ?");
                $update_stmt->bind_param("si", $password_hash, $user_id);

                if ($update_stmt->execute()) {
                    $this->addStep('确认管理员', '成功', "管理员账户 '$username' 存在，密码已更新");
                } else {
                    $this->addStep('确认管理员', '警告', "管理员账户 '$username' 存在，但密码更新失败");
                }
                $update_stmt->close();
            } else {
                // 密码匹配
                $this->addStep('确认管理员', '成功', "管理员账户 '$username' 已确认存在且密码正确");
            }
        } else {
            // 管理员账号不存在，创建新账号
            $password_hash = password_hash($password, PASSWORD_DEFAULT);
            $email = 'admin@example.com';

            $insert_stmt = $this->conn->prepare("INSERT IGNORE INTO users (username, password, email, levels_id, status, avatar) VALUES (?, ?, ?, 3, 1, '/assets/images/admin.jpg')");
            $insert_stmt->bind_param("sss", $username, $password_hash, $email);

            if ($insert_stmt->execute()) {
                $this->addStep('确认管理员', '成功', "管理员账户 '$username' 已创建");
            } else {
                $this->addStep('确认管理员', '警告', "管理员账户 '$username' 创建失败，但安装将继续");
            }
            $insert_stmt->close();
        }
    }

    /**
     * 强制设置管理员账号和密码
     * 无论是否存在ID为1的管理员账号，都确保使用用户输入的用户名和密码
     * @param string $username 管理员用户名
     * @param string $password 管理员密码
     */
    private function forceAdminPassword($username, $password)
    {
        $this->addStep('强制设置管理员', '开始', "确保管理员账户使用指定的用户名 '$username' 和密码");

        try {
            // 生成密码哈希
            $password_hash = password_hash($password, PASSWORD_DEFAULT);
            $email = 'admin@example.com';

            // 首先检查ID为1的账号是否存在
            $check_id1_stmt = $this->conn->prepare("SELECT id, username, levels_id FROM users WHERE id = 1");
            $check_id1_stmt->execute();
            $id1_result = $check_id1_stmt->get_result();
            $check_id1_stmt->close();

            $id1_user = $id1_result->fetch_assoc();
            $admin_updated = false;

            // 处理ID为1的账号
            if ($id1_user) {
                // ID为1的账号存在
                if ($id1_user['levels_id'] != 3) {
                    // 如果不是管理员，先将其提升为管理员
                    $update_level_stmt = $this->conn->prepare("UPDATE users SET levels_id = 3 WHERE id = 1");
                    $update_level_stmt->execute();
                    $update_level_stmt->close();
                    $this->addStep('强制设置管理员', '信息', "ID为1的账号已提升为管理员权限");
                }

                // 更新ID为1的账号的用户名和密码
                $update_admin_stmt = $this->conn->prepare("UPDATE users SET username = ?, password = ?, email = ?, status = 1, avatar = '/assets/images/admin.jpg' WHERE id = 1");
                $update_admin_stmt->bind_param("sss", $username, $password_hash, $email);

                if ($update_admin_stmt->execute()) {
                    $this->addStep('强制设置管理员', '成功', "ID为1的管理员账户已更新为用户名 '$username' 和新密码");
                    $admin_updated = true;
                } else {
                    $this->addStep('强制设置管理员', '警告', "更新ID为1的管理员账户失败: " . $this->conn->error);
                }
                $update_admin_stmt->close();
            } else {
                // ID为1的账号不存在，创建一个新的管理员账号
                $insert_admin_stmt = $this->conn->prepare("INSERT INTO users (id, username, password, email, levels_id, status, avatar) VALUES (1, ?, ?, ?, 3, 1, '/assets/images/admin.jpg') ON DUPLICATE KEY UPDATE username = VALUES(username), password = VALUES(password), email = VALUES(email), levels_id = 3, status = 1, avatar = '/assets/images/admin.jpg'");
                $insert_admin_stmt->bind_param("sss", $username, $password_hash, $email);

                if ($insert_admin_stmt->execute()) {
                    $this->addStep('强制设置管理员', '成功', "已创建ID为1的管理员账户，用户名为 '$username'");
                    $admin_updated = true;
                } else {
                    $this->addStep('强制设置管理员', '警告', "创建ID为1的管理员账户失败: " . $this->conn->error);
                }
                $insert_admin_stmt->close();
            }

            // 如果ID为1的账号已处理，检查是否存在其他管理员账号并处理
            if ($admin_updated) {
                // 查找其他管理员账号（levels_id=3但ID不等于1）
                $other_admins_stmt = $this->conn->prepare("SELECT id, username FROM users WHERE levels_id = 3 AND id != 1");
                $other_admins_stmt->execute();
                $other_admins_result = $other_admins_stmt->get_result();
                $other_admins_stmt->close();

                if ($other_admins_result->num_rows > 0) {
                    // 存在其他管理员账号，将其降级为普通用户
                    $demote_stmt = $this->conn->prepare("UPDATE users SET levels_id = 1 WHERE levels_id = 3 AND id != 1");
                    if ($demote_stmt->execute()) {
                        $this->addStep('强制设置管理员', '信息', "已将其他 $other_admins_result->num_rows 个管理员账号降级为普通用户，确保只有ID为1的管理员账号");
                    } else {
                        $this->addStep('强制设置管理员', '警告', "降级其他管理员账号失败: " . $this->conn->error);
                    }
                    $demote_stmt->close();
                }
            }
        } catch (Exception $e) {
            $this->addStep('强制设置管理员', '错误', "强制设置管理员账号和密码时发生异常: " . $e->getMessage());
        }
    }

    private function importSQLData()
    {
        $this->addStep('导入SQL数据', '开始', '开始检查SQL文件');

        set_time_limit(600);
        ini_set('memory_limit', '512M');

        $sql_file_path = null;

        if (isset($_FILES['sql_file']) && $_FILES['sql_file']['error'] === UPLOAD_ERR_OK) {
            $uploaded_file = $_FILES['sql_file'];
            if (pathinfo($uploaded_file['name'], PATHINFO_EXTENSION) === 'sql') {
                $sql_file_path = $uploaded_file['tmp_name'];
                $this->addStep('导入SQL数据', '信息', '使用自定义SQL文件: ' . $uploaded_file['name']);
            }
        }

        if ($sql_file_path === null) {
            $default_sql_path = '../assets/qkcms.sql';
            if (file_exists($default_sql_path)) {
                $sql_file_path = $default_sql_path;
                $this->addStep('导入SQL数据', '信息', '使用默认SQL文件: assets/qkcms.sql');
            }
        }

        if ($sql_file_path !== null) {
            $this->addStep('导入SQL数据', '进行中', '开始导入数据，请稍候...');
            $this->executeSQLImport($sql_file_path);
        } else {
            $this->addStep('导入SQL数据', '跳过', '未找到SQL文件，跳过导入');
        }
    }

    private function executeSQLImport($sql_file_path)
    {
        $start_time = microtime(true);

        try {
            $sql_content = file_get_contents($sql_file_path);
            if ($sql_content === false) {
                $this->addStep('导入SQL数据', '失败', '无法读取SQL文件');
                return false;
            }

            $sql_content = preg_replace('/\-\-.*$/m', '', $sql_content);
            $sql_content = preg_replace('/\/\*(.*?)\*\//s', '', $sql_content);

            $sql_statements = preg_split('/;\s*$/m', $sql_content);
            $sql_statements = array_filter(array_map('trim', $sql_statements));

            $insert_statements = [];
            foreach ($sql_statements as $statement) {
                $statement = trim($statement);
                if (!empty($statement) && stripos($statement, 'INSERT') === 0) {
                    // 对users表的插入语句进行处理
                    if (stripos($statement, 'users') !== false) {
                        // 将普通插入语句转换为INSERT IGNORE，避免重复插入
                        $statement = preg_replace('/^INSERT\s+(INTO\s+)?(users)/i', 'INSERT IGNORE INTO $2', $statement);

                        // 特殊处理管理员账号（levels_id=3）的插入，避免覆盖后续设置的管理员密码
                        // 这里不跳过所有users表插入，只是确保管理员账号由专门的方法处理
                    }
                    $insert_statements[] = $statement;
                }
            }

            $total_statements = count($insert_statements);
            $this->addStep('导入SQL数据', '信息', "准备导入 $total_statements 条数据记录");

            $this->conn->query('SET FOREIGN_KEY_CHECKS=0');
            $this->conn->query('SET UNIQUE_CHECKS=0');
            $this->conn->query('SET AUTOCOMMIT=0');

            $success_count = 0;
            $error_count = 0;
            $batch_size = 50;

            foreach ($insert_statements as $index => $statement) {
                if ($this->conn->query($statement)) {
                    $success_count++;
                } else {
                    $error_count++;
                }

                if (($index + 1) % $batch_size === 0) {
                    $this->conn->query('COMMIT');
                    $this->conn->query('START TRANSACTION');
                }
            }

            $this->conn->query('COMMIT');
            $this->conn->query('SET AUTOCOMMIT=1');
            $this->conn->query('SET UNIQUE_CHECKS=1');
            $this->conn->query('SET FOREIGN_KEY_CHECKS=1');

            $end_time = microtime(true);
            $execution_time = round($end_time - $start_time, 2);

            $message = "SQL数据导入完成，成功: $success_count 条，失败: $error_count 条。耗时: {$execution_time}秒";

            if ($error_count > 0) {
                $this->addStep('导入SQL数据', '警告', $message);
            } else {
                $this->addStep('导入SQL数据', '成功', $message);
            }

            return $success_count > 0;
        } catch (Exception $e) {
            $this->conn->query('SET AUTOCOMMIT=1');
            $this->conn->query('SET UNIQUE_CHECKS=1');
            $this->conn->query('SET FOREIGN_KEY_CHECKS=1');

            $this->addStep('导入SQL数据', '警告', 'SQL导入过程中出现异常');
            return false;
        }
    }

    private function updateConfigFiles($db_host, $db_username, $db_password, $db_name, $mark_installed = false)
    {
        $config_file = __DIR__ . '/../config.php';
        $safe_host = str_replace(["\\", "'"], ["\\\\", "\\'"], (string)$db_host);
        $safe_user = str_replace(["\\", "'"], ["\\\\", "\\'"], (string)$db_username);
        $safe_pass = str_replace(["\\", "'"], ["\\\\", "\\'"], (string)$db_password);
        $safe_name = str_replace(["\\", "'"], ["\\\\", "\\'"], (string)$db_name);

        if (file_exists($config_file)) {
            $content = file_get_contents($config_file);
            if ($content === false) {
                return false;
            }
        } else {
            $content = "<?php\n";
            $content .= "if (!defined('DB_HOST')) define('DB_HOST', getenv('DB_HOST') ?: '{$safe_host}');\n";
            $content .= "if (!defined('DB_USERNAME')) define('DB_USERNAME', getenv('DB_USERNAME') ?: '{$safe_user}');\n";
            $content .= "if (!defined('DB_PASSWORD')) define('DB_PASSWORD', getenv('DB_PASSWORD') ?: '{$safe_pass}');\n";
            $content .= "if (!defined('DB_NAME')) define('DB_NAME', getenv('DB_NAME') ?: '{$safe_name}');\n";
        }

        $content = preg_replace(
            "/if\\s*\\(!defined\\('DB_HOST'\\)\\)\\s*define\\('DB_HOST',\\s*.*?\\);/i",
            "if (!defined('DB_HOST')) define('DB_HOST', getenv('DB_HOST') ?: '{$safe_host}');",
            $content
        );
        $content = preg_replace(
            "/if\\s*\\(!defined\\('DB_USERNAME'\\)\\)\\s*define\\('DB_USERNAME',\\s*.*?\\);/i",
            "if (!defined('DB_USERNAME')) define('DB_USERNAME', getenv('DB_USERNAME') ?: '{$safe_user}');",
            $content
        );
        $content = preg_replace(
            "/if\\s*\\(!defined\\('DB_PASSWORD'\\)\\)\\s*define\\('DB_PASSWORD',\\s*.*?\\);/i",
            "if (!defined('DB_PASSWORD')) define('DB_PASSWORD', getenv('DB_PASSWORD') ?: '{$safe_pass}');",
            $content
        );
        $content = preg_replace(
            "/if\\s*\\(!defined\\('DB_NAME'\\)\\)\\s*define\\('DB_NAME',\\s*.*?\\);/i",
            "if (!defined('DB_NAME')) define('DB_NAME', getenv('DB_NAME') ?: '{$safe_name}');",
            $content
        );

        $content = preg_replace("/define\\('DB_HOST',\\s*'[^']*'\\);/i", "define('DB_HOST', '{$safe_host}');", $content);
        $content = preg_replace("/define\\('DB_USERNAME',\\s*'[^']*'\\);/i", "define('DB_USERNAME', '{$safe_user}');", $content);
        $content = preg_replace("/define\\('DB_PASSWORD',\\s*'[^']*'\\);/i", "define('DB_PASSWORD', '{$safe_pass}');", $content);
        $content = preg_replace("/define\\('DB_NAME',\\s*'[^']*'\\);/i", "define('DB_NAME', '{$safe_name}');", $content);

        if (file_put_contents($config_file, $content) === false) {
            return false;
        }

        if ($mark_installed) {
            $install_file = __DIR__ . '/install.php';
            if (file_exists($install_file)) {
                $content = file_get_contents($install_file);
                if ($content === false) {
                    return false;
                }
                $content = preg_replace('/const\s+DB_INIT_STATUS\s*=\s*[\'"](init|force_init)[\'"];/i', "const DB_INIT_STATUS = 'done';", $content);
                if (file_put_contents($install_file, $content) === false) {
                    return false;
                }
            }
        }
        return true;
    }

    private function addStep($step, $status, $detail)
    {
        $this->steps[] = compact('step', 'status', 'detail');
    }

    private function jsonResponse($success, $message = '', $data = [])
    {
        header('Content-Type: application/json');
        $response = ['success' => $success];
        if ($message) $response['message'] = $message;
        echo json_encode(array_merge($response, $data));
        exit;
    }

    public function __destruct()
    {
        if ($this->conn) {
            $this->conn->close();
        }
    }
}

function checkEnvironment()
{
    $php_version = phpversion();
    $required_php_version = '7.0.0';
    $php_ok = version_compare($php_version, $required_php_version) >= 0;

    $mysql_version = '未知';
    $mysql_service_running = false;
    $mysql_ok = false;

    // 检查mysqli扩展是否加载
    if (extension_loaded('mysqli')) {
        // 定义要测试的主机和端口组合
        $test_hosts = [
            ['localhost', 3306],
            ['127.0.0.1', 3306]
        ];

        // 尝试连接到MySQL服务器来检测服务是否运行
        foreach ($test_hosts as $host_port) {
            $socket = @fsockopen($host_port[0], $host_port[1], $errno, $errstr, 2);
            if ($socket !== false) {
                $mysql_service_running = true;
                fclose($socket);
                break;
            }
        }

        // 如果服务正在运行，尝试获取版本信息
        if ($mysql_service_running) {
            // 先检查是否有用户已经验证过的MySQL凭据
            if (session_status() === PHP_SESSION_NONE) {
                session_start();
            }

            $test_credentials = [];
            // 如果有已验证的凭据，优先使用
            if (isset($_SESSION['db_config'])) {
                $db_config = $_SESSION['db_config'];
                $test_credentials[] = [
                    $db_config['host'],
                    $db_config['username'],
                    $db_config['password']
                ];
            }

            // 尝试连接MySQL以获取版本信息
            foreach ($test_credentials as $cred) {
                $mysqli = @new mysqli($cred[0], $cred[1], $cred[2]);
                if (!$mysqli->connect_error) {
                    $mysql_version = $mysqli->server_info;
                    $mysql_ok = version_compare($mysql_version, '5.0.0') >= 0;
                    $mysqli->close();
                    break;
                }
            }
        }
    }

    $functions_ok = function_exists('password_hash') && function_exists('json_encode');
    $install_ok = $php_ok && $mysql_service_running && $functions_ok;

    return compact('php_version', 'required_php_version', 'php_ok', 'mysql_version', 'mysql_ok', 'mysql_service_running', 'functions_ok', 'install_ok');
}

$installer = new Installer();
$installer->handleRequest();

$env = checkEnvironment();
?>

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>QKCMS——安装向导</title>
    <meta name="keywords" content="QKCMS,轻量级CMS,AI建站系统,企业建站程序,内容管理系统,织梦替代,启肯科技">
    <meta name="description" content="QKCMS采用AI智能技术，标签化模板开发引擎，体积轻巧仅几十KB，比织梦系统更简洁易用。零门槛高效建站系统，让部署变得轻松高效，适合个人与企业快速建站。启肯科技（启肯网络）负责开发运营，专业技术值得信赖。">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif
        }

        body {
            background: #fff;
            color: #333;
            line-height: 1.6;
            min-height: 100vh
        }

        .install-container {
            max-width: 900px;
            margin: 40px auto;
            padding: 0 20px
        }

        .card {
            background: #fff;
            border-radius: 12px;
            border: 1px solid #e2e8f0;
            box-shadow: 0 0px 7px rgba(0, 0, 0, 0.1);
            overflow: visible;
            padding: 30px;
            margin-bottom: 30px;
            transition: all 0.3s ease;
            position: relative
        }

        .card.active {
            border-color: #10B981;
            box-shadow: 0 5px 15px rgba(16, 185, 129, 0.1)
        }

        .card.completed {
            border-color: #e2e8f0;
            background-color: #f8fafc
        }

        .card h2 {
            margin-bottom: 30px;
            padding: 5px 15px;
            border-radius: 10px;
            border-left: 4px solid #10B981
        }

        .btn {
            border: none;
            padding: 12px 30px;
            border-radius: 8px;
            font-size: 16px;
            cursor: pointer;
            transition: all 0.2s ease;
            font-weight: 500;
            text-decoration: none;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            height: 48px;
            min-width: 120px
        }

        .primary-btn {
            background: #10B981;
            color: #fff
        }

        .primary-btn:hover {
            background: #059669;
            transform: translateY(-1px);
            box-shadow: 0 4px 12px rgba(16, 185, 129, 0.2)
        }

        .form-group {
            margin-bottom: 20px
        }

        .form-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: 500;
            color: #334155;
            font-size: 14px
        }

        .form-group input {
            width: 100%;
            padding: 12px 16px;
            border: 1px solid #e2e8f0;
            border-radius: 8px;
            font-size: 14px;
            transition: all 0.2s ease
        }

        .form-group input:focus {
            border-color: #10B981;
            outline: none;
            box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1)
        }

        .form-actions {
            margin-top: 30px;
            display: flex;
            justify-content: flex-end
        }

        .env-check-container {
            display: flex;
            flex-direction: column;
            gap: 24px
        }

        .env-cards-row {
            display: flex;
            gap: 24px;
            flex-wrap: wrap
        }

        .env-card-item {
            flex: 1;
            min-width: 280px;
            background: #ffffff;
            border: 1px solid #e0e0e0;
            border-radius: 8px;
            padding: 24px
        }

        .env-card-header {
            display: flex;
            align-items: center;
            gap: 12px;
            margin-bottom: 16px
        }

        .env-card-icon {
            padding: 0px 15px;
            height: 40px;
            background: #f5f5f5;
            border-radius: 40px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.2rem;
            font-weight: 600;
            color: #666
        }

        .env-card-title {
            font-size: 0.95rem;
            font-weight: 500;
            color: #2c3e50;
            margin: 0;
            display: flex;
            align-items: center;
            flex: 1;
            gap: 10px
        }

        .running-status {
            font-size: 0.75rem;
            color: #10B981;
            font-weight: 500;
            margin-left: auto;
            display: flex;
            align-items: center;
            background: #ebf5fb;
            padding: 3px 10px;
            border-radius: 14px
        }

        .running-status::before {
            content: '⟳';
            color: #10B981;
            font-size: 0.7rem;
            margin-right: 5px;
            animation: spin 1.5s linear infinite;
            display: inline-block
        }

        .env-card-content {
            margin-left: 46px;
            background: transparent;
            padding: 0;
            margin-top: 8px
        }

        .env-card-info {
            margin-bottom: 8px;
            font-size: 14px;
            color: #7f8c8d;
            line-height: 1.4
        }

        .function-check-section {
            background: #ffffff;
            border: 1px solid #e9ecef;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06)
        }

        .function-check-title {
            font-size: 1rem;
            font-weight: 500;
            color: #2c3e50;
            margin: 0 0 16px 0;
            display: flex;
            align-items: center;
            gap: 10px;
            padding-bottom: 10px;
            border-bottom: 0px solid #e9ecef
        }

        .function-check-list {
            list-style: none;
            padding: 0;
            margin: 0
        }

        .function-check-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 12px 0;
            border-bottom: 1px solid #e9ecef
        }

        .function-check-item:last-child {
            border-bottom: none
        }

        .function-name {
            font-size: 0.9rem;
            color: #334155;
            font-weight: 400
        }

        .function-status {
            font-size: 0.8rem;
            color: #334155;
            display: flex;
            align-items: center;
            gap: 5px;
            font-weight: 500
        }

        .check-icon {
            width: 18px;
            height: 18px;
            background: transparent;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 0.7rem;
            font-weight: 600;
            color: #2c3e50
        }

        .progress-bar-container {
            margin: 20px 0
        }

        .progress-info {
            display: flex;
            justify-content: space-between;
            margin-bottom: 8px;
            font-size: 0.9rem;
            color: #6b7280
        }

        .progress-percentage {
            font-weight: 500;
            color: #10B981
        }

        .progress-bar {
            width: 100%;
            height: 10px;
            background: #f3f4f6;
            border-radius: 6px;
            overflow: hidden;
            position: relative
        }

        .progress-fill {
            height: 100%;
            background-color: #10B981;
            border-radius: 6px;
            transition: width 0.3s ease;
            width: 0%
        }

        .installation-logs {
            background: #f9fafb;
            border-radius: 8px;
            border: 1px solid #e5e7eb;
            max-height: 300px;
            overflow-y: auto;
            padding: 20px;
            margin-bottom: 20px
        }

        .log-entry {
            padding: 8px 0;
            border-bottom: 1px solid #f3f4f6;
            font-size: 0.9rem;
            display: flex;
            align-items: flex-start;
            gap: 10px
        }

        .log-entry:last-child {
            border-bottom: none
        }

        .log-icon {
            font-size: 1rem;
            flex-shrink: 0;
            margin-top: 2px
        }

        .status-indicator {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-bottom: 20px;
            padding: 12px 16px;
            text-align: right;
            border-radius: 6px；
        }

        .status-dot {
            width: 10px;
            height: 10px;
            background: #10B981;
            border-radius: 50%;
            animation: pulse 2s infinite
        }

        .error-message {


            padding: 12px 16px;
            border-radius: 6px;
            margin-bottom: 20px;
            font-size: 0.9rem;
            text-align: right;
        }

        .success-icon {
            font-size: 6rem;
            color: #10B981;
            margin-bottom: 20px;
            text-align: center
        }

        .complete-title {
            color: #111827;
            margin-bottom: 16px;
            font-size: 2.2rem;
            font-weight: 600;
            text-align: center
        }

        .complete-description {
            color: #666;
            margin-bottom: 30px;
            font-size: 1.1rem;
            line-height: 1.6;
            text-align: center
        }

        .admin-info {
            background: #f8fafc;
            border-radius: 8px;
            padding: 24px;
            margin-bottom: 30px;
            text-align: left;
            border-left: 4px solid #10B981;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05)
        }

        .admin-info h3 {
            margin-bottom: 16px;
            color: #111827;
            font-size: 1.25rem;
            font-weight: 500
        }

        .admin-info-item {
            margin-bottom: 12px;
            font-size: 1rem;
            display: flex;
            justify-content: space-between;
            align-items: center;
            flex-wrap: wrap
        }

        .admin-info-label {
            color: #4b5563;
            font-weight: 500
        }

        .admin-info-value {
            background: #f1f5f9;
            padding: 4px 12px;
            border-radius: 6px;
            font-family: 'Courier New', monospace;
            color: #10B981;
            font-weight: 500;
            word-break: break-all;
            max-width: 60%;
            text-align: right
        }

        .button-group {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-bottom: 40px;
            flex-wrap: wrap
        }

        .button {
            padding: 12px 30px;
            border-radius: 8px;
            font-size: 1rem;
            font-weight: 600;
            text-decoration: none;
            transition: all 0.3s ease;
            display: inline-block;
            cursor: pointer;
            border: none;
            outline: none;
            min-width: 160px;
            text-align: center
        }

        .button-primary {
            background: #10B981;
            color: #fff;
            box-shadow: 0 4px 14px rgba(16, 185, 129, 0.3)
        }

        .button-primary:hover {
            filter: alpha(opacity:80);
            opacity: 0.8
        }

        .tech-bg {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: -1;
            overflow: hidden
        }

        .grid-lines {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-image: linear-gradient(rgba(16, 185, 129, 0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(16, 185, 129, 0.05) 1px, transparent 1px);
            background-size: 30px 30px;
            animation: gridMove 20s linear infinite
        }

        .welcome-container {
            position: relative;
            text-align: center;
            padding: 80px 20px 0px;
            overflow: hidden
        }

        .hero-title {
            font-size: 3.5rem;
            font-weight: 700;
            color: #0f172a;
            margin-bottom: 16px;
            background: linear-gradient(90deg, #10B981, #3b82f6);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
            display: inline-block;
            position: relative;
            animation: floatUp 0.8s ease-out;
            overflow: hidden
        }

        .hero-title::after {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 50%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.8), transparent);
            animation: sweepLight 2s infinite linear
        }

        .hero-subtitle {
            font-size: 1.25rem;
            color: #64748b;
            max-width: 600px;
            margin: 0 auto 32px;
            animation: floatUp 1s ease-out
        }

        .section-status {
            position: absolute;
            top: 20px;
            right: 20px;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 16px;
            font-weight: bold;
            z-index: 10;

            transition: all 0.3s ease;
        }

        .status-pending {
            background-color: #f3f4f6;
            color: #64748b;
            border: 0px solid #e2e8f0;
        }

        .status-completed {
            background-color: #10B981;
            color: white;
            border: 2px solid #10B981;
        }



        .sql-upload-section {
            margin-top: 20px;
            padding-top: 20px;
            border-top: 0px solid #e2e8f0
        }

        .sql-upload-box {
            background: #f8fafc;
            border: 2px dashed #e2e8f0;
            border-radius: 12px;
            padding: 20px;
            text-align: center;
            transition: all 0.3s ease;
            cursor: pointer;
            margin-top: 15px
        }

        .sql-upload-box:hover {
            border-color: #10B981;
            background: #f0fdf4
        }

        .sql-upload-icon {
            font-size: 36px;
            margin-bottom: 10px
        }

        .sql-upload-text {
            color: #64748b;
            margin-bottom: 15px
        }

        .sql-file-input {
            display: none
        }

        .sql-upload-btn {
            background: #10B981;
            color: #fff;
            border: none;
            padding: 10px 20px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 14px
        }

        .checkbox-group {
            display: flex;
            align-items: center;
            margin-bottom: 15px
        }

        .checkbox-group input[type="checkbox"] {
            margin-right: 10px;
            width: 18px;
            height: 18px
        }

        @keyframes spin {
            from {
                transform: rotate(0deg)
            }

            to {
                transform: rotate(360deg)
            }
        }

        @keyframes gridMove {
            0% {
                transform: translateY(0)
            }

            100% {
                transform: translateY(-30px)
            }
        }

        @keyframes floatUp {
            0% {
                opacity: 0;
                transform: translateY(20px)
            }

            100% {
                opacity: 1;
                transform: translateY(0)
            }
        }

        @keyframes pulse {

            0%,
            100% {
                opacity: 1
            }

            50% {
                opacity: 0.5
            }
        }

        @keyframes sweepLight {
            0% {
                left: -100%
            }

            100% {
                left: 200%
            }
        }

        @media (max-width:768px) {
            .env-cards-row {
                flex-direction: column
            }

            .install-container {
                margin: 20px auto
            }

            .card {
                padding: 20px
            }

            .admin-info-item {
                flex-direction: column;
                align-items: flex-start;
                gap: 8px
            }

            .admin-info-value {
                text-align: left;
                max-width: 100%;
                width: 100%
            }
        }
    </style>
</head>

<body>
    <div class="tech-bg">
        <div class="grid-lines"></div>
    </div>
    <div class="welcome-container">
        <div class="hero-section">
            <h1 class="hero-title">QKCMS 智能网站程序</h1>
            <p class="hero-subtitle">AI助力，零门槛建站，简单部署，强大功能</p>
        </div>
    </div>
    <div class="install-wrapper">
        <div class="install-container">
            <div class="section-container">
                <div class="card" id="environment-card">
                    <div class="section-status status-pending" id="environment-status">1</div>
                    <h2>环境检查</h2>
                    <div class="env-check-container">
                        <div class="env-cards-row">
                            <div class="env-card-item">
                                <div class="env-card-header">
                                    <div class="env-card-icon">PHP</div>
                                    <h3 class="env-card-title">PHP 运行环境 <span class="running-status">服务运行中</span></h3>
                                </div>
                                <div class="env-card-content">
                                    <div class="env-card-info"> <span>当前版本:</span> <?php echo $env['php_version']; ?> </div>
                                    <div class="env-card-info"> <span>程序要求:</span> <?php echo $env['required_php_version']; ?> + </div>
                                </div>
                            </div>
                            <div class="env-card-item">
                                <div class="env-card-header">
                                    <div class="env-card-icon">SQL</div>
                                    <h3 class="env-card-title">数据库服务 <span class="running-status" style="color: <?php echo $env['mysql_service_running'] ? '#10b981' : '#ef4444'; ?>"><?php echo $env['mysql_service_running'] ? '服务运行中' : '服务未启动'; ?></span></h3>
                                </div>
                                <div class="env-card-content">
                                    <div class="env-card-info"> <span>当前版本:</span> <?php echo $env['mysql_version']; ?> </div>
                                    <div class="env-card-info"> <span>程序要求:</span> 5.1.0+ </div>
                                </div>
                            </div>
                        </div>
                        <div class="function-check-section">
                            <h3 class="function-check-title"> <span class="env-card-icon">⚙</span> 核心功能检查 </h3>
                            <ul class="function-check-list">
                                <li class="function-check-item"> <span class="function-name">密码加密 (password_hash)</span> <span class="function-status"> <span class="check-icon">✓</span> 已启用 </span> </li>
                                <li class="function-check-item"> <span class="function-name">数据处理 (json_encode)</span> <span class="function-status"> <span class="check-icon">✓</span> 已启用 </span> </li>
                                <li class="function-check-item"> <span class="function-name">文件上传支持</span> <span class="function-status"> <span class="check-icon">✓</span> 已启用 </span> </li>
                                <li class="function-check-item"> <span class="function-name">GD 图像处理</span> <span class="function-status"> <span class="check-icon">✓</span> 已启用 </span> </li>
                            </ul>
                        </div>
                    </div>
                    <div class="form-actions">
                        <button type="button" class="btn primary-btn" id="check-environment-btn" <?php if (!$env['install_ok']) echo ' disabled style="background-color: #9cb2bd;"'; ?>> <?php echo $env['install_ok'] ? '环境检查通过，继续' : '环境检查不通过，无法继续'; ?> </button>
                    </div>
                </div>
            </div>
            <div class="section-container">
                <div class="card" id="database-card" style="display: none;">
                    <div class="section-status status-pending" id="database-status">2</div>
                    <h2>数据库配置</h2>
                    <div class="form-group">
                        <label for="db_host">数据库主机</label>
                        <input type="text" id="db_host" name="db_host" value="localhost" placeholder="数据库主机地址">
                    </div>
                    <div class="form-group">
                        <label for="db_name">数据库名称：</label>
                        <input type="text" id="db_name" name="db_name" value="" placeholder="要创建的数据库名称">
                    </div>
                    <div class="form-group">
                        <label for="db_username">数据库用户名</label>
                        <input type="text" id="db_username" name="db_username" value="" placeholder="数据库用户名">
                    </div>
                    <div class="form-group">
                        <label for="db_password">数据库密码</label>
                        <input type="password" id="db_password" name="db_password" placeholder="数据库密码">
                    </div>
                    <div class="sql-upload-section">
                        <div class="checkbox-group">
                            <input type="checkbox" id="enable-sql-import" name="enable_sql_import" checked>
                            <label for="enable-sql-import">导入SQL数据文件（可选）</label>
                        </div>
                        <div class="sql-upload-box" id="sql-upload-container" style="display: block;">
                            <div class="sql-upload-icon">📁</div>
                            <div class="sql-upload-text">
                                <p style="margin-bottom:10px" id="selected-sql-path">默认测试数据SQL文件: ../assets/qkcms.sql</p>
                                <p style="font-size:12px">选择SQL文件，可在初始化中导入数据库</p>
                            </div>
                            <input type="file" id="sql-file" class="sql-file-input" accept=".sql">
                            <button type="button" id="select-sql-btn" class="sql-upload-btn">选择文件</button>
                        </div>
                    </div>
                    <div class="form-actions" style="display: flex; align-items: center;">
                        <div id="database-message" style="display: none; height: 48px; display: flex; align-items: center; flex: 1; margin-bottom: 0; color: #dc2626; font-size: 0.9rem;"></div>
                        <button type="button" class="btn primary-btn" id="test-db-connection" style="margin-left: auto;">继续下一步</button>
                    </div>
                </div>
            </div>
            <div class="section-container">
                <div class="card" id="admin-card" style="display: none;">
                    <div class="section-status status-pending" id="admin-status">3</div>
                    <h2>管理员账户设置</h2>
                    <div class="form-group">
                        <label for="admin_username">管理员用户名</label>
                        <input type="text" id="admin_username" name="admin_username" value="admin" placeholder="管理员用户名">
                    </div>
                    <div class="form-group">
                        <label for="admin_password">管理员密码</label>
                        <input type="password" id="admin_password" name="admin_password" placeholder="管理员密码">
                    </div>
                    <div class="form-actions">
                        <button type="button" class="btn primary-btn" id="start-installation">开始安装</button>
                    </div>
                </div>
            </div>
            <div class="section-container">
                <div class="card" id="progress-card" style="display: none;">
                    <div class="section-status status-pending" id="progress-status">4</div>
                    <h2>安装进度</h2>
                    <div class="status-indicator" id="installation-status" style="display: none;">
                        <div class="status-dot"></div>
                        <div class="status-text">正在安装，请稍候...</div>
                    </div>
                    <div class="progress-bar-container">
                        <div class="progress-info">
                            <div class="progress-label">安装进度</div>
                            <div class="progress-percentage" id="progress-percentage">0%</div>
                        </div>
                        <div class="progress-bar">
                            <div class="progress-fill" id="progress-fill"></div>
                        </div>
                    </div>
                    <div class="installation-logs" id="installation-logs"></div>
                </div>
            </div>
            <div class="section-container">
                <div class="card" id="complete-card" style="display: none;">
                    <div class="section-status status-pending" id="complete-status">5</div>
                    <div class="success-icon">✓</div>
                    <h1 class="complete-title">安装完成！</h1>
                    <p class="complete-description"> 恭喜你，QKCMS智能建站程序已经安装成功！ </p>
                    <div class="admin-info">
                        <h3>管理员信息</h3>
                        <div class="admin-info-item"> <span class="admin-info-label">用户名:</span> <span class="admin-info-value" id="final-admin-username"></span> </div>
                        <div class="admin-info-item"> <span class="admin-info-label">数据库名称:</span> <span class="admin-info-value" id="final-db-name"></span> </div>
                    </div>
                    <div class="button-group"> <a href="../index.php" class="button button-primary">进入首页</a> <a href="../admin/" class="button button-primary">管理后台</a> </div>
                </div>
            </div>
        </div>
    </div>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const environmentCard = document.getElementById('environment-card');
            const databaseCard = document.getElementById('database-card');
            const adminCard = document.getElementById('admin-card');
            const progressCard = document.getElementById('progress-card');
            const completeCard = document.getElementById('complete-card');

            const checkEnvironmentBtn = document.getElementById('check-environment-btn');
            const testDbConnectionBtn = document.getElementById('test-db-connection');
            const startInstallationBtn = document.getElementById('start-installation');

            const databaseMessage = document.getElementById('database-message');
            const installationLogs = document.getElementById('installation-logs');
            const progressFill = document.getElementById('progress-fill');
            const progressPercentage = document.getElementById('progress-percentage');
            const installationStatus = document.getElementById('installation-status');

            const finalAdminUsername = document.getElementById('final-admin-username');
            const finalDbName = document.getElementById('final-db-name');

            const enableSqlImport = document.getElementById('enable-sql-import');
            const sqlUploadContainer = document.getElementById('sql-upload-container');
            const sqlFileInput = document.getElementById('sql-file');
            const selectSqlBtn = document.getElementById('select-sql-btn');
            const selectedSqlPath = document.getElementById('selected-sql-path');

            const environmentStatus = document.getElementById('environment-status');
            const databaseStatus = document.getElementById('database-status');
            const adminStatus = document.getElementById('admin-status');
            const progressStatus = document.getElementById('progress-status');
            const completeStatus = document.getElementById('complete-status');

            enableSqlImport.addEventListener('change', function() {
                sqlUploadContainer.style.display = this.checked ? 'block' : 'none';
                if (!this.checked) {
                    sqlFileInput.value = '';
                    selectedSqlPath.textContent = '将使用默认SQL文件: assets/qkcms.sql';
                }
            });

            selectSqlBtn.addEventListener('click', function() {
                sqlFileInput.click();
            });

            sqlFileInput.addEventListener('change', function(e) {
                const file = e.target.files[0];
                selectedSqlPath.textContent = file ? '已选择文件: ' + file.name : '将使用默认SQL文件: assets/qkcms.sql';
            });

            checkEnvironmentBtn.addEventListener('click', function() {
                environmentCard.classList.add('completed');
                environmentStatus.classList.remove('status-pending');
                environmentStatus.classList.add('status-completed');
                environmentStatus.textContent = '✓';

                databaseCard.style.display = 'block';
                databaseCard.classList.add('active');
                databaseCard.scrollIntoView({
                    behavior: 'smooth'
                });
            });

            testDbConnectionBtn.addEventListener('click', function() {
                const dbHost = document.getElementById('db_host').value;
                const dbUsername = document.getElementById('db_username').value;
                const dbPassword = document.getElementById('db_password').value;
                const dbName = document.getElementById('db_name').value;

                if (!dbHost || !dbUsername || !dbName) {
                    showDatabaseMessage('请填写必要的数据库信息');
                    return;
                }

                fetch('', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/x-www-form-urlencoded'
                        },
                        body: `action=validate_database&db_host=${encodeURIComponent(dbHost)}&db_username=${encodeURIComponent(dbUsername)}&db_password=${encodeURIComponent(dbPassword)}&db_name=${encodeURIComponent(dbName)}`
                    })
                    .then(response => response.json())
                    .then(data => {
                        if (data.success) {
                            showDatabaseMessage(data.message, false);
                            databaseCard.classList.remove('active');
                            databaseCard.classList.add('completed');
                            databaseStatus.classList.remove('status-pending');
                            databaseStatus.classList.add('status-completed');
                            databaseStatus.textContent = '✓';

                            adminCard.style.display = 'block';
                            adminCard.classList.add('active');
                            adminCard.scrollIntoView({
                                behavior: 'smooth'
                            });
                        } else {
                            showDatabaseMessage(data.message);
                        }
                    })
                    .catch(error => {
                        showDatabaseMessage('连接失败: ' + error.message);
                    });
            });

            let currentProgress = 0;

            function updateProgress(targetProgress) {
                currentProgress = targetProgress;
                progressFill.style.width = currentProgress + '%';
                progressPercentage.textContent = Math.floor(currentProgress) + '%';
            }

            startInstallationBtn.addEventListener('click', function() {
                const adminUsername = document.getElementById('admin_username').value;
                const adminPassword = document.getElementById('admin_password').value;
                const enableSqlImportValue = enableSqlImport.checked ? 'on' : 'off';

                if (!adminUsername || !adminPassword) {
                    alert('请填写管理员用户名和密码');
                    return;
                }

                adminCard.classList.remove('active');
                adminCard.classList.add('completed');
                adminStatus.classList.remove('status-pending');
                adminStatus.classList.add('status-completed');
                adminStatus.textContent = '✓';

                progressCard.style.display = 'block';
                progressCard.classList.add('active');
                progressCard.scrollIntoView({
                    behavior: 'smooth'
                });
                installationStatus.style.display = 'flex';

                addLogEntry('信息', '安装准备', '正在准备安装环境...');
                updateProgress(5);

                const formData = new FormData();
                formData.append('action', 'start_installation');
                formData.append('admin_username', adminUsername);
                formData.append('admin_password', adminPassword);
                formData.append('enable_sql_import', enableSqlImportValue);

                if (sqlFileInput.files.length > 0) {
                    formData.append('sql_file', sqlFileInput.files[0]);
                }

                fetch('', {
                        method: 'POST',
                        body: formData
                    })
                    .then(response => response.json())
                    .then(data => {
                        let currentIndex = 0;
                        const totalSteps = data.steps.length;

                        function processNextStep() {
                            if (currentIndex >= totalSteps) {
                                if (data.success) {
                                    updateProgress(100);
                                    progressCard.classList.remove('active');
                                    progressCard.classList.add('completed');
                                    progressStatus.classList.remove('status-pending');
                                    progressStatus.classList.add('status-completed');
                                    progressStatus.textContent = '✓';

                                    finalAdminUsername.textContent = data.admin_username;
                                    finalDbName.textContent = data.db_name;
                                    completeCard.style.display = 'block';
                                    completeCard.classList.add('active');
                                    completeStatus.classList.remove('status-pending');
                                    completeStatus.classList.add('status-completed');
                                    completeStatus.textContent = '✓';
                                    completeCard.scrollIntoView({
                                        behavior: 'smooth'
                                    });
                                } else {
                                    progressStatus.classList.remove('status-pending');
                                    progressStatus.classList.add('status-error');
                                    progressStatus.textContent = '!';
                                }
                                installationStatus.style.display = 'none';
                                return;
                            }

                            const step = data.steps[currentIndex];
                            addLogEntry(step.status, step.step, step.detail);

                            const progress = Math.round(((currentIndex + 1) / totalSteps) * 100);
                            updateProgress(progress);

                            currentIndex++;
                            setTimeout(processNextStep, 50);
                        }

                        processNextStep();
                    })
                    .catch(error => {
                        addLogEntry('错误', '安装过程', '安装失败: ' + error.message);
                        progressStatus.classList.remove('status-pending');
                        progressStatus.classList.add('status-error');
                        progressStatus.textContent = '!';
                        installationStatus.style.display = 'none';
                    });
            });

            function showDatabaseMessage(message, isError = true) {
                databaseMessage.textContent = message;
                databaseMessage.style.display = 'block';
                databaseMessage.className = isError ? 'error-message' : 'status-indicator';

                if (!isError) {
                    setTimeout(() => databaseMessage.style.display = 'none', 5000);
                }
            }

            function addLogEntry(status, title, detail) {
                const icons = {
                    '成功': '✓',
                    '失败': '❌',
                    '开始': '▶️',
                    '跳过': '⏭️',
                    '信息': 'ℹ️',
                    '警告': '⚠️'
                };
                const icon = icons[status] || 'ℹ️';

                const logEntry = document.createElement('div');
                logEntry.className = 'log-entry';
                logEntry.innerHTML = `
                    <div class="log-icon">${icon}</div>
                    <div class="log-info">
                        <div class="log-title">${title} [${status}]</div>
                        <div class="log-detail">${detail}</div>
                    </div>
                `;
                installationLogs.appendChild(logEntry);
                installationLogs.scrollTop = installationLogs.scrollHeight;
            }
        });
    </script>
</body>

</html>
