<?php
require_once __DIR__ . '/cong.php';
require_once __DIR__ . '/admin/bootstrap.php';
require_once __DIR__ . '/admin/ConfigWriter.php';
require_once __DIR__ . '/lib/Cloak/DomainRepository.php';
require_once __DIR__ . '/lib/CloakAdSourceGuard.php';
require_once __DIR__ . '/lib/Cloak/CloudflareConfig.php';
require_once __DIR__ . '/lib/Cloak/DomainProvisioningService.php';

session_start();
$filename     = basename(__FILE__);
$current_name = pathinfo($filename, PATHINFO_FILENAME);

// 登出
if (!empty($_REQUEST["action"]) && $_REQUEST["action"] == "logout") {
    unset($_SESSION['password']);
    unset($_SESSION['check_result']);
    echo("<script>window.location='{$current_name}';</script>");
    exit();
}

// 重置临时链接参数
if (!empty($_REQUEST["action"]) && $_REQUEST["action"] == "delUrlArgs") {
    $check_name = strip_tags($_REQUEST['check_name']);
    $dir        = dirname(__FILE__) . '/args';
    $files      = glob($dir . '/' . $check_name . "_*.txt");
    foreach ($files as $file) {
        if (preg_match('/_(\d{10})\.txt$/', $file, $m)) {
            unlink($file);
        }
    }
    header('Location: ' . $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . '?action=edit_config&name=' . urlencode($check_name));
    exit;
}

// 确定当前配置上下文（供表单回显用）
if (!empty($_REQUEST["name"])) {
    $check_name  = trim($_REQUEST["name"]);
    $config_name = str_replace(".php", "", $check_name);
    $config_file = "check_config/" . $config_name . "_config.php";
    if (!file_exists($config_file)) {
        copy("check_config/index_config.php", $config_file);
    }
} else {
    $check_name  = "index";
	$config_file = "check_config/index_config.php";
}
	include($config_file);

// 密码处理
if (!empty($_REQUEST['password'])) {
    $_SESSION['password']  = $_REQUEST['password'];
    $_SESSION["myaction"]  = $_REQUEST['myaction'];
}

// 设置测试访问状态（写入完整 Session 判定缓存，便于测试广告落地链接直达真实页）
if (!empty($_REQUEST["action"]) && $_REQUEST["action"] == "setuvi") {
    require_once __DIR__ . '/lib/Cloak/VisitorRepository.php';
    if (!empty($_REQUEST["res"]) && $_REQUEST["res"] == "true") {
        cloak_session_mark_real_visitor();
    }
    if (!empty($_REQUEST["res"]) && $_REQUEST["res"] == "false") {
        cloak_session_clear_real_visitor();
    }
    echo("<script>window.location='{$current_name}?action=edit_config&name={$check_name}';</script>");
    exit();
}

// 保存配置
if (!empty($_REQUEST["action"]) && $_REQUEST["action"] == "submit") {
    $check_name           = trim($_REQUEST["check_name"]);
    $methods              = trim($_REQUEST["methods"]);
    $country              = trim($_REQUEST["country"]);
    $blacklist_group_id   = (int)($_REQUEST["blacklist_group_id"] ?? 0);
    $whitelist_group_id   = (int)($_REQUEST["whitelist_group_id"] ?? 0);
	try {
		$pdoDash = new PDO(
			'mysql:host=127.0.0.1;dbname=' . DB_NAME . ';charset=utf8mb4',
            DB_USERNAME, DB_PASSWORD,
			[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
		);
		$chk = $pdoDash->prepare('SELECT 1 FROM ip_groups WHERE id = ? AND type = ? LIMIT 1');
		if ($blacklist_group_id > 0) {
			$chk->execute([$blacklist_group_id, 'black']);
            if (!$chk->fetchColumn()) $blacklist_group_id = 0;
		}
		if ($whitelist_group_id > 0) {
			$chk->execute([$whitelist_group_id, 'white']);
            if (!$chk->fetchColumn()) $whitelist_group_id = 0;
		}
	} catch (Throwable $e) {
        $blacklist_group_id = $whitelist_group_id = 0;
    }
    $DB_fp             = $_REQUEST["DB_fp"];
    $DB_zp             = trim($_REQUEST["DB_zp"]);
    $redirect_method   = trim($_REQUEST["redirect_method"]);
    $show_content      = trim($_REQUEST["show_content"]);
    $costm_ip_score    = trim($_REQUEST["costm_ip_score"]);
    $write_log         = trim($_REQUEST["write_log"]);
    $zh_on             = trim($_REQUEST["zh_on"]);
    $os_on             = trim($_REQUEST["os_on"]);
    $mobile_on         = trim($_REQUEST["mobile_on"]);
    $v_referer         = trim($_REQUEST["v_referer"]);
    $is_virtual        = trim($_REQUEST["is_virtual"]);
    $auto_black        = trim($_REQUEST["auto_black"]);
    $auto_black_times  = trim($_REQUEST["auto_black_times"]);
    $white_params      = trim($_REQUEST["white_params"]);
    $keep_params       = trim($_REQUEST["keep_params"]);
    $iphone_model      = $_REQUEST["iphone_model"];
    $risk_number       = $_REQUEST["risk_number"];
    $risk_enhanced     = in_array(strtoupper(trim($_REQUEST["risk_enhanced"] ?? '')), ['ON']) ? 'ON' : 'OFF';
    $url_args_timeout  = $_REQUEST["url_args_timeout"];
    $debug_mode           = in_array(strtoupper(trim($_REQUEST["debug_mode"] ?? '')), ['ON']) ? 'ON' : 'OFF';
    $ad_fb                = in_array(strtoupper(trim($_REQUEST["ad_fb"] ?? '')), ['ON']) ? 'ON' : 'OFF';
    $ad_google            = in_array(strtoupper(trim($_REQUEST["ad_google"] ?? '')), ['ON']) ? 'ON' : 'OFF';
    $ad_tiktok            = in_array(strtoupper(trim($_REQUEST["ad_tiktok"] ?? '')), ['ON']) ? 'ON' : 'OFF';
    $ad_strict            = in_array(strtoupper(trim($_REQUEST["ad_strict"] ?? '')), ['ON']) ? 'ON' : 'OFF';

    $config_name_submit = str_replace('.php', '', $check_name);
    $existing_spm_id  = '';
    $existing_cfg     = 'check_config/' . $config_name_submit . '_config.php';
    if (file_exists($existing_cfg)) {
        $existing_raw = file_get_contents($existing_cfg);
        if (preg_match("/define\('CLOAK_AD_SPM_ID',\s*'([^']*)'\)/", $existing_raw, $spmM)) {
            $existing_spm_id = $spmM[1];
        }
    }
    $ad_spm_id = CloakAdSourceGuard::isValidSpmId($existing_spm_id) ? $existing_spm_id : '';
    if (($ad_fb === 'ON' || $ad_google === 'ON' || $ad_tiktok === 'ON') && $ad_spm_id === '') {
        $ad_spm_id = CloakAdSourceGuard::generateSpmId();
    }

	if (strtoupper($auto_black) === 'ON' && $blacklist_group_id <= 0) {
        echo "<script>alert('开启「自动黑名单」时，必须先选择「黑名单 IP 组」。');history.back();</script>";
		exit();
	}

    if (!empty($methods)) {
        ConfigWriter::save($check_name, [
            'methods'                => $methods,
            'blacklist_group_id'     => $blacklist_group_id,
            'whitelist_group_id'     => $whitelist_group_id,
            'country'                => $country,
            'show_content'           => $show_content,
            'DB_fp'                  => $DB_fp,
            'costm_ip_score'         => $costm_ip_score,
            'auto_black'             => $auto_black,
            'is_virtual'             => $is_virtual,
            'auto_black_times'       => $auto_black_times,
            'white_params'           => $white_params,
            'iphone_model'           => $iphone_model,
            'write_log'              => $write_log,
            'zh_on'                  => $zh_on,
            'os_on'                  => $os_on,
            'keep_params'            => $keep_params,
            'redirect_method'        => $redirect_method,
            'DB_zp'                  => $DB_zp,
            'mobile_on'              => $mobile_on,
            'v_referer'              => $v_referer,
            'risk_number'            => $risk_number,
            'risk_enhanced'          => $risk_enhanced,
            'url_args_timeout'       => $url_args_timeout,
            'debug_mode'             => $debug_mode,
            'ad_fb'                  => $ad_fb,
            'ad_google'              => $ad_google,
            'ad_tiktok'              => $ad_tiktok,
            'ad_strict'              => $ad_strict,
            'ad_spm_id'              => $ad_spm_id,
        ]);
        try {
            $pdoBind = DomainRepository::pdo();
            DomainRepository::ensureTable($pdoBind);
            $siteDomainId = (int) ($_REQUEST['site_domain_id'] ?? 0);
            if ($siteDomainId > 0) {
                DomainRepository::bindConfigToDomain($pdoBind, $check_name, $siteDomainId);
            } else {
                DomainRepository::clearConfigBinding($pdoBind, $check_name);
            }
        } catch (Throwable $e) {
        }
        echo("<script>alert('保存成功！');window.location='{$current_name}?action=edit_config&name={$check_name}';</script>");
        exit();
    }
}

function write_file($file_name, $text_str) {
    $f = fopen($file_name, "w");
    rewind($f);
    fwrite($f, $text_str);  
	  fclose($f);      
}

function onoff_radio($name, $val, $label_on='开启', $label_off='关闭') {
  $on  = ($val == 'ON') ? 'active' : '';
  $off = ($val != 'ON') ? 'active' : '';
  return '<div class="btn-group btn-group-toggle" data-toggle="buttons">
    <label class="btn btn-sm btn-outline-secondary ' . $on . '">
      <input type="radio" name="' . $name . '" value="ON" ' . ($val=='ON'?'checked':'') . '> ' . $label_on . '
    </label>
    <label class="btn btn-sm btn-outline-secondary ' . $off . '">
      <input type="radio" name="' . $name . '" value="OFF" ' . ($val!='ON'?'checked':'') . '> ' . $label_off . '
    </label>
  </div>';
}

function dash_truncate_attr($text, $maxLen = 52) {
    $text = (string) $text;
    $esc  = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
    if (function_exists('mb_strlen') && function_exists('mb_substr')) {
        if (mb_strlen($text, 'UTF-8') <= $maxLen) {
            return $esc;
        }
        return '<span class="cell-truncate" title="' . $esc . '">' . htmlspecialchars(mb_substr($text, 0, $maxLen, 'UTF-8'), ENT_QUOTES, 'UTF-8') . '…</span>';
    }
    if (strlen($text) <= $maxLen) {
        return $esc;
    }
    return '<span class="cell-truncate" title="' . $esc . '">' . htmlspecialchars(substr($text, 0, $maxLen), ENT_QUOTES, 'UTF-8') . '…</span>';
}

?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>IPCLOAKAPI 多功能管理后台面板 v8.2.1</title>
<link rel="stylesheet" href="./dist/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="./dist/jquery-2.2.4.min.js"></script>
<script src="./dist/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>
 <style>
body { background:#f0f2f5; font-family:'Segoe UI',Tahoma,Geneva,Verdana,sans-serif; }
.topbar { background:linear-gradient(135deg,#16baaa,#0e8d81); color:#fff; padding:14px 24px; display:flex; align-items:center; justify-content:space-between; box-shadow:0 2px 8px rgba(0,0,0,.15); }
.topbar a { color:rgba(255,255,255,.85); text-decoration:none; font-size:.9rem; }
.topbar a:hover { color:#fff; }
.topbar h1 { margin:0; font-size:1.25rem; font-weight:600; }
.page-body { max-width:1100px; margin:32px auto; padding:0 16px; }
.status-bar { display:flex; gap:12px; margin-bottom:20px; flex-wrap:wrap; }
.status-badge { display:inline-flex; align-items:center; gap:6px; padding:6px 14px; border-radius:20px; font-size:.82rem; font-weight:500; }
.status-ok   { background:#d4edda; color:#155724; }
.status-err  { background:#f8d7da; color:#721c24; }
.card-header-custom { background:#fff; border-bottom:1px solid #e9ecef; padding:14px 20px; display:flex; align-items:center; justify-content:space-between; border-radius:8px 8px 0 0; }
.card-header-custom h5 { margin:0; font-size:1rem; font-weight:600; }
.config-table th { background:#f8f9fa; font-weight:600; }
.config-table td, .config-table th { vertical-align:middle !important; padding:12px 16px !important; }
.config-table tr:hover { background:#f0f7ff; }
.url-text { font-size:.78rem; color:#6c757d; }
.ad-link-row { display:flex; align-items:flex-start; gap:6px; margin-bottom:6px; }
.ad-link-row:last-child { margin-bottom:0; }
.ad-link-label { font-size:.72rem; color:#495057; white-space:nowrap; min-width:58px; padding-top:2px; }
.btn-copy-ad { font-size:.72rem; padding:2px 8px; flex-shrink:0; }
.ad-link-hint { font-size:.68rem; color:#adb5bd; margin-top:4px; }
.section-heading { background:#e8f4fd; color:#1565c0; font-weight:600; padding:8px 14px; border-radius:4px; margin:6px 0 2px; font-size:.85rem; letter-spacing:.3px; }
.form-label-cell { width:36%; font-size:.88rem; color:#444; padding:10px 14px !important; }
.form-val-cell { padding:8px 14px !important; }
.form-section { border:1px solid #dee2e6; border-radius:6px; margin-bottom:8px; overflow:hidden; }
.form-section .section-toggle { background:#f8f9fa; padding:10px 16px; cursor:pointer; display:flex; align-items:center; justify-content:space-between; font-weight:600; font-size:.9rem; border:none; width:100%; text-align:left; }
.form-section .section-toggle:hover { background:#e9ecef; }
.form-section .section-toggle .arrow { transition:transform .2s; }
.form-section .section-toggle.collapsed .arrow { transform:rotate(-90deg); }
.back-link { display:inline-flex; align-items:center; gap:6px; color:#1565c0; font-size:.9rem; margin-bottom:16px; text-decoration:none; }
.back-link:hover { text-decoration:underline; }
.sticky-actions { position:sticky; bottom:0; background:#fff; border-top:1px solid #dee2e6; padding:12px 20px; display:flex; gap:10px; align-items:center; z-index:100; border-radius:0 0 8px 8px; }
.login-wrap { min-height:100vh; display:flex; align-items:center; justify-content:center; }
.login-card { background:#fff; border-radius:10px; box-shadow:0 4px 20px rgba(0,0,0,.1); padding:40px; width:340px; }
.login-card h2 { text-align:center; color:#16baaa; margin-bottom:24px; font-size:1.4rem; }
.list-page-title { margin-bottom: 4px; }
.list-page-title h2 { margin: 0 0 6px; font-size: 1.2rem; font-weight: 600; color: #2c3e50; }
.list-page-title p { margin: 0; font-size: .85rem; color: #8c98a4; }
.card-shell { border-radius: 10px; overflow: hidden; border: 1px solid #e8ecf1; box-shadow: 0 2px 12px rgba(15,23,42,.04); }
.card-header-custom .header-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.card-header-custom .header-actions .btn-teal { background: #16baaa; color: #fff; border: none; }
.card-header-custom .header-actions .btn-teal:hover { background: #0e8d81; color: #fff; }
.list-table-wrap { overflow-x: auto; }
.config-table thead th {
  position: sticky;
  top: 0;
  z-index: 5;
  background: linear-gradient(180deg, #f4f7fb 0%, #eef2f7 100%) !important;
  border-bottom: 2px solid #dde4ec !important;
  font-size: .82rem;
  letter-spacing: .02em;
  text-transform: none;
  white-space: nowrap;
}
.config-table tbody tr:nth-child(even) { background: #fafbfc; }
.config-table tbody tr:hover { background: #eef6ff !important; }
.config-table tbody tr { transition: background-color .15s ease; }
.config-table tbody td { border-color: #eef1f5 !important; font-size: .86rem; }
.list-table thead th {
  background: #f4f7fb;
  font-weight: 600;
  font-size: .82rem;
  border-bottom: 2px solid #dde4ec !important;
  padding: 10px 14px !important;
  white-space: nowrap;
}
.list-table tbody tr:nth-child(even) { background: #fafbfc; }
.list-table tbody tr:hover { background: #eef6ff; }
.list-table tbody td { vertical-align: middle !important; padding: 11px 14px !important; border-color: #eef1f5 !important; font-size: .84rem; }
.cell-truncate { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; cursor: default; }
.url-text-truncate { font-size: .78rem; color: #6c757d; word-break: break-all; }
.action-btn-group { display: flex; flex-wrap: wrap; gap: 6px; }
.action-btn-group .btn { border-radius: 6px; }
.domain-host-badge { display: inline-block; padding: 2px 8px; background: #e8f4fd; color: #1565c0; border-radius: 4px; font-size: .78rem; font-family: 'SF Mono', Consolas, monospace; }
.config-name-cell strong { color: #2c3e50; font-size: .92rem; }
.empty-hint { padding: 28px 20px; text-align: center; color: #8c98a4; font-size: .88rem; background: #fafbfc; border-radius: 0 0 10px 10px; }
</style>
</head>
<body>

<?php if (empty($_SESSION['password'])): ?>
<!-- ===================== 登录页 ===================== -->
<div class="login-wrap">
  <div class="login-card">
    <h2>IPCLOAKAPI 多功能管理后台面板 v8.2.1</h2>
    <form method="post" action="<?php echo $current_name; ?>">
      <div class="form-group">
        <label>登录密码</label>
        <input type="password" name="password" class="form-control" placeholder="请输入密码" autofocus>
    </div>
      <input type="hidden" name="myaction" value="dolist">
      <button type="submit" class="btn btn-block" style="background:#16baaa;color:#fff;margin-top:8px;">进入后台</button>
  </form>
  </div>
</div>
<?php exit(); endif; ?>

  <?php
// 密码验证
if ($_SESSION['password'] != LOGIN_PASSWORD) {
    unset($_SESSION['password']);
    echo("<script>alert('密码错误！');window.location='{$current_name}';</script>");
		exit();
	}

// 删除配置
if (!empty($_REQUEST["action"]) && $_REQUEST["action"] == "delete_config" && !empty($_REQUEST["name"])) {
	$name = trim($_REQUEST["name"]);
    if ($name == "index") {
        echo("<script>alert('请勿删除默认配置！');window.location='{$current_name}';</script>");
		exit();
	}
    $cfg = str_replace(".php", "", $name);
    try {
        DomainRepository::clearConfigBinding(DomainRepository::pdo(), $cfg);
    } catch (Throwable $e) {
    }
    @unlink("check_config/{$cfg}_config.php");
    @unlink("{$cfg}.php");
    echo("<script>alert('删除成功！');window.location='{$current_name}';</script>");
	exit();
}

// 站点域名管理
$cloakDomainMsg = '';
$cloakDomainErr = '';
$cloakCfEnabled   = CloudflareConfig::isEnabled();
if (!empty($_REQUEST['action']) && $_REQUEST['action'] === 'add_domain' && !empty($_POST['new_hostname'])) {
    try {
        $pdoDom = DomainRepository::pdo();
        $res    = DomainProvisioningService::provisionOnAdd($pdoDom, $_POST['new_hostname']);
        if ($res['ok']) {
            $cloakDomainMsg = '域名「' . htmlspecialchars($res['hostname']) . '」已添加';
            if (!empty($res['nameservers'])) {
                $nsHtml = implode('</code>、<code>', array_map('htmlspecialchars', $res['nameservers']));
                $cloakDomainMsg .= '。请到注册商将 NS 修改为：<code>' . $nsHtml . '</code>，然后点击「检测/刷新」。';
            } else {
                $cloakDomainMsg .= '，请在编辑配置时关联此域名。';
            }
        } else {
            $cloakDomainErr = $res['error'] ?? '添加失败';
        }
    } catch (Throwable $e) {
        $cloakDomainErr = $e->getMessage();
    }
}
if (!empty($_REQUEST['action']) && $_REQUEST['action'] === 'check_domain') {
    $domainId = (int) ($_POST['domain_id'] ?? $_REQUEST['domain_id'] ?? 0);
    $jsonOut  = isset($_REQUEST['format']) && $_REQUEST['format'] === 'json';
    try {
        $res = DomainProvisioningService::checkAndProvision(DomainRepository::pdo(), $domainId);
        if ($jsonOut) {
            header('Content-Type: application/json; charset=utf-8');
            echo json_encode($res, JSON_UNESCAPED_UNICODE);
            exit;
        }
        if ($res['ok']) {
            $cloakDomainMsg = $res['message'] ?? '检测完成';
        } else {
            $cloakDomainErr = $res['message'] ?? '检测失败';
        }
		} catch (Throwable $e) {
        if ($jsonOut) {
            header('Content-Type: application/json; charset=utf-8');
            echo json_encode(['ok' => false, 'message' => $e->getMessage()], JSON_UNESCAPED_UNICODE);
            exit;
        }
        $cloakDomainErr = $e->getMessage();
    }
}
if (!empty($_REQUEST['action']) && $_REQUEST['action'] === 'delete_domain' && !empty($_REQUEST['domain_id'])) {
    try {
        $res = DomainProvisioningService::deleteWithCloudflare(DomainRepository::pdo(), (int) $_REQUEST['domain_id']);
        if ($res['ok']) {
            $cloakDomainMsg = $res['message'] ?? '域名已删除。';
            if (!empty($res['warning'])) {
                $cloakDomainErr = $res['warning'];
            }
        } else {
            $cloakDomainErr = $res['message'] ?? '删除失败';
        }
    } catch (Throwable $e) {
        $cloakDomainErr = $e->getMessage();
    }
}

// 系统状态检测（列表页用）
function dash_check_mysql() {
    try {
        $pdo = new PDO('mysql:host=127.0.0.1;dbname=' . DB_NAME . ';charset=utf8mb4', DB_USERNAME, DB_PASSWORD, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
        return true;
    } catch (Throwable $e) { return false; }
}
function dash_check_redis() {
    if (!extension_loaded('redis') || strtoupper(REDIS_ENABLED) !== 'ON') return null;
    try {
        $r = new Redis();
        if (!@$r->connect(REDIS_HOST, (int)REDIS_PORT, 0.5)) return false;
        $r->ping();
        return true;
    } catch (Throwable $e) { return false; }
}

function dash_cfg_get($raw, $name)
{
    if (preg_match("/define\('" . preg_quote($name, '/') . "',\s*'([^']*)'\)/", $raw, $m)) {
        return $m[1];
    }
    return '';
}

function dash_build_ad_links($pf, $protocol, $host)
{
    $path = __DIR__ . "/check_config/{$pf}_config.php";
    try {
        $pdoDashHost = DomainRepository::pdo();
        DomainRepository::ensureTable($pdoDashHost);
        $bound = DomainRepository::primaryHostnameForConfig($pdoDashHost, $pf);
        if ($bound !== '') {
            $host = $bound;
        }
    } catch (Throwable $e) {
    }
    $host = DomainRepository::normalizeHostname($host);
    if ($host === '') {
        $host = DomainRepository::normalizeHostname($_SERVER['HTTP_HOST'] ?? '');
    }
    $base = rtrim($protocol . $host, '/') . '/' . (($pf != 'index') ? $pf : '');

    if (!file_exists($path)) {
        return [['label' => '落地链接', 'url' => $base]];
    }

    $raw = file_get_contents($path);
    $enabled = [];
    if (dash_cfg_get($raw, 'CLOAK_AD_FB') === 'ON') {
        $enabled[] = CloakAdSourceGuard::PLATFORM_FB;
    }
    if (dash_cfg_get($raw, 'CLOAK_AD_GOOGLE') === 'ON') {
        $enabled[] = CloakAdSourceGuard::PLATFORM_GOOGLE;
    }
    if (dash_cfg_get($raw, 'CLOAK_AD_TIKTOK') === 'ON') {
        $enabled[] = CloakAdSourceGuard::PLATFORM_TIKTOK;
    }

    if (empty($enabled)) {
        return [['label' => '落地链接', 'url' => $base]];
    }

    $spmId = dash_cfg_get($raw, 'CLOAK_AD_SPM_ID');
    $query = CloakAdSourceGuard::buildAdLinkQuery($enabled, $spmId);
    $url   = $base . ($query !== '' ? '?' . $query : '');

    return [['label' => '落地链接', 'url' => $url]];
}

// 遍历配置列表
$products_file_ary = [];
$dd = opendir("check_config");
while (false !== ($f = readdir($dd))) {
    if ($f == "." || $f == "..") continue;
    if (filetype("check_config/$f") == "dir" || $f == "index.php" || $f == "a.txt") continue;
    $fname = str_replace("_config.php", "", $f);
    $products_file_ary[] = $fname;
    if (!file_exists($fname . ".php")) {
        copy("tem_link.php", $fname . ".php");
    }
}
closedir($dd);
sort($products_file_ary);

// 加载 IP 组（编辑页用）
$blackGroups = $whiteGroups = [];
try {
    $pdoDash = new PDO('mysql:host=127.0.0.1;dbname=' . DB_NAME . ';charset=utf8mb4', DB_USERNAME, DB_PASSWORD, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]);
    $stb = $pdoDash->prepare("SELECT id, name FROM ip_groups WHERE type = 'black' ORDER BY id ASC");
    $stb->execute(); $blackGroups = $stb->fetchAll();
    $stw = $pdoDash->prepare("SELECT id, name FROM ip_groups WHERE type = 'white' ORDER BY id ASC");
    $stw->execute(); $whiteGroups = $stw->fetchAll();
} catch (Throwable $e) {}
$currentBlacklistGroupId = defined('BLACKLIST_GROUP_ID') ? (int)BLACKLIST_GROUP_ID : 0;
$currentWhitelistGroupId = defined('WHITELIST_GROUP_ID') ? (int)WHITELIST_GROUP_ID : 0;

$action  = $_REQUEST['action'] ?? '';
$isEdit  = in_array($action, ['edit_config', 'submit'], true);

$cloakSiteDomains     = [];
$selectedDomainId     = 0;
$dashboardDefaultHost = DomainRepository::normalizeHostname($_SERVER['HTTP_HOST'] ?? '');
try {
    $pdoDash = $pdoDash ?? DomainRepository::pdo();
    DomainRepository::ensureTable($pdoDash);
    $cloakSiteDomains = DomainRepository::listAll($pdoDash);
    if ($isEdit) {
        $selectedDomainId = DomainRepository::domainIdForConfig($pdoDash, $check_name);
    }
} catch (Throwable $e) {
    $cloakSiteDomains = [];
}

// 视图判断
$_d = function($name, $default) { return defined($name) ? constant($name) : $default; };
?>

<!-- ===================== 顶栏 ===================== -->
<div class="topbar">
  <h1>IPCLOAKAPI 多功能管理后台面板 v8.2.1</h1>
  <div style="display:flex;gap:16px;align-items:center;">
    <?php if ($isEdit): ?>
    <a href="<?php echo $current_name; ?>">← 返回列表</a>
    <?php endif; ?>
    <a href="<?php echo $current_name; ?>?action=logout">退出登录</a>
  </div>
</div>

<div class="page-body">

<?php if (!$isEdit): ?>
<!-- ===================== 列表视图 ===================== -->

<div class="list-page-title">
  <h2>配置管理</h2>
  <p>管理 Cloak 配置、广告落地链接与站点域名</p>
</div>

<!-- 系统状态 -->
<div class="status-bar">
<?php
  $mysqlOk  = dash_check_mysql();
  $redisOk  = dash_check_redis();
  echo '<span class="status-badge ' . ($mysqlOk ? 'status-ok' : 'status-err') . '">● MySQL ' . ($mysqlOk ? '已连接' : '连接失败') . '</span>';
  if ($redisOk === null) {
      echo '<span class="status-badge" style="background:#fff3cd;color:#856404;">● Redis 未启用</span>';
  } else {
      echo '<span class="status-badge ' . ($redisOk ? 'status-ok' : 'status-err') . '">● Redis ' . ($redisOk ? '已连接' : '连接失败') . '</span>';
  }
?>
  <span class="status-badge" style="background:#e2e3e5;color:#383d41;">● 配置数：<?php echo count($products_file_ary); ?></span>
  <span class="status-badge" style="background:#e2e3e5;color:#383d41;">● 已登记域名：<?php echo count($cloakSiteDomains); ?></span>
</div>

<?php if ($cloakDomainMsg): ?>
<div class="alert alert-success"><?php echo $cloakDomainMsg; ?></div>
<?php endif; ?>
<?php if ($cloakDomainErr): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($cloakDomainErr); ?></div>
<?php endif; ?>

<!-- 配置列表卡片 -->
<div class="card shadow-sm card-shell">
  <div class="card-header-custom">
    <h5>配置列表</h5>

    <div class="header-actions">
        <a href="/table" target="_blank" class="btn btn-sm btn-outline-secondary">查看日志</a>
        <a href="/log_analytics.php" target="_blank" class="btn btn-sm btn-outline-secondary">数据分析</a>
        <a href="<?php echo $current_name; ?>?action=edit_config&name=new_config" class="btn btn-sm btn-teal">+ 新增配置</a>
    </div>
  </div>
  <div class="list-table-wrap">
  <table class="table config-table mb-0">
    <thead>
      <tr>
        <th style="width:22%">配置名称</th>
        <th style="width:14%">绑定域名</th>
        <th>广告链接（广告后台填入的链接）</th>
        <th>真实页链接（客户到达的链接）</th>
        <th style="width:22%">操作</th>
  </tr>
    </thead>
    <tbody>
    <?php foreach ($products_file_ary as $pf):
        $pcfg = "check_config/{$pf}_config.php";
        $pfp  = [];
        if (file_exists($pcfg)) {
            // 简单读取 DB_FP 和 DB_ZP 值用于展示
            $raw = file_get_contents($pcfg);
            if (preg_match("/define\('DB_FP',\s*(array\s*\(.*?\))\s*\)/s", $raw, $m)) {
                @eval('$pfp = ' . $m[1] . ';');
            }
            preg_match("/define\('DB_ZP',\s*'([^']*)'\)/", $raw, $zpM);
            $pzp = $zpM[1] ?? '';
        }
    ?>
      <tr>
        <td class="config-name-cell">
          <strong><?php echo htmlspecialchars($pf); ?></strong>
          <?php if ($pf === 'index'): ?><span class="badge badge-secondary ml-1" style="font-size:.7rem;">默认</span><?php endif; ?>
    </td>
        <td style="font-size:.82rem;">
          <?php
            $pfHost = '';
            try {
                $pfHost = DomainRepository::primaryHostnameForConfig($pdoDash ?? DomainRepository::pdo(), $pf);
            } catch (Throwable $e) {
            }
            if ($pfHost !== '') {
                echo '<span class="domain-host-badge" title="' . htmlspecialchars($pfHost, ENT_QUOTES) . '">' . htmlspecialchars($pfHost) . '</span>';
            } else {
                echo '<span class="text-muted cell-truncate" title="' . htmlspecialchars($dashboardDefaultHost, ENT_QUOTES) . '">' . htmlspecialchars($dashboardDefaultHost) . '<br><small>（默认后台域）</small></span>';
            }
          ?>
    </td>
        <td>
          <?php
            $adLinks = dash_build_ad_links($pf, $protocol, $_SERVER['HTTP_HOST']);
            foreach ($adLinks as $link):
          ?>
          <div class="ad-link-row">

            <span class="ad-link-label"><?php echo htmlspecialchars($link['label']); ?></span>

            <div class="url-text flex-grow-1 url-text-truncate"><?php echo dash_truncate_attr($link['url'], 56); ?></div>
            <button type="button" class="btn btn-sm btn-outline-secondary btn-copy-ad" data-copy="<?php echo htmlspecialchars($link['url'], ENT_QUOTES); ?>">复制</button>
          </div>
          <?php endforeach; ?>
					</td>
        <td>
          <?php if (!empty($pfp)) {
              $first = is_array($pfp) ? $pfp[0] : $pfp;
              echo '<div class="url-text url-text-truncate">' . dash_truncate_attr($first, 48) . '</div>';
              if (is_array($pfp) && count($pfp) > 1) {
                  echo '<div class="url-text text-muted">+' . (count($pfp)-1) . ' 个链接</div>';
              }
          } else { ?>
          <span class="text-muted" style="font-size:.82rem;">—</span>
          <?php } ?>
		</td>
        <td>
          <div class="action-btn-group">
          <a href="<?php echo $current_name . '?action=edit_config&name=' . $pf; ?>" class="btn btn-sm btn-outline-primary">编辑</a>
          <a href="/<?php echo $pf; ?>.php" target="_blank" class="btn btn-sm btn-outline-secondary">查看</a>
          <?php if ($pf !== 'index'): ?>
          <button class="btn btn-sm btn-outline-danger" onclick="if(confirm('确定删除配置「<?php echo htmlspecialchars($pf); ?>」？')) location='<?php echo $current_name . '?action=delete_config&name=' . $pf; ?>'">删除</button>
          <?php endif; ?>
          </div>
		</td>
  </tr>
    <?php endforeach; ?>
    </tbody>
  </table>
  </div>
</div>

<!-- 站点域名 -->
<div class="card shadow-sm card-shell mb-4" style="margin-top: 16px;">
  <div class="card-header-custom">
    <h5>站点域名</h5>
  </div>
  <div style="padding:16px 20px;">
    <?php if ($cloakCfEnabled): ?>
    <div class="alert alert-info mb-3" style="font-size:.88rem;">
      <strong>Cloudflare 已启用：</strong>添加域名后将自动创建 Zone 并显示 Nameserver；请到注册商修改 NS 后点击「检测/刷新」。NS 生效后将自动配置 proxied A 记录、Flexible SSL 与 Always HTTPS。
      源站仍需在宝塔添加站点并监听 <code><?php echo htmlspecialchars(CloudflareConfig::serverIp() ?: 'SERVER_IP'); ?></code>（Flexible：访客↔CF 为 HTTPS，CF↔源站为 HTTP）。
    </div>
    <?php else: ?>
    <div class="alert alert-warning mb-3" style="font-size:.88rem;">
      <strong>使用前请先在宝塔完成：</strong>在宝塔面板 → 网站 → 添加站点（填写下方相同域名）→ 申请并开启 SSL 证书。完成后再在此添加域名并关联配置。
      若在 <code>cong.php</code> 配置 Cloudflare API Token 与 Account ID，可自动创建 Zone 并管理 DNS/SSL。
    </div>
    <?php endif; ?>
    <form method="post" action="<?php echo $current_name; ?>" class="form-inline mb-3">
      <input type="hidden" name="action" value="add_domain">
      <input type="text" name="new_hostname" class="form-control form-control-sm mr-2" style="min-width:280px;" placeholder="例如 shop.example.com" required>
      <button type="submit" class="btn btn-sm" style="background:#16baaa;color:#fff;">添加域名</button>
    </form>
    <?php if (empty($cloakSiteDomains)): ?>
    <div class="empty-hint">尚未添加域名。未添加时，广告链接将使用当前后台访问域名：<code><?php echo htmlspecialchars($dashboardDefaultHost); ?></code></div>
    <?php else: ?>
    <div class="list-table-wrap">
    <table class="table table-sm mb-0 list-table">
      <thead><tr>
        <th>域名</th>
        <th>关联配置</th>
        <?php if ($cloakCfEnabled): ?><th>Cloudflare</th><th>Nameserver</th><?php endif; ?>
        <th style="width:140px;">操作</th>
      </tr></thead>
      <tbody>
      <?php foreach ($cloakSiteDomains as $dom):
        $cfStatus = $dom['cf_status'] ?? 'local';
        $cfLabel  = CloudflareConfig::statusLabel($cfStatus);
        $badgeCls = 'secondary';
        if ($cfStatus === 'pending_ns') { $badgeCls = 'warning'; }
        elseif ($cfStatus === 'provisioning') { $badgeCls = 'info'; }
        elseif ($cfStatus === 'ready') { $badgeCls = 'success'; }
        elseif ($cfStatus === 'error') { $badgeCls = 'danger'; }
        $nsList = CloudflareConfig::parseNameservers($dom['cf_nameservers'] ?? '');
        $delConfirm = '确定删除该域名？';
        if ($cloakCfEnabled && !empty($dom['cf_zone_id'])) {
            $delConfirm .= '将同时删除 Cloudflare Zone（不可恢复）。';
        }
      ?>
      <tr>
        <td><span class="domain-host-badge" title="<?php echo htmlspecialchars($dom['hostname'], ENT_QUOTES); ?>"><?php echo htmlspecialchars($dom['hostname']); ?></span></td>
        <td><?php
          if ($dom['config_name'] !== '') {
              echo '<span class="badge badge-light border">' . htmlspecialchars($dom['config_name']) . '</span>';
          } else {
              echo '<span class="text-muted">未关联</span>';
          }
        ?></td>
        <?php if ($cloakCfEnabled): ?>
        <td>
          <span class="badge badge-<?php echo $badgeCls; ?>"><?php echo htmlspecialchars($cfLabel); ?></span>
          <?php if ($cfStatus === 'error' && !empty($dom['cf_error'])): ?>
          <br><small class="text-danger"><?php echo htmlspecialchars($dom['cf_error']); ?></small>
          <?php endif; ?>
        </td>
        <td style="font-size:.8rem;max-width:220px;">
          <?php if ($nsList): ?>
            <?php foreach ($nsList as $ns): ?><div><span class="cell-truncate domain-host-badge" style="display:block;max-width:200px;" title="<?php echo htmlspecialchars($ns, ENT_QUOTES); ?>"><?php echo htmlspecialchars($ns); ?></span></div><?php endforeach; ?>
          <?php else: ?>
            <span class="text-muted">—</span>
          <?php endif; ?>
        </td>
        <?php endif; ?>
        <td class="text-nowrap">
          <div class="action-btn-group">
          <?php if ($cloakCfEnabled && in_array($cfStatus, ['pending_ns', 'provisioning', 'ready', 'error'], true)): ?>
          <form method="post" action="<?php echo $current_name; ?>" class="d-inline">
            <input type="hidden" name="action" value="check_domain">
            <input type="hidden" name="domain_id" value="<?php echo (int)$dom['id']; ?>">
            <button type="submit" class="btn btn-sm btn-outline-primary">检测/刷新</button>
          </form>
          <?php endif; ?>
          <a href="<?php echo $current_name; ?>?action=delete_domain&amp;domain_id=<?php echo (int)$dom['id']; ?>" class="btn btn-sm btn-outline-danger" onclick="return confirm('<?php echo htmlspecialchars($delConfirm, ENT_QUOTES); ?>');">删除</a>
          </div>
		</td>
  </tr>
      <?php endforeach; ?>
      </tbody>
    </table>
    </div>
    <?php endif; ?>
  </div>
</div>

<?php else: ?>
<!-- ===================== 编辑视图 ===================== -->

<a href="<?php echo $current_name; ?>" class="back-link">← 返回配置列表</a>

<div class="card shadow-sm" style="border-radius:8px;overflow:hidden;">
  <div class="card-header-custom">
    <h5>编辑配置：<?php echo htmlspecialchars($check_name); ?></h5>
    <div>
      <?php if (empty($_SESSION["check_result"]) || $_SESSION["check_result"] != "true"): ?>
      <a href="<?php echo $current_name; ?>?action=setuvi&res=true&name=<?php echo $check_name; ?>" class="btn btn-sm btn-outline-success mr-1">设置当前浏览器为真实访客</a>
      <?php else: ?>
      <a href="<?php echo $current_name; ?>?action=setuvi&res=false&name=<?php echo $check_name; ?>" class="btn btn-sm btn-outline-warning mr-1">清除访客状态</a>
      <?php endif; ?>
      
    </div>
  </div>

  <form action="<?php echo $current_name; ?>?action=submit" method="post" id="configForm">

  <div style="padding:16px;">

  <!-- ===== 基本设置 ===== -->
  <div class="form-section">
    <button type="button" class="section-toggle" data-target="sec-basic">
      基本设置 <span class="arrow">▼</span>
    </button>
    <div id="sec-basic">
    <table class="table table-sm mb-0">
      <tr>
        <td class="form-label-cell"><strong>配置名称</strong></td>
        <td class="form-val-cell">
          <input type="text" name="check_name" class="form-control form-control-sm" value="<?php echo htmlspecialchars($check_name); ?>" style="max-width:300px;">
          <small class="text-muted">示例：f123、d258</small>
					</td>
  </tr>
  <tr>
        <td class="form-label-cell">
          <strong>关联域名</strong><br>
          <small class="text-muted">请先在上方「站点域名」中添加并在宝塔创建该站点与 SSL</small>
					</td>
        <td class="form-val-cell">
          <select name="site_domain_id" class="form-control form-control-sm" style="max-width:360px;">
            <option value="0"<?php echo $selectedDomainId === 0 ? ' selected' : ''; ?>>
              不指定（广告链接使用当前后台域名：<?php echo htmlspecialchars($dashboardDefaultHost); ?>）
            </option>
            <?php foreach ($cloakSiteDomains as $dom): ?>
            <option value="<?php echo (int) $dom['id']; ?>"<?php echo $selectedDomainId === (int) $dom['id'] ? ' selected' : ''; ?>>
              <?php echo htmlspecialchars($dom['hostname']); ?>
              <?php if ($dom['config_name'] !== '' && $dom['config_name'] !== $check_name): ?>
                （已绑：<?php echo htmlspecialchars($dom['config_name']); ?>）
              <?php endif; ?>
            </option>
            <?php endforeach; ?>
          </select>
          <?php if (empty($cloakSiteDomains)): ?>
          <small class="text-warning d-block mt-1">尚未添加任何域名，保存后广告链接将使用 <?php echo htmlspecialchars($dashboardDefaultHost); ?></small>
          <?php endif; ?>
					</td>
  </tr>
  <tr>
        <td class="form-label-cell">
          是否开启 DEBUG 模式<br>
          <small class="text-muted">开启后访问落地链接将显示格式化调试页（判定结果、理由、代码行、访客信息），不会跳转真实页/安全页；生产环境请关闭</small>
					</td>
        <td class="form-val-cell"><?php echo onoff_radio('debug_mode', $_d('CLOAK_DEBUG_MODE','OFF')); ?></td>
  </tr>
  <tr>
        <td class="form-label-cell">屏蔽模式</td>
        <td class="form-val-cell">
          <div class="btn-group btn-group-toggle" data-toggle="buttons">
            <label class="btn btn-sm btn-outline-primary <?php if(SHOW_SITE_MODE_SWITCH == 'ip_check') echo 'active'; ?>">
              <input type="radio" name="methods" value="ip_check" <?php if(SHOW_SITE_MODE_SWITCH == 'ip_check') echo 'checked'; ?>> 正常屏蔽模式
            </label>
            <label class="btn btn-sm btn-outline-primary <?php if(SHOW_SITE_MODE_SWITCH == 'fp') echo 'active'; ?>">
              <input type="radio" name="methods" value="fp" <?php if(SHOW_SITE_MODE_SWITCH == 'fp') echo 'checked'; ?>> 真实页模式
            </label>
            <label class="btn btn-sm btn-outline-primary <?php if(SHOW_SITE_MODE_SWITCH == 'zp') echo 'active'; ?>">
              <input type="radio" name="methods" value="zp" <?php if(SHOW_SITE_MODE_SWITCH == 'zp') echo 'checked'; ?>> 安全页模式
            </label>
          </div>
					</td>
  </tr>
      <tr>
        <td class="form-label-cell">指定国家访问真实页（逗号分隔国家代码）</td>
        <td class="form-val-cell"><input type="text" name="country" class="form-control form-control-sm" value="<?php echo SHOW_SITE_COUNTRY; ?>" placeholder="如：US,GB,CA" style="max-width:300px;"></td>
  </tr>
  <tr>
        <td class="form-label-cell">广告策略 ID</td>
        <td class="form-val-cell"><input type="text" name="costm_ip_score" class="form-control form-control-sm" value="<?php echo COSTM_IP_SCORE; ?>" style="max-width:360px;"></td>
  </tr>
      
      <tr>
        <td class="form-label-cell">安全页跳转方式</td>
        <td class="form-val-cell">
          <select name="redirect_method" class="form-control form-control-sm" style="max-width:320px;">
            <option value="curl" <?php if(CLOAK_REDIRECT_METHOD=='curl') echo 'selected'; ?>>抓取显示（链接不变）</option>
            <option value="302"  <?php if(CLOAK_REDIRECT_METHOD=='302')  echo 'selected'; ?>>302 跳转（域名改变）</option>
            <option value="js"   <?php if(CLOAK_REDIRECT_METHOD=='js')   echo 'selected'; ?>>JS 跳转</option>
        </select>
	</td>
  </tr>
  <tr>
        <td class="form-label-cell">安全页链接（留空显示空白页）</td>
        <td class="form-val-cell"><input type="text" name="DB_zp" class="form-control form-control-sm" value="<?php echo DB_ZP; ?>" placeholder="https://..." style="max-width:420px;"></td>
  </tr>
      
      <tr>
        <td class="form-label-cell">真实页跳转方式</td>
        <td class="form-val-cell">
          <select name="show_content" class="form-control form-control-sm" style="max-width:320px;">
            <option value="curl" <?php if(CLOAK_SHOW_CONTENT=='curl') echo 'selected'; ?>>抓取显示（链接不变）</option>
            <option value="302"  <?php if(CLOAK_SHOW_CONTENT=='302')  echo 'selected'; ?>>302 跳转（域名改变）</option>
            <option value="js"   <?php if(CLOAK_SHOW_CONTENT=='js')   echo 'selected'; ?>>JS 跳转</option>
        </select>
	</td>
  </tr>
  <tr>
        <td class="form-label-cell">真实页链接地址</td>
        <td class="form-val-cell" id="db_fp">
        <?php
          if (DB_FP) {
              foreach (DB_FP as $idx => $link) {
                  if ($idx == 0) {
                      echo '<input type="text" name="DB_fp[]" class="form-control form-control-sm mb-1" value="' . htmlspecialchars($link) . '" style="max-width:420px;" data-idx="1"> <a href="javascript:void(0);" id="addNewLinkBtn" class="btn btn-sm btn-outline-secondary">+ 新增</a>';
                } else {
                      echo '<br><input type="text" name="DB_fp[]" class="form-control form-control-sm mt-1" value="' . htmlspecialchars($link) . '" style="max-width:420px;" data-idx="' . ($idx+1) . '"> <a href="javascript:void(0);" class="removeLinkBtn btn btn-sm btn-outline-danger">删除</a>';
                }
            }
            } else {
              echo '<input type="text" name="DB_fp[]" class="form-control form-control-sm" value="" style="max-width:420px;" data-idx="1"> <a href="javascript:void(0);" id="addNewLinkBtn" class="btn btn-sm btn-outline-secondary">+ 新增</a>';
            }
        ?>
	</td>
  </tr>
    </table>
    </div>
  </div>

  <!-- ===== IP 与名单 ===== -->
  <div class="form-section">
    <button type="button" class="section-toggle collapsed" data-target="sec-ip">
      IP黑白单管理 <span class="arrow">▼</span>
    </button>
    <div id="sec-ip" style="display:none;">
    <table class="table table-sm mb-0">
      <tr>
        <td class="form-label-cell">白名单 IP 组（允许访问真实页）</td>
        <td class="form-val-cell">
          <select name="whitelist_group_id" class="form-control form-control-sm" style="max-width:320px;">
            <option value="0" <?php if($currentWhitelistGroupId===0) echo 'selected'; ?>>无</option>
            <?php foreach($whiteGroups as $wg): ?>
            <option value="<?php echo (int)$wg['id']; ?>" <?php if($currentWhitelistGroupId===(int)$wg['id']) echo 'selected'; ?>><?php echo htmlspecialchars($wg['name']); ?> (ID <?php echo $wg['id']; ?>)</option>
            <?php endforeach; ?>
          </select>
          <small><a href="/admin_ip_manager.php?type=white" target="_blank">管理白名单</a></small>
		</td>
  </tr>
      <tr>
        <td class="form-label-cell">黑名单 IP 组（命中则拦截）</td>
        <td class="form-val-cell">
          <select name="blacklist_group_id" class="form-control form-control-sm" style="max-width:320px;">
            <option value="0" <?php if($currentBlacklistGroupId===0) echo 'selected'; ?>>无</option>
            <?php foreach($blackGroups as $bg): ?>
            <option value="<?php echo (int)$bg['id']; ?>" <?php if($currentBlacklistGroupId===(int)$bg['id']) echo 'selected'; ?>><?php echo htmlspecialchars($bg['name']); ?> (ID <?php echo $bg['id']; ?>)</option>
            <?php endforeach; ?>
          </select>
          <small><a href="/admin_ip_manager.php?type=black" target="_blank">管理黑名单</a></small>
	 </td>
      </tr>
      <tr>
        <td class="form-label-cell">自动黑名单（达到次数后自动加入黑名单组）</td>
        <td class="form-val-cell">
          <div class="d-flex align-items-center gap-2" style="gap:10px;">
            <div class="btn-group btn-group-toggle" data-toggle="buttons">
              <label class="btn btn-sm btn-outline-secondary <?php if(AUTO_BLACK=='ON') echo 'active'; ?>">
                <input type="radio" name="auto_black" id="auto_black_on" value="ON" <?php if(AUTO_BLACK=='ON') echo 'checked'; ?>> 开启
              </label>
              <label class="btn btn-sm btn-outline-secondary <?php if(AUTO_BLACK!='ON') echo 'active'; ?>">
                <input type="radio" name="auto_black" id="auto_black_off" value="OFF" <?php if(AUTO_BLACK!='ON') echo 'checked'; ?>> 关闭
              </label>
            </div>
            <span class="ml-2">触发次数：</span>
            <input type="number" name="auto_black_times" value="<?php echo AUTO_BLACK_TIMES; ?>" class="form-control form-control-sm" style="width:80px;" min="1">
          </div>
	</td>
  </tr>
      <tr>
        <td class="form-label-cell">白名单链接参数（携带此参数直接放行，格式：param=value）</td>
        <td class="form-val-cell"><input type="text" name="white_params" class="form-control form-control-sm" value="<?php echo htmlspecialchars(WHITE_PARAMS); ?>" style="max-width:280px;" placeholder="如：token=abc123"></td>
      </tr>
</table>
    </div>
  </div>

  <!-- ===== 设备与语言 ===== -->
  <div class="form-section">
    <button type="button" class="section-toggle collapsed" data-target="sec-device">
      设备与语言过滤 <span class="arrow">▼</span>
    </button>
    <div id="sec-device" style="display:none;">
    <table class="table table-sm mb-0">
      <tr>
        <td class="form-label-cell">屏蔽无 Referer 来源（防爬虫）</td>
        <td class="form-val-cell"><?php echo onoff_radio('v_referer', CLOAK_V_REFERER); ?></td>
      </tr>
      <tr>
        <td class="form-label-cell">仅允许移动端访问</td>
        <td class="form-val-cell"><?php echo onoff_radio('mobile_on', CLOAK_MOBILE_ON); ?></td>
      </tr>
      <tr>
        <td class="form-label-cell">屏蔽中文浏览器</td>
        <td class="form-val-cell"><?php echo onoff_radio('zh_on', CLOAK_ZH_ON); ?></td>
      </tr>
      <tr>
        <td class="form-label-cell">仅允许 iOS / Android 系统</td>
        <td class="form-val-cell"><?php echo onoff_radio('os_on', CLOAK_OS_ON); ?></td>
      </tr>
      <tr>
        <td class="form-label-cell">保留跳转链接参数</td>
        <td class="form-val-cell"><?php echo onoff_radio('keep_params', KEEP_PARAMS); ?></td>
      </tr>
      <tr>
        <td class="form-label-cell">屏蔽 iPhone 型号</td>
        <td class="form-val-cell">
          <select name="iphone_model" class="form-control form-control-sm" style="max-width:260px;">
            <option value="0"  <?php if(IPHONE_MODEL=='0')  echo 'selected'; ?>>不屏蔽</option>
            <option value="8"  <?php if(IPHONE_MODEL=='8')  echo 'selected'; ?>>屏蔽 iPhone 8 及以下</option>
            <option value="10" <?php if(IPHONE_MODEL=='10') echo 'selected'; ?>>屏蔽 iPhone X 及以下</option>
            <option value="11" <?php if(IPHONE_MODEL=='11') echo 'selected'; ?>>屏蔽 iPhone 11 及以下</option>
            <option value="12" <?php if(IPHONE_MODEL=='12') echo 'selected'; ?>>屏蔽 iPhone 12 及以下</option>
          </select>
        </td>
      </tr>
      <tr>
        <td class="form-label-cell">
          虚拟设备检测<br>
          <small class="text-muted">简单：全平台自动化/爬虫；标准：+环境一致性（移动无触摸等）；严格：+移动GPU校验与传感器（约180ms）</small>
        </td>
        <td class="form-val-cell">
          <select name="is_virtual" class="form-control form-control-sm" style="max-width:260px;">
            <option value="0" <?php if(IS_VIRTUAL=='0') echo 'selected'; ?>>不检测</option>
            <option value="1" <?php if(IS_VIRTUAL=='1') echo 'selected'; ?>>简单</option>
            <option value="2" <?php if(IS_VIRTUAL=='2') echo 'selected'; ?>>标准</option>
            <option value="3" <?php if(IS_VIRTUAL=='3') echo 'selected'; ?>>严格</option>
          </select>
</td>
</tr>
</table>
    </div>
  </div>

  <!-- ===== 广告来源限制 ===== -->
  <div class="form-section">
    <button type="button" class="section-toggle collapsed" data-target="sec-ad-source">
      广告来源限制 <span class="arrow">▼</span>
    </button>
    <div id="sec-ad-source" style="display:none;">
    <table class="table table-sm mb-0">
      <tr>
        <td class="form-label-cell">Facebook</td>
        <td class="form-val-cell"><?php echo onoff_radio('ad_fb', $_d('CLOAK_AD_FB', 'OFF')); ?></td>
      </tr>
      <tr>
        <td class="form-label-cell">Google</td>
        <td class="form-val-cell"><?php echo onoff_radio('ad_google', $_d('CLOAK_AD_GOOGLE', 'OFF')); ?></td>
      </tr>
      <tr>
        <td class="form-label-cell">TikTok</td>
        <td class="form-val-cell"><?php echo onoff_radio('ad_tiktok', $_d('CLOAK_AD_TIKTOK', 'OFF')); ?></td>
      </tr>
      <tr>
        <td class="form-label-cell">严格模式</td>
        <td class="form-val-cell">
          <?php echo onoff_radio('ad_strict', $_d('CLOAK_AD_STRICT', 'OFF')); ?>
          <div class="text-muted mt-1" style="font-size:.78rem;">开启后，未通过广告来源验证的访问将直接跳转安全页；关闭时仅追加「未确定流量来源」并继续后续判定，日志行显示为黄色。</div>
        </td>
      </tr>
      <tr>
        <td class="form-label-cell">强验证参数 ad_spm_id</td>
        <td class="form-val-cell">
          <?php $spmShow = $_d('CLOAK_AD_SPM_ID', ''); ?>
          <?php if ($spmShow !== ''): ?>
            <code><?php echo htmlspecialchars($spmShow); ?></code>
            <div class="text-muted mt-1" style="font-size:.78rem;">保存配置且开启任一广告平台时自动生成，写入广告链接用于强验证。</div>
          <?php else: ?>
            <span class="text-muted">保存并开启任一广告平台后自动生成</span>
          <?php endif; ?>
        </td>
      </tr>
    </table>
    </div>
  </div>

  <!-- ===== 高级设置 ===== -->
  <div class="form-section">
    <button type="button" class="section-toggle collapsed" data-target="sec-advanced">
      高级设置 <span class="arrow">▼</span>
    </button>
    <div id="sec-advanced" style="display:none;">
    <table class="table table-sm mb-0">
      <tr>
        <td class="form-label-cell">指纹风险系数（0=关闭，推荐50，最大90）</td>
        <td class="form-val-cell"><input type="number" name="risk_number" class="form-control form-control-sm" value="<?php echo CLOAK_RISK_NUMBER; ?>" style="width:100px;" min="0" max="90"></td>
      </tr>
      <tr>
        <td class="form-label-cell">加强判断</td>
        <td class="form-val-cell">
          <?php echo onoff_radio('risk_enhanced', $_d('CLOAK_RISK_ENHANCED', 'OFF')); ?>
          <div class="text-muted mt-1" style="font-size:.78rem;">开启后将额外采集 Canvas / WebGL / WebGPU / 字体等深度指纹，识别更精细；老旧设备或弱网环境下可能导致二次风控无法完成。仅在需要更高精度时开启。</div>
        </td>
      </tr>
      <tr>
        <td class="form-label-cell">
          临时链接参数有效时长（分钟，0=关闭）<br>
          <small class="text-muted">通过广告来源限制规则（ad_spm_id / clid / Referer / UA 等）后开始计时，有效时长内放行；到期重新判断。未开启广告平台时仍按 clid/ad_spm_id 触发。</small>
        </td>
        <td class="form-val-cell">
          <div class="d-flex align-items-center" style="gap:8px;">
            <input type="number" name="url_args_timeout" class="form-control form-control-sm" value="<?php echo CLOAK_URL_ARGS_TIMEOUT; ?>" style="width:90px;" min="0"> 分钟
            <button type="button" class="btn btn-sm btn-outline-warning" onclick="delUrlArgs()">重置计时</button>
          </div>
        </td>
      </tr>
      <tr>
        <td class="form-label-cell">记录访客日志</td>
        <td class="form-val-cell">
          <div class="btn-group btn-group-toggle" data-toggle="buttons">
            <label class="btn btn-sm btn-outline-secondary <?php if(WRITE_LOG=='1') echo 'active'; ?>">
              <input type="radio" name="write_log" value="1" <?php if(WRITE_LOG=='1') echo 'checked'; ?>> 开启
            </label>
            <label class="btn btn-sm btn-outline-secondary <?php if(WRITE_LOG!='1') echo 'active'; ?>">
              <input type="radio" name="write_log" value="0" <?php if(WRITE_LOG!='1') echo 'checked'; ?>> 关闭
            </label>
          </div>
	</td>
  </tr>
</table>
    </div>
  </div>

  </div><!-- /padding -->

  <!-- 底部操作栏 -->
  <div class="sticky-actions">
    <button type="submit" class="btn btn-primary">保存配置</button>
    <a href="<?php echo $current_name . '?action=edit_config&name=' . $check_name; ?>" class="btn btn-outline-secondary">重置</a>
    <a href="/table" target="_blank" class="btn btn-outline-info">查看日志</a>
    <a href="/log_analytics.php" target="_blank" class="btn btn-outline-info">数据分析</a>
    <a href="/share_log.php" target="_blank" class="btn btn-outline-info">分享日志</a>
  </div>

  </form>
</div>

<?php endif; ?>
</div><!-- /page-body -->

<script>
    $(function() {
    // 手风琴展开/折叠
    $('.section-toggle').on('click', function() {
        var target = '#' + $(this).data('target');
        $(this).toggleClass('collapsed');
        $(target).slideToggle(180);
    });

    // 动态添加链接
    var linkIdx = 1;
    $(document).on('click', '#addNewLinkBtn', function() {
        linkIdx++;
        var html = '<br><input type="text" name="DB_fp[]" class="form-control form-control-sm mt-1" value="" style="max-width:420px;" data-idx="' + linkIdx + '"> <a href="javascript:void(0);" class="removeLinkBtn btn btn-sm btn-outline-danger">删除</a>';
        $(this).after(html);
    });
    $(document).on('click', '.removeLinkBtn', function() {
        $(this).prev('br').remove();
        $(this).prev('input').remove();
        $(this).remove();
    });

    // 自动黑名单校验
    $('#configForm').on('submit', function() {
        var on  = $('#auto_black_on').is(':checked');
        var gid = parseInt($('select[name=blacklist_group_id]').val(), 10) || 0;
            if (on && gid <= 0) {
            alert('开启「自动黑名单」时，必须先选择「黑名单 IP 组」。');
                return false;
            }
            return true;
        });

    // 广告链接复制
    $(document).on('click', '.btn-copy-ad', function() {
        var text = $(this).attr('data-copy') || '';
        if (!text) return;
        var btn = this;
        var done = function() {
            var orig = btn.textContent;
            btn.textContent = '已复制';
            setTimeout(function() { btn.textContent = orig; }, 1200);
        };
        if (navigator.clipboard && navigator.clipboard.writeText) {
            navigator.clipboard.writeText(text).then(done).catch(function() {
                window.prompt('请手动复制链接：', text);
            });
        } else {
            window.prompt('请手动复制链接：', text);
        }
    });

});

function delUrlArgs() {
    if (!confirm('确认重置临时链接参数计时？')) return;
    window.location.href = '<?php echo $current_name; ?>?action=delUrlArgs&check_name=<?php echo urlencode($check_name); ?>';
}
</script>
</body>
</html>
