<?php
/**
 * 授权中心 · 安装向导
 *
 * v1.0.1 修正：
 * 1. 不再重复定义 LIC_ROOT（原来会报 Constant LIC_ROOT already defined）
 * 2. 先验证数据库能连通，再写配置；参数填错不会把配置写死
 * 3. 已经装过但数据库连不上的情况，可以直接在这一页改配置修好，不用删文件重装
 */
require_once __DIR__ . '/inc/core.php';

$installed = lic_installed();
$oldCfg = lic_config();
$oldDb = (isset($oldCfg['db']) && is_array($oldCfg['db'])) ? lic_db_normalize($oldCfg['db']) : lic_db_normalize(array());

$dbOk = false;
$dbErr = '';
$dbRaw = '';
if ($installed) {
    $t = lic_test_db($oldDb);
    $dbOk = $t['ok'];
    $dbErr = $t['msg'];
    $dbRaw = $t['raw'];
}

$isRepair = $installed && !$dbOk;      // 已装但连不上 → 修复模式
$canSubmit = (!$installed) || $isRepair;

$errors = array();
$done = false;
$doneRepair = false;

$checks = array();
$checks[] = array('PHP ≥ 7.4', version_compare(PHP_VERSION, '7.4.0', '>='), PHP_VERSION);
$checks[] = array('PDO 扩展', extension_loaded('pdo'), extension_loaded('pdo') ? '已启用' : '未启用');
$checks[] = array('pdo_mysql / pdo_sqlite', extension_loaded('pdo_mysql') || extension_loaded('pdo_sqlite'),
    extension_loaded('pdo_mysql') ? 'pdo_mysql 已启用' : (extension_loaded('pdo_sqlite') ? 'pdo_sqlite 已启用' : '都没启用'));
$checks[] = array('curl 扩展（易支付用）', extension_loaded('curl'), extension_loaded('curl') ? '已启用' : '未启用，在线支付会失败');
$checks[] = array('data 目录可写', is_dir(LIC_ROOT . '/data') && is_writable(LIC_ROOT . '/data'),
    is_dir(LIC_ROOT . '/data') ? (is_writable(LIC_ROOT . '/data') ? '可写' : '不可写，请 chmod 755') : '目录不存在');
$checks[] = array('inc 目录可写', is_dir(LIC_ROOT . '/inc') && is_writable(LIC_ROOT . '/inc'),
    is_dir(LIC_ROOT . '/inc') ? (is_writable(LIC_ROOT . '/inc') ? '可写' : '不可写，请 chmod 755') : '目录不存在');

if ($_SERVER['REQUEST_METHOD'] === 'POST' && $canSubmit) {

    $driver    = (isset($_POST['driver']) && $_POST['driver'] === 'sqlite') ? 'sqlite' : 'mysql';
    $host      = trim(isset($_POST['host']) ? (string) $_POST['host'] : '127.0.0.1');
    $port      = intval(isset($_POST['port']) ? $_POST['port'] : 3306);
    $name      = trim(isset($_POST['name']) ? (string) $_POST['name'] : '');
    $user      = trim(isset($_POST['user']) ? (string) $_POST['user'] : '');
    $pass      = isset($_POST['pass']) ? (string) $_POST['pass'] : '';
    $prefix    = trim(isset($_POST['prefix']) ? (string) $_POST['prefix'] : 'lic_');
    $sqlite    = trim(isset($_POST['sqlite']) ? (string) $_POST['sqlite'] : 'data/lic.db');
    $adminPass = isset($_POST['admin_pass']) ? (string) $_POST['admin_pass'] : '';
    $siteName  = trim(isset($_POST['site_name']) ? (string) $_POST['site_name'] : 'BC28 授权中心');
    $contact   = trim(isset($_POST['contact']) ? (string) $_POST['contact'] : '');
    $epayUrl   = trim(isset($_POST['epay_url']) ? (string) $_POST['epay_url'] : '');
    $epayPid   = trim(isset($_POST['epay_pid']) ? (string) $_POST['epay_pid'] : '');
    $epayKey   = trim(isset($_POST['epay_key']) ? (string) $_POST['epay_key'] : '');
    $epayType  = trim(isset($_POST['epay_type']) ? (string) $_POST['epay_type'] : 'alipay');

    if ($prefix === '' || !preg_match('/^[A-Za-z0-9_]+$/', $prefix)) {
        $errors[] = '表前缀只能用字母、数字、下划线';
    }
    if ($driver === 'mysql' && ($name === '' || $user === '')) {
        $errors[] = '数据库名和用户名不能为空';
    }

    // 修复模式：必须验证后台密码，防止别人打开 install.php 把数据库改走
    $newHash = '';
    if ($isRepair) {
        $hash = isset($oldCfg['admin_pass']) ? (string) $oldCfg['admin_pass'] : '';
        if ($hash !== '') {
            if ($adminPass === '' || !password_verify($adminPass, $hash)) {
                $errors[] = '后台密码不对（这里要填你现在登录后台用的密码），验证不通过不能改数据库配置';
            } else {
                $newHash = $hash;
            }
        }
    }

    if (!$isRepair) {
        if ($adminPass === '') {
            $errors[] = '请设置后台密码';
        } elseif (strlen($adminPass) < 6) {
            $errors[] = '后台密码至少 6 位';
        } else {
            $newHash = password_hash($adminPass, PASSWORD_DEFAULT);
        }
    }

    if (count($errors) === 0) {
        $db = array(
            'driver' => $driver, 'host' => $host, 'port' => $port, 'name' => $name,
            'user' => $user, 'pass' => $pass, 'prefix' => $prefix, 'sqlite' => $sqlite,
        );

        // 先真连一次，连不上就不写配置（原来的做法是先写再连，填错就永远卡死）
        $test = lic_test_db($db);
        if (!$test['ok']) {
            $errors[] = $test['msg'];
            $dbRaw = $test['raw'];
        } else {
            $cfg = array(
                'db'         => $db,
                'admin_pass' => $newHash,
                'created_at' => (isset($oldCfg['created_at']) && $oldCfg['created_at'] !== '') ? $oldCfg['created_at'] : lic_now(),
                'updated_at' => lic_now(),
            );
            if (!lic_save_config($cfg)) {
                $errors[] = '无法写入 inc/config.php，请把 inc 目录权限设为 755、属主 www';
            } else {
                lic_config(true);
                try {
                    lic_db()->query('SELECT 1');
                    lic_migrate();

                    // 只在原来是空的时候写默认值，修复配置不会覆盖已有设置
                    $seed = array(
                        'site_name' => $siteName !== '' ? $siteName : 'BC28 授权中心',
                        'contact'   => $contact,
                        'notice'    => '授权码一码一站点，自动绑定下单时填写的域名，绑定后不可更换。',
                        'epay_url'  => $epayUrl,
                        'epay_pid'  => $epayPid,
                        'epay_key'  => $epayKey,
                        'epay_type' => $epayType !== '' ? $epayType : 'alipay',
                    );
                    $cur = lic_settings(true);
                    foreach ($seed as $k => $v) {
                        if (!isset($cur[$k]) || $cur[$k] === '') {
                            if ($v !== '') {
                                lic_set_setting($k, $v);
                            }
                        }
                    }

                    $done = true;
                    $doneRepair = $isRepair;
                    $installed = true;
                    $dbOk = true;
                } catch (Throwable $e) {
                    $errors[] = '数据库能连上，但建表失败：' . $e->getMessage();
                    $dbRaw = $e->getMessage();
                }
            }
        }
    }
}

// 已安装（修复模式）才去读数据库里的现有设置；全新安装一律用默认值
$curSet = ($installed && $dbOk) ? lic_settings() : array();
$setOr = function ($k, $def) use ($curSet) {
    return (isset($curSet[$k]) && $curSet[$k] !== '') ? $curSet[$k] : $def;
};

$form = array(
    'driver'   => isset($_POST['driver']) ? $_POST['driver'] : $oldDb['driver'],
    'host'     => isset($_POST['host']) ? $_POST['host'] : $oldDb['host'],
    'port'     => isset($_POST['port']) ? $_POST['port'] : $oldDb['port'],
    'name'     => isset($_POST['name']) ? $_POST['name'] : $oldDb['name'],
    'user'     => isset($_POST['user']) ? $_POST['user'] : $oldDb['user'],
    'pass'     => isset($_POST['pass']) ? $_POST['pass'] : $oldDb['pass'],
    'prefix'   => isset($_POST['prefix']) ? $_POST['prefix'] : $oldDb['prefix'],
    'sqlite'   => isset($_POST['sqlite']) ? $_POST['sqlite'] : $oldDb['sqlite'],
    'site_name' => isset($_POST['site_name']) ? $_POST['site_name'] : $setOr('site_name', 'BC28 授权中心'),
    'contact'  => isset($_POST['contact']) ? $_POST['contact'] : $setOr('contact', ''),
    'epay_url' => isset($_POST['epay_url']) ? $_POST['epay_url'] : $setOr('epay_url', ''),
    'epay_pid' => isset($_POST['epay_pid']) ? $_POST['epay_pid'] : $setOr('epay_pid', ''),
    'epay_key' => isset($_POST['epay_key']) ? $_POST['epay_key'] : $setOr('epay_key', ''),
    'epay_type' => isset($_POST['epay_type']) ? $_POST['epay_type'] : $setOr('epay_type', 'alipay'),
);
?>
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>授权中心安装</title>
<style>
*{box-sizing:border-box;margin:0;padding:0}
:root{--bg:#08090b;--card:#111317;--line:rgba(255,255,255,.08);--fg:#f2f4f7;--fg2:#9aa1ad;--gold:#e8c07d}
body{background:var(--bg);color:var(--fg);font:14px/1.7 -apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;padding:40px 18px}
.wrap{max-width:620px;margin:0 auto}
h1{font-size:20px;margin-bottom:6px}
.sub{color:var(--fg2);font-size:13px;margin-bottom:22px}
.card{border:1px solid var(--line);background:var(--card);border-radius:16px;padding:20px;margin-bottom:16px}
h2{font-size:14px;margin:0 0 14px;color:var(--gold);font-weight:600}
.row{display:flex;align-items:center;gap:12px;margin-bottom:12px}
.row label{flex:0 0 132px;font-size:13px;color:var(--fg2)}
.row input,.row select{flex:1 1 auto;padding:10px 12px;border-radius:9px;border:1px solid var(--line);background:#0c0e11;color:var(--fg);font-size:13.5px;outline:none}
.check{display:flex;justify-content:space-between;font-size:13px;padding:5px 0;border-bottom:1px dashed rgba(255,255,255,.06)}
.ok{color:#86efac}.bad{color:#fca5a5}
.alert{border-radius:11px;padding:12px 14px;font-size:13px;margin-bottom:12px;line-height:1.7}
.alert.err{background:rgba(248,113,113,.12);border:1px solid rgba(248,113,113,.35);color:#fca5a5}
.alert.warn{background:rgba(251,191,36,.1);border:1px solid rgba(251,191,36,.32);color:#fcd34d}
.alert.info{background:rgba(96,165,250,.1);border:1px solid rgba(96,165,250,.3);color:#93c5fd}
button{width:100%;padding:12px;border:0;border-radius:10px;background:var(--gold);color:#171a1f;font-weight:600;font-size:14px;cursor:pointer;margin-top:8px}
code{background:rgba(255,255,255,.08);padding:2px 6px;border-radius:5px;color:var(--gold);font-size:12.5px}
pre{background:#0c0e11;border:1px solid var(--line);border-radius:9px;padding:10px;font-size:12px;color:#c9ced8;overflow:auto;white-space:pre-wrap;word-break:break-all;margin-top:8px}
a{color:var(--gold)}
.tip{font-size:12px;color:#6f7683;margin-top:-4px;margin-bottom:10px}
</style>
</head>
<body>
<div class="wrap">
    <h1>授权中心 · 安装</h1>
    <div class="sub">加拿大28 服务端的授权码售卖与校验站点</div>

    <?php if ($done): ?>
        <div class="card">
            <div class="alert info">
                <?php echo $doneRepair ? '数据库配置已修正，站点恢复正常。' : '安装完成，授权中心已经可以用了。'; ?>
            </div>
            <div style="line-height:2.2;font-size:13.5px">
                <div>购买页：<code><?php echo htmlspecialchars(lic_base_url() . '/index.php'); ?></code></div>
                <div>管理后台：<code><?php echo htmlspecialchars(lic_base_url() . '/admin/'); ?></code></div>
                <div>校验接口：<code><?php echo htmlspecialchars(lic_base_url() . '/api.php?act=verify'); ?></code></div>
            </div>
            <div class="alert warn" style="margin-top:14px">
                装完请删除 install.php。另外先去后台「授权码」里生成一批库存，否则付款后发不出码。
            </div>
            <div style="margin-top:14px"><a href="check.php">打开 check.php 看一眼整体状态</a> · <a href="admin/">进后台</a></div>
        </div>

    <?php elseif ($installed && $dbOk): ?>
        <div class="card">
            <div class="alert info">已经安装过了，数据库连接正常。</div>
            <div class="alert warn">要重装请先删除 <code>inc/config.php</code>（库里的数据不会被删）。</div>
            <div><a href="index.php">去购买页</a> · <a href="admin/">去后台</a> · <a href="check.php">诊断页</a></div>
        </div>

    <?php else: ?>

        <?php if ($isRepair): ?>
            <div class="card">
                <div class="alert err">
                    <strong>已安装，但数据库连不上。</strong><br>
                    原因：<?php echo htmlspecialchars($dbErr); ?>
                    <?php if ($dbRaw !== ''): ?><pre><?php echo htmlspecialchars($dbRaw); ?></pre><?php endif; ?>
                </div>
                <div class="alert warn">
                    下面的表单已经带出了当前配置。把不对的地方改掉，输入你现在的后台密码，点保存就能修好——不用删文件重装，库里的授权码和订单也不会丢。
                </div>
            </div>
        <?php endif; ?>

        <div class="card">
            <h2>环境检查</h2>
            <?php foreach ($checks as $c): ?>
                <div class="check"><span><?php echo htmlspecialchars($c[0]); ?></span>
                    <span class="<?php echo $c[1] ? 'ok' : 'bad'; ?>"><?php echo htmlspecialchars($c[2]); ?></span></div>
            <?php endforeach; ?>
        </div>

        <?php if (count($errors) > 0): ?>
            <div class="card"><div class="alert err">
                <?php foreach ($errors as $e): ?>· <?php echo htmlspecialchars($e); ?><br><?php endforeach; ?>
            </div></div>
        <?php endif; ?>

        <form method="post" class="card">
            <h2>数据库</h2>
            <div class="row"><label>类型</label>
                <select name="driver" id="driver" onchange="tg()">
                    <option value="mysql" <?php echo $form['driver'] === 'mysql' ? 'selected' : ''; ?>>MySQL（推荐）</option>
                    <option value="sqlite" <?php echo $form['driver'] === 'sqlite' ? 'selected' : ''; ?>>SQLite（零配置）</option>
                </select></div>
            <div id="mysqlBox">
                <div class="row"><label>主机</label><input type="text" name="host" value="<?php echo htmlspecialchars($form['host']); ?>"></div>
                <div class="row"><label>端口</label><input type="number" name="port" value="<?php echo htmlspecialchars((string) $form['port']); ?>"></div>
                <div class="row"><label>数据库名</label><input type="text" name="name" value="<?php echo htmlspecialchars($form['name']); ?>" placeholder="宝塔里建的库名"></div>
                <div class="row"><label>用户名</label><input type="text" name="user" value="<?php echo htmlspecialchars($form['user']); ?>"></div>
                <div class="row"><label>密码</label><input type="text" name="pass" value="<?php echo htmlspecialchars($form['pass']); ?>"></div>
            </div>
            <div id="sqliteBox" style="display:none">
                <div class="row"><label>数据库文件</label><input type="text" name="sqlite" value="<?php echo htmlspecialchars($form['sqlite']); ?>"></div>
            </div>
            <div class="row"><label>表前缀</label><input type="text" name="prefix" value="<?php echo htmlspecialchars($form['prefix']); ?>"></div>
            <div class="tip">数据库密码是明文显示，方便你对照宝塔里的密码。修完记得删掉 install.php。</div>

            <h2 style="margin-top:20px">站点信息</h2>
            <div class="row"><label>站点名称</label><input type="text" name="site_name" value="<?php echo htmlspecialchars($form['site_name']); ?>"></div>
            <div class="row"><label>客服联系方式</label><input type="text" name="contact" value="<?php echo htmlspecialchars($form['contact']); ?>" placeholder="QQ / 邮箱 / TG，可留空"></div>

            <h2 style="margin-top:20px">易支付（可以不填，装完在后台补）</h2>
            <div class="row"><label>网关地址</label><input type="text" name="epay_url" value="<?php echo htmlspecialchars($form['epay_url']); ?>" placeholder="https://pay.example.com"></div>
            <div class="row"><label>商户 PID</label><input type="text" name="epay_pid" value="<?php echo htmlspecialchars($form['epay_pid']); ?>"></div>
            <div class="row"><label>商户 KEY</label><input type="text" name="epay_key" value="<?php echo htmlspecialchars($form['epay_key']); ?>"></div>
            <div class="row"><label>默认通道</label>
                <select name="epay_type">
                    <option value="alipay" <?php echo $form['epay_type'] === 'alipay' ? 'selected' : ''; ?>>支付宝</option>
                    <option value="wxpay" <?php echo $form['epay_type'] === 'wxpay' ? 'selected' : ''; ?>>微信</option>
                </select></div>

            <h2 style="margin-top:20px"><?php echo $isRepair ? '身份验证' : '后台'; ?></h2>
            <div class="row"><label><?php echo $isRepair ? '当前后台密码' : '后台密码'; ?></label>
                <input type="password" name="admin_pass" placeholder="<?php echo $isRepair ? '输入你现在登录后台的密码' : '至少 6 位，账号固定 admin'; ?>"></div>
            <div class="tip"><?php echo $isRepair ? '只是验证是你本人在改配置，不会改掉原密码。' : '装完记得删除 install.php'; ?></div>

            <button type="submit"><?php echo $isRepair ? '保存并修复' : '开始安装'; ?></button>
        </form>
    <?php endif; ?>
</div>
<script>
function tg() {
    var d = document.getElementById('driver').value;
    document.getElementById('mysqlBox').style.display = d === 'mysql' ? '' : 'none';
    document.getElementById('sqliteBox').style.display = d === 'sqlite' ? '' : 'none';
}
tg();
</script>
</body>
</html>
