<?php
/**
 * 芋头CMS（yutoucms）
 * 安装向导 - 第 2 步：数据库配置
 */

function installReadSqlStatements($file)
{
    $content = file_get_contents($file);
    if ($content === false) {
        throw new Exception('无法读取数据库快照文件：' . basename($file));
    }

    if (substr($content, 0, 2) === "\xFF\xFE") {
        if (function_exists('mb_convert_encoding')) {
            $content = mb_convert_encoding(substr($content, 2), 'UTF-8', 'UTF-16LE');
        } else {
            $content = iconv('UTF-16LE', 'UTF-8//IGNORE', substr($content, 2));
        }
    } elseif (substr($content, 0, 2) === "\xFE\xFF") {
        if (function_exists('mb_convert_encoding')) {
            $content = mb_convert_encoding(substr($content, 2), 'UTF-8', 'UTF-16BE');
        } else {
            $content = iconv('UTF-16BE', 'UTF-8//IGNORE', substr($content, 2));
        }
    }

    if (substr($content, 0, 3) === "\xEF\xBB\xBF") {
        $content = substr($content, 3);
    }

    $content = str_replace("\r", '', $content);
    $lines = explode("\n", $content);
    $statements = [];
    $buffer = '';

    foreach ($lines as $line) {
        $trimmed = trim($line);
        if ($trimmed === '' || strpos($trimmed, '-- ') === 0 || $trimmed === '--' || strpos($trimmed, '#') === 0) {
            continue;
        }

        $buffer .= $line . "\n";
        if (substr(rtrim($trimmed), -1) === ';') {
            $sql = trim($buffer);
            if ($sql !== '' && $sql !== ';') {
                $statements[] = $sql;
            }
            $buffer = '';
        }
    }

    $buffer = trim($buffer);
    if ($buffer !== '' && $buffer !== ';') {
        $statements[] = $buffer;
    }

    return $statements;
}

function installEnsureSnapshotSchema(PDO $pdo, $schemaFile)
{
    if (!file_exists($schemaFile)) {
        return;
    }

    foreach (installReadSqlStatements($schemaFile) as $sql) {
        $pdo->exec($sql);
    }
}

function installBuildBaseUrl()
{
    $https = (!empty($_SERVER['HTTPS']) && strtolower((string) $_SERVER['HTTPS']) !== 'off')
        || (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower((string) $_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https')
        || ((string) ($_SERVER['SERVER_PORT'] ?? '') === '443');
    $scheme = $https ? 'https' : 'http';
    $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
    $scriptDir = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'] ?? '/install/index.php'));
    $basePath = trim(str_replace('/install', '', $scriptDir), '/');

    return $scheme . '://' . $host . ($basePath === '' ? '' : '/' . $basePath);
}

function installNormalizeSnapshotUrls(PDO $pdo, $prefix, $baseUrl)
{
    $baseUrl = rtrim($baseUrl, '/');
    $host = parse_url($baseUrl, PHP_URL_HOST) ?: ($_SERVER['HTTP_HOST'] ?? 'localhost');
    $replaceMap = [
        'config' => ['config_value'],
        'article' => ['litpic', 'content', 'redirect_url'],
        'channel' => ['redirect_url'],
        'custom_var' => ['var_value'],
        'download' => ['file_path', 'content'],
        'image' => ['litpic', 'albums', 'content'],
        'page' => ['page_content'],
        'product' => ['litpic', 'pictures', 'content', 'redirect_url'],
        'slide' => ['litpic', 'link'],
    ];

    foreach ($replaceMap as $table => $columns) {
        foreach ($columns as $column) {
            $pdo->exec(sprintf(
                "UPDATE `%s%s` SET `%s` = REPLACE(`%s`, 'http://127.0.0.1', '%s') WHERE `%s` LIKE '%%127.0.0.1%%'",
                $prefix,
                $table,
                $column,
                $column,
                addslashes($baseUrl),
                $column
            ));
        }
    }

    $siteUrl = $baseUrl . '/';
    $stmt = $pdo->prepare("UPDATE `{$prefix}config` SET config_value = ? WHERE config_key = 'site_url'");
    $stmt->execute([$siteUrl]);

    $stmt = $pdo->prepare("UPDATE `{$prefix}license` SET license_domain = ? WHERE license_domain IS NOT NULL");
    $stmt->execute([$host]);
}

function installConnectDatabase($dbHost, $dbPort, $dbName, $dbUser, $dbPass)
{
    $serverDsn = "mysql:host={$dbHost};port={$dbPort};charset=utf8mb4";
    $databaseDsn = "mysql:host={$dbHost};port={$dbPort};dbname={$dbName};charset=utf8mb4";

    try {
        $pdo = new PDO($databaseDsn, $dbUser, $dbPass);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $pdo->exec("SET NAMES utf8mb4");

        return $pdo;
    } catch (PDOException $existingDbException) {
        $pdo = new PDO($serverDsn, $dbUser, $dbPass);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $pdo->exec("CREATE DATABASE IF NOT EXISTS `{$dbName}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
        $pdo->exec("USE `{$dbName}`");
        $pdo->exec("SET NAMES utf8mb4");

        return $pdo;
    }
}

$error = '';
$success = false;
$snapshotFile = ROOT_PATH . 'install/data_snapshot.sql';
$schemaFullSnapshotFile = ROOT_PATH . 'install/schema_full_snapshot.sql';
$hasSnapshot = file_exists($snapshotFile);

$db_host = isset($_POST['db_host']) ? trim($_POST['db_host']) : '127.0.0.1';
$db_port = isset($_POST['db_port']) ? trim($_POST['db_port']) : '3306';
$db_name = isset($_POST['db_name']) ? trim($_POST['db_name']) : '';
$db_user = isset($_POST['db_user']) ? trim($_POST['db_user']) : '';
$db_pass = isset($_POST['db_pass']) ? (string) $_POST['db_pass'] : '';
$db_prefix = isset($_POST['db_prefix']) ? trim($_POST['db_prefix']) : ($hasSnapshot ? 'yutou_' : 'ec_');

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if ($hasSnapshot) {
        $db_prefix = 'yutou_';
    }

    if ($db_name === '') {
        $error = '数据库名称不能为空。';
    } elseif ($db_user === '') {
        $error = '数据库用户名不能为空。';
    } elseif ($db_prefix === '') {
        $error = '数据表前缀不能为空。';
    } else {
        try {
            $pdo = installConnectDatabase($db_host, $db_port, $db_name, $db_user, $db_pass);

            $configArray = [
                'type' => 'mysql',
                'host' => $db_host,
                'port' => (int) $db_port,
                'database' => $db_name,
                'username' => $db_user,
                'password' => $db_pass,
                'charset' => 'utf8mb4',
                'prefix' => $db_prefix,
                'collation' => 'utf8mb4_unicode_ci',
            ];
            $dbConfig = "<?php\nreturn " . var_export($configArray, true) . ";\n";

            file_put_contents(CORE_PATH . 'db/config.php', $dbConfig);
            if (!is_dir(DATA_PATH)) {
                @mkdir(DATA_PATH, 0755, true);
            }
            file_put_contents(DATA_PATH . 'config.php', $dbConfig);

            if ($hasSnapshot) {
                installEnsureSnapshotSchema($pdo, $schemaFullSnapshotFile);

                foreach (installReadSqlStatements($snapshotFile) as $sql) {
                    $pdo->exec($sql);
                }

                $pdo->exec("DELETE FROM `{$db_prefix}license`");
                $licenseCode = 'FREE-' . strtoupper(substr(md5($_SERVER['HTTP_HOST'] ?? 'localhost'), 0, 8));
                $siteId = 'EC' . date('Ymd') . strtoupper(substr(md5(uniqid((string) mt_rand(), true)), 0, 8));
                $now = time();
                $stmt = $pdo->prepare("INSERT INTO `{$db_prefix}license` (license_code, license_domain, license_level, license_expire, site_id, bind_count, max_domains, license_status, create_time, update_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
                $stmt->execute([
                    $licenseCode,
                    $_SERVER['HTTP_HOST'] ?? 'localhost',
                    1,
                    null,
                    $siteId,
                    1,
                    1,
                    1,
                    $now,
                    $now,
                ]);

                installNormalizeSnapshotUrls($pdo, $db_prefix, installBuildBaseUrl());
                $_SESSION['install_import_snapshot'] = 1;
            } else {
                $schema = require CORE_PATH . 'db/schema.php';
                $failed = [];
                foreach ($schema as $table => $sql) {
                    $sql = str_replace('{prefix}', $db_prefix, $sql);
                    try {
                        $pdo->exec($sql);
                    } catch (PDOException $e) {
                        $failed[] = "表 {$table} 创建失败：" . $e->getMessage();
                    }
                }

                if (!empty($failed)) {
                    throw new Exception(implode("\n", $failed));
                }

                $defaultConfigs = [
                    ['site_name', '芋头CMS网站', 'text', 'basic'],
                    ['site_title', '芋头CMS（yutoucms）', 'text', 'basic'],
                    ['site_keywords', '芋头CMS,企业建站系统', 'text', 'basic'],
                    ['site_description', '芋头CMS 企业网站内容管理系统', 'textarea', 'basic'],
                    ['site_icp', '', 'text', 'basic'],
                    ['site_copyright', 'Copyright © ' . date('Y'), 'text', 'basic'],
                    ['site_code', '', 'text', 'basic'],
                    ['smtp_host', '', 'text', 'email'],
                    ['smtp_port', '25', 'text', 'email'],
                    ['smtp_user', '', 'text', 'email'],
                    ['smtp_pass', '', 'password', 'email'],
                    ['smtp_email', '', 'text', 'email'],
                    ['upload_max_size', '20971520', 'text', 'upload'],
                    ['upload_exts', 'jpg,jpeg,gif,png,bmp,zip,rar,doc,docx,xls,xlsx,pdf', 'text', 'upload'],
                ];

                $stmt = $pdo->prepare("INSERT INTO `{$db_prefix}config` (config_key, config_value, config_type, config_group) VALUES (?, ?, ?, ?)");
                foreach ($defaultConfigs as $item) {
                    $stmt->execute($item);
                }

                $adminPassword = password_hash('admin123', PASSWORD_DEFAULT);
                $stmt = $pdo->prepare("INSERT INTO `{$db_prefix}admin` (username, password, realname, create_time) VALUES (?, ?, ?, ?)");
                $stmt->execute(['admin', $adminPassword, '管理员', time()]);
                $pdo->exec("DELETE FROM `{$db_prefix}license`");
                $licenseCode = 'FREE-' . strtoupper(substr(md5($_SERVER['HTTP_HOST'] ?? 'localhost'), 0, 8));
                $siteId = 'EC' . date('Ymd') . strtoupper(substr(md5(uniqid((string) mt_rand(), true)), 0, 8));
                $now = time();
                $stmt = $pdo->prepare("INSERT INTO `{$db_prefix}license` (license_code, license_domain, license_level, license_expire, site_id, bind_count, max_domains, license_status, create_time, update_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
                $stmt->execute([
                    $licenseCode,
                    $_SERVER['HTTP_HOST'] ?? 'localhost',
                    1,
                    null,
                    $siteId,
                    1,
                    1,
                    1,
                    $now,
                    $now,
                ]);
                $_SESSION['install_import_snapshot'] = 0;
            }

            require_once CORE_PATH . 'lib/license.php';
            try {
                $installLicense = new \Core\Lib\License();
                $installLicense->reportInstallation(true, 'install');
            } catch (\Throwable $e) {}

            $success = true;
        } catch (PDOException $e) {
            $message = $e->getMessage();
            if (stripos($message, 'CREATE DATABASE') !== false || stripos($message, 'Access denied') !== false) {
                $message .= '。当前数据库账号可能没有建库权限，请先在空间面板中手动创建数据库后再安装。';
            }
            $error = '数据库连接或写入失败：' . $message;
        } catch (Exception $e) {
            $error = '安装失败：' . $e->getMessage();
        }
    }
}
?>
<div class="step-content">
    <div class="content-head">
        <h3>数据库配置</h3>
        <p>填写 MySQL 连接信息。检测到示例快照时，安装过程会自动恢复演示站点数据。</p>
    </div>

    <?php if ($hasSnapshot): ?>
    <div class="alert alert-success">
        已检测到示例数据安装包。本次安装会自动导入演示数据，数据表前缀固定为 <strong>yutou_</strong>。
    </div>
    <?php endif; ?>

    <?php if ($error !== ''): ?>
    <div class="alert alert-error"><?php echo htmlspecialchars($error); ?></div>
    <?php endif; ?>

    <?php if ($success): ?>
    <div class="alert alert-success">
        数据库配置完成，<?php echo $hasSnapshot ? '示例数据已导入。' : '系统基础数据已初始化。'; ?>
    </div>
    <div class="btn-box">
        <a href="?step=3" class="btn btn-primary">下一步</a>
    </div>
    <?php else: ?>
    <form method="post" class="form">
        <div class="grid-two">
            <div class="form-group">
                <label>数据库地址</label>
                <input type="text" name="db_host" value="<?php echo htmlspecialchars($db_host); ?>" required>
            </div>
            <div class="form-group">
                <label>数据库端口</label>
                <input type="text" name="db_port" value="<?php echo htmlspecialchars($db_port); ?>" required>
            </div>
        </div>
        <div class="grid-two">
            <div class="form-group">
                <label>数据库名称</label>
                <input type="text" name="db_name" value="<?php echo htmlspecialchars($db_name); ?>" required placeholder="请输入数据库名称">
            </div>
            <div class="form-group">
                <label>数据库用户</label>
                <input type="text" name="db_user" value="<?php echo htmlspecialchars($db_user); ?>" required placeholder="请输入数据库用户名">
            </div>
        </div>
        <div class="grid-two">
            <div class="form-group">
                <label>数据库密码</label>
                <input type="password" name="db_pass" value="<?php echo htmlspecialchars($db_pass); ?>" placeholder="留空表示无密码">
            </div>
            <div class="form-group">
                <label>数据表前缀</label>
                <input type="text" name="db_prefix" value="<?php echo htmlspecialchars($db_prefix); ?>" <?php echo $hasSnapshot ? 'readonly' : ''; ?> required>
                <span class="hint"><?php echo $hasSnapshot ? '示例数据安装包固定使用 yutou_。' : '建议使用独立前缀提升安全性。'; ?></span>
            </div>
        </div>

        <div class="tip-box">
            <strong>安装提示</strong>
            <p>安装器会优先连接已有数据库；若数据库不存在，才尝试自动创建。虚拟主机若无建库权限，请先在空间面板中手动创建数据库后再继续安装。</p>
        </div>

        <div class="btn-box">
            <a href="?step=1" class="btn btn-default">上一步</a>
            <button type="submit" class="btn btn-primary">保存并导入数据</button>
        </div>
    </form>
    <?php endif; ?>
</div>
