<?php
/**
 * 芋头CMS
 * ============================================================================
 * 版权所有 2016-2028 沅陵县乌托邦网络服务有限公司，并保留所有权利。
 * 网站地址: http://www.yutoucms.cn
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 * Author: 芋头 <mxgsf@qq.com>
 * Date: 2026-5-20
 */


$action = isset($_GET['action']) ? $_GET['action'] : 'list';

function buildChannelPreviewUrl($siteUrl, $urlMode, $channel) {
    $siteUrl = rtrim($siteUrl, '/');
    $id = intval($channel['id']);
    $channelType = intval($channel['channel_type']);
    $channelDir = isset($channel['channel_dir']) ? ltrim($channel['channel_dir'], '/') : '';
    $redirectUrl = isset($channel['redirect_url']) ? trim($channel['redirect_url']) : '';

    if ($redirectUrl !== '') {
        return $redirectUrl;
    }

    if ($urlMode === 'dynamic') {
        if ($channelType === 3) {
            return $siteUrl . '/index.php?m=page&id=' . $id;
        }
        if ($channelType === 8) {
            return $siteUrl . '/index.php?m=guestbook';
        }
        return $siteUrl . '/index.php?m=channel&id=' . $id;
    }

    if ($channelType === 3) {
        return $siteUrl . '/page/' . $id . '.html';
    }
    if ($channelType === 8) {
        return $siteUrl . '/guestbook/';
    }
    return $channelDir === '' || $channelDir === '/' ? $siteUrl . '/' : $siteUrl . '/' . $channelDir . '/';
}

// ========== AJAX GET 操作（预览URL） ==========
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['action']) && $_GET['action'] === 'get_url') {
    while (ob_get_level() > 0) { ob_end_clean(); }
    header('Content-Type: application/json; charset=utf-8');
    $id = isset($_GET['id']) ? intval($_GET['id']) : 0;
    if ($id <= 0) {
        echo json_encode(['code' => 400, 'msg' => '参数错误']);
        exit;
    }
    $ch = $db->fetch("SELECT * FROM {$db->table('channel')} WHERE id = ?", [$id]);
    if (!$ch) {
        echo json_encode(['code' => 404, 'msg' => '栏目不存在']);
        exit;
    }
    $siteUrlRow = $db->fetch("SELECT config_value FROM {$db->table('config')} WHERE config_key = 'site_url'");
    $siteUrl = $siteUrlRow ? rtrim($siteUrlRow['config_value'], '/') : '';
    // 检查URL模式，动态模式用 ?m=xxx&id= 的格式，否则用别名路径
    $urlModeRow = $db->fetch("SELECT config_value FROM {$db->table('config')} WHERE config_key = 'url_mode'");
    $urlMode = $urlModeRow ? $urlModeRow['config_value'] : 'dynamic';
    $url = buildChannelPreviewUrl($siteUrl, $urlMode, $ch);
    echo json_encode(['code' => 200, 'url' => $url]);
    exit;
}

// ========== AJAX 批量操作 ==========
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax_action'])) {
    // 清除所有输出缓冲，防止 HTML 前缀混入 JSON 响应
    while (ob_get_level() > 0) { ob_end_clean(); }
    header('Content-Type: application/json; charset=utf-8');
    $ajaxAct = $_POST['ajax_action'];

    // 批量删除
    if ($ajaxAct === 'batch_delete') {
        $raw = file_get_contents('php://input');
        $params = [];
        parse_str($raw, $params);
        $idsRaw = isset($params['ids']) ? $params['ids'] : '[]';
        $ids = json_decode($idsRaw, true);
        if (!is_array($ids)) { $ids = []; }
        $ids = array_map('intval', $ids);
        if (empty($ids)) {
            echo json_encode(['code' => 400, 'msg' => '请选择要删除的栏目']);
            exit;
        }
        // 递归删除下级栏目
        $allIds = [];
        foreach ($ids as $id) {
            $allIds[] = $id;
            $children = $db->fetchAll("SELECT id FROM {$db->table('channel')} WHERE parent_id = ?", [$id]);
            foreach ($children as $c) {
                $sub = [$c['id']];
                $subs2 = $db->fetchAll("SELECT id FROM {$db->table('channel')} WHERE parent_id = ?", [$c['id']]);
                foreach ($subs2 as $s) { $sub[] = $s['id']; }
                $allIds = array_merge($allIds, $sub);
            }
        }
        $allIds = array_unique($allIds);
        if (empty($allIds)) {
            echo json_encode(['code' => 200, 'msg' => '没有栏目可删除']);
            exit;
        }
        $placeholders2 = implode(',', array_fill(0, count($allIds), '?'));
        $db->query("DELETE FROM {$db->table('channel')} WHERE id IN ($placeholders2)", $allIds);
        echo json_encode(['code' => 200, 'msg' => '已删除 ' . count($allIds) . ' 个栏目']);
        exit;
    }

    // 批量显示/隐藏
    // 预览 - 获取栏目URL
    if ($ajaxAct === 'get_url') {
        $id = isset($_GET['id']) ? intval($_GET['id']) : 0;
        if ($id <= 0) {
            echo json_encode(['code' => 400, 'msg' => '参数错误']);
            exit;
        }
        $ch = $db->fetch("SELECT * FROM {$db->table('channel')} WHERE id = ?", [$id]);
        if (!$ch) {
            echo json_encode(['code' => 404, 'msg' => '栏目不存在']);
            exit;
        }
        $siteUrlRow = $db->fetch("SELECT config_value FROM {$db->table('config')} WHERE config_key = 'site_url'");
        $siteUrl = $siteUrlRow ? rtrim($siteUrlRow['config_value'], '/') : '';
        $urlModeRow = $db->fetch("SELECT config_value FROM {$db->table('config')} WHERE config_key = 'url_mode'");
        $urlMode = $urlModeRow ? $urlModeRow['config_value'] : 'dynamic';
        $url = buildChannelPreviewUrl($siteUrl, $urlMode, $ch);
        echo json_encode(['code' => 200, 'url' => $url]);
        exit;
    }

    if ($ajaxAct === 'batch_show' || $ajaxAct === 'batch_hide') {
        $idsRaw = isset($_POST['ids']) ? $_POST['ids'] : '';
        $ids = json_decode($idsRaw, true);
        if (!is_array($ids)) {
            $ids = json_decode(urldecode($idsRaw), true);
        }
        if (!is_array($ids)) { $ids = []; }
        $ids = array_map('intval', $ids);
        if (empty($ids)) {
            echo json_encode(['code' => 400, 'msg' => '请选择栏目']);
            exit;
        }
        $isShow = $ajaxAct === 'batch_show' ? 1 : 0;
        $placeholders = implode(',', array_fill(0, count($ids), '?'));
        $db->query("UPDATE {$db->table('channel')} SET is_show = ?, update_time = ? WHERE id IN ($placeholders)", array_merge([$isShow, time()], $ids));
        echo json_encode(['code' => 200, 'msg' => $ajaxAct === 'batch_show' ? '已批量显示' : '已批量隐藏']);
        exit;
    }

    // 批量移动
    if ($ajaxAct === 'batch_move') {
        $idsRaw = isset($_POST['ids']) ? $_POST['ids'] : '';
        $ids = json_decode($idsRaw, true);
        if (!is_array($ids)) {
            $ids = json_decode(urldecode($idsRaw), true);
        }
        if (!is_array($ids)) { $ids = []; }
        $ids = array_map('intval', $ids);
        $targetParent = isset($_POST['target_parent']) ? intval($_POST['target_parent']) : 0;
        if (empty($ids)) {
            echo json_encode(['code' => 400, 'msg' => '请选择要移动的栏目']);
            exit;
        }
        // 检查不能把栏目移动到自己或自己的下级
        foreach ($ids as $id) {
            if ($id === $targetParent) {
                echo json_encode(['code' => 400, 'msg' => '不能将栏目移动到自身']);
                exit;
            }
            if (isAncestorOf($id, $targetParent)) {
                echo json_encode(['code' => 400, 'msg' => '不能将栏目移动到自己的下级']);
                exit;
            }
        }
        $placeholders = implode(',', array_fill(0, count($ids), '?'));
        $db->query("UPDATE {$db->table('channel')} SET parent_id = ?, update_time = ? WHERE id IN ($placeholders)", array_merge([$targetParent, time()], $ids));
        echo json_encode(['code' => 200, 'msg' => '已移动 ' . count($ids) . ' 个栏目']);
        exit;
    }

    // 批量更新排序
    if ($ajaxAct === 'batch_sort') {
        $orders = isset($_POST['orders']) ? json_decode($_POST['orders'], true) : [];
        if (!empty($orders)) {
            foreach ($orders as $id => $order) {
                $db->update('channel', ['list_order' => intval($order), 'update_time' => time()], 'id = ?', [intval($id)]);
            }
        }
        echo json_encode(['code' => 200, 'msg' => '排序已更新，共 ' . count($orders) . ' 条']);
        exit;
    }

    // 单条删除
    if ($ajaxAct === 'delete') {
        $id = intval($_POST['id']);
        $children = $db->fetchAll("SELECT id FROM {$db->table('channel')} WHERE parent_id = ?", [$id]);
        $allIds = [$id];
        foreach ($children as $c) {
            $allIds = array_merge($allIds, getChildIds($c['id']));
        }
        $allIds = array_unique($allIds);
        $placeholders = implode(',', array_fill(0, count($allIds), '?'));
        $db->query("DELETE FROM {$db->table('channel')} WHERE id IN ($placeholders)", $allIds);
        addLog('删除', '栏目管理', '删除栏目 ID:' . $id);
        echo json_encode(['code' => 200, 'msg' => '已删除 ' . count($allIds) . ' 个栏目（含下级）']);
        exit;
    }

    // 保存新增/编辑
    if ($ajaxAct === 'save') {
        $id = intval($_POST['id']);
        $channel_name = trim($_POST['channel_name']);
        $channel_dir = trim($_POST['channel_dir']);
        $parent_id = intval($_POST['parent_id']);

        if (empty($channel_name)) {
            echo json_encode(['code' => 400, 'msg' => '栏目名称不能为空']);
            exit;
        }
        if (empty($channel_dir)) {
            echo json_encode(['code' => 400, 'msg' => '栏目别名不能为空']);
            exit;
        }
        // 别名唯一性检查
        $checkSql = $id > 0
            ? "SELECT id FROM {$db->table('channel')} WHERE channel_dir = ? AND id != ?"
            : "SELECT id FROM {$db->table('channel')} WHERE channel_dir = ?";
        $checkParams = $id > 0 ? [$channel_dir, $id] : [$channel_dir];
        if ($db->fetch($checkSql, $checkParams)) {
            echo json_encode(['code' => 400, 'msg' => '栏目别名已存在，请更换']);
            exit;
        }
        // 不能将父级设为自己或自己的下级
        if ($id > 0 && $parent_id > 0) {
            if ($id === $parent_id || isAncestorOf($id, $parent_id)) {
                echo json_encode(['code' => 400, 'msg' => '父级栏目选择非法']);
                exit;
            }
        }

        $data = [
            'channel_name' => $channel_name,
            'channel_dir' => strtolower(preg_replace('/[^a-z0-9_\-]/', '', $channel_dir)),
            'parent_id' => $parent_id,
            'channel_type' => intval($_POST['channel_type']),
            'list_template' => trim($_POST['list_template']),
            'article_template' => trim($_POST['article_template']),
            'redirect_url' => trim($_POST['redirect_url']),
            'seo_title' => trim($_POST['seo_title']),
            'seo_keywords' => trim($_POST['seo_keywords']),
            'seo_description' => trim($_POST['seo_description']),
            'view_level' => intval(isset($_POST['view_level']) ? $_POST['view_level'] : 0),
            'list_order' => intval($_POST['list_order']),
            'is_show' => isset($_POST['is_show']) ? 1 : 0,
            'channel_thumb' => trim($_POST['channel_thumb']),
            'channel_intro' => trim($_POST['channel_intro']),
            'update_time' => time()
        ];

        if ($id > 0) {
            $db->update('channel', $data, 'id = ?', [$id]);
            addLog('修改', '栏目管理', '修改栏目 ' . $channel_name);
            echo json_encode(['code' => 200, 'msg' => '保存成功']);
        } else {
            $data['create_time'] = time();
            $db->insert('channel', $data);
            addLog('添加', '栏目管理', '添加栏目 ' . $channel_name);
            echo json_encode(['code' => 200, 'msg' => '添加成功']);
        }
        exit;
    }

    // 预览
    if ($ajaxAct === 'preview') {
        $id = intval($_POST['id']);
        $ch = $db->fetch("SELECT channel_dir, channel_type FROM {$db->table('channel')} WHERE id = ?", [$id]);
        if ($ch) {
            $siteUrl = rtrim(getSiteConfig('site_url', 'http://' . $_SERVER['HTTP_HOST']), '/');
            $urlMode = getSiteConfig('url_mode', 'dynamic');
            $url = buildChannelPreviewUrl($siteUrl, $urlMode, array('id' => $id, 'channel_type' => $ch['channel_type'], 'channel_dir' => $ch['channel_dir']));
            echo json_encode(['code' => 200, 'url' => $url]);
        } else {
            echo json_encode(['code' => 404, 'msg' => '栏目不存在']);
        }
        exit;
    }

    echo json_encode(['code' => 400, 'msg' => '未知操作']);
    exit;
}

// ========== 辅助函数 ==========
function getChildIds($parentId) {
    global $db;
    $children = $db->fetchAll("SELECT id FROM {$db->table('channel')} WHERE parent_id = ?", [$parentId]);
    $ids = [];
    foreach ($children as $c) {
        $ids[] = $c['id'];
        $ids = array_merge($ids, getChildIds($c['id']));
    }
    return $ids;
}

function isAncestorOf($ancestorId, $targetId) {
    global $db;
    $current = $targetId;
    while ($current > 0) {
        $parent = $db->fetch("SELECT parent_id FROM {$db->table('channel')} WHERE id = ?", [$current]);
        if (!$parent) break;
        if ($parent['parent_id'] == $ancestorId) return true;
        $current = $parent['parent_id'];
    }
    return false;
}

function buildTree($channels, $parentId = 0, $depth = 0) {
    $result = [];
    foreach ($channels as $ch) {
        if ($ch['parent_id'] == $parentId) {
            $ch['_depth'] = $depth;
            $result[] = $ch;
            $result = array_merge($result, buildTree($channels, $ch['id'], $depth + 1));
        }
    }
    return $result;
}

// ========== 列表页 ==========
if ($action === 'list') {
    $channels = $db->fetchAll("SELECT * FROM {$db->table('channel')} ORDER BY list_order ASC");
    $totalChannel = $db->fetch("SELECT COUNT(*) as cnt FROM {$db->table('channel')}")['cnt'];
    $typeNames = ['', '文章', '产品', '单页', '图集', '下载', '图标', '视频', '留言', '招聘'];
    $typeIcons = ['', '📄', '🛒', '📋', '🖼', '📥', '🖼', '🎬', '💬', '👔'];
    $treeChannels = buildTree($channels);
    $visibleChannelCount = 0;
    $hiddenChannelCount = 0;
    $topLevelCount = 0;

    foreach ($channels as $channelItem) {
        if (!empty($channelItem['is_show'])) {
            $visibleChannelCount++;
        } else {
            $hiddenChannelCount++;
        }
        if (intval($channelItem['parent_id']) === 0) {
            $topLevelCount++;
        }
    }

    // 获取模板文件列表
    $templateFiles = [];
    $tplDir = dirname(__DIR__, 2) . '/template/default/';
    if (is_dir($tplDir)) {
        foreach (glob($tplDir . '*.html') as $f) {
            $templateFiles[] = basename($f);
        }
    }
    ?>
    <div class="page-container fade-in channel-admin-page">
        <div class="page-header">
            <div class="page-title">
                <div class="page-icon">📂</div>
                <div>
                    <h1>栏目管理</h1>
                    <p style="font-size:12px;color:#64748b;margin:0;">维护栏目结构、显示状态与排序规则，不展示页面摘要卡。</p>
                </div>
            </div>
            <div class="page-actions channel-page-actions">
                <button class="btn btn-secondary" type="button" onclick="batchAction('show')">批量显示</button>
                <button class="btn btn-secondary" type="button" onclick="batchAction('hide')">批量隐藏</button>
                <button class="btn btn-danger" type="button" onclick="batchAction('delete')">批量删除</button>
                <a href="?act=channel&action=add" class="btn btn-primary">添加栏目</a>
            </div>
        </div>

        <div class="channel-context-bar">
            <div class="channel-context-item">
                <span class="channel-context-label">栏目总数</span>
                <span class="channel-context-value"><?php echo $totalChannel; ?> 个</span>
            </div>
            <div class="channel-context-item">
                <span class="channel-context-label">顶级栏目</span>
                <span class="channel-context-value"><?php echo $topLevelCount; ?> 个</span>
            </div>
            <div class="channel-context-item">
                <span class="channel-context-label">显示状态</span>
                <span class="channel-context-value"><?php echo $visibleChannelCount; ?> 显示 / <?php echo $hiddenChannelCount; ?> 隐藏</span>
            </div>
            <div class="channel-context-item">
                <span class="channel-context-label">当前说明</span>
                <span class="channel-context-value channel-context-muted">支持拖拽或数字排序，批量操作对已勾选栏目生效。</span>
            </div>
        </div>

        <div class="channel-toolbar">
            <div class="channel-sort-mode">
                <span class="channel-sort-label">排序模式</span>
                <label class="channel-sort-option">
                <input type="radio" name="sortMode" value="drag" checked onchange="setSortMode('drag')" style="accent-color:#2563eb;">
                <span>拖拽排序</span>
            </label>
                <label class="channel-sort-option">
                <input type="radio" name="sortMode" value="number" onchange="setSortMode('number')" style="accent-color:#2563eb;">
                <span>数字排序</span>
            </label>
            </div>
            <button class="btn btn-sm btn-success" id="saveSortBtn" onclick="saveSort()" style="display:none;">保存排序</button>
        </div>

        <div class="content-card">
            <?php if (empty($treeChannels)): ?>
            <div class="empty-state">
                <div class="empty-icon" style="font-size:40px;">📂</div>
                <h3>暂无栏目</h3>
                <p>创建第一个栏目吧</p>
            </div>
            <?php else: ?>
            <div class="channel-table-shell">
                <table class="data-table channel-data-table" style="min-width:960px;">
                    <thead>
                        <tr>
                            <th style="width:40px;"><input type="checkbox" id="checkAll" onchange="toggleCheckAll(this)" style="accent-color:#2563eb;width:16px;height:16px;cursor:pointer;"></th>
                            <th style="width:60px;">ID</th>
                            <th>栏目名称</th>
                            <th style="width:100px;">别名</th>
                            <th style="width:80px;">模型</th>
                            <th style="width:100px;">状态</th>
                            <th style="width:70px;">排序</th>
                            <th style="width:320px;">操作</th>
                        </tr>
                    </thead>
                    <tbody id="channelTableBody">
                        <?php foreach ($treeChannels as $item): ?>
                        <?php
                        $previewUrl = '/public/index.php?m=channel&id=' . $item['id'];
                        $channelType = intval($item['channel_type']);
                        if ($channelType == 3) {
                            $previewUrl = '/public/index.php?m=page&id=' . $item['id'];
                        } elseif ($channelType == 8) {
                            $previewUrl = '/public/index.php?m=guestbook';
                        }
                        ?>
                        <tr class="channel-row" data-id="<?php echo $item['id']; ?>" data-parent="<?php echo $item['parent_id']; ?>">
                            <td style="text-align:center;">
                                <input type="checkbox" class="row-check" value="<?php echo $item['id']; ?>" style="accent-color:#2563eb;width:16px;height:16px;cursor:pointer;">
                            </td>
                            <td class="id-cell"><?php echo $item['id']; ?></td>
                            <td>
                                <div class="channel-name-cell">
                                    <span class="drag-handle" style="cursor:grab;color:#94a3b8;font-size:16px;display:none;" title="拖拽排序">☰</span>
                                    <?php if ($item['_depth'] > 0): ?>
                                    <span class="channel-depth-tree" style="margin-left:<?php echo $item['_depth'] * 16; ?>px;">
                                        <?php for ($i = 0; $i < $item['_depth']; $i++): ?><span style="color:#cbd5e1;">│</span><?php endfor; ?>
                                        <span style="color:#cbd5e1;">├─</span>
                                    </span>
                                    <?php endif; ?>
                                    <div class="channel-type-icon">
                                        <?php echo $typeIcons[$item['channel_type']]; ?>
                                    </div>
                                    <div class="channel-name-meta">
                                        <span class="channel-name-text"><?php echo htmlspecialchars($item['channel_name']); ?></span>
                                        <?php if ($item['_depth'] === 0): ?>
                                        <span class="channel-level-tag">顶级</span>
                                        <?php endif; ?>
                                    </div>
                                    <?php if (!empty($item['channel_thumb'])): ?>
                                    <img src="<?php echo htmlspecialchars($item['channel_thumb']); ?>" style="width:20px;height:20px;object-fit:cover;border-radius:4px;" onerror="this.style.display='none';">
                                    <?php endif; ?>
                                </div>
                            </td>
                            <td><code class="channel-code"><?php echo htmlspecialchars($item['channel_dir']); ?></code></td>
                            <td><span class="badge badge-primary"><?php echo $typeNames[$item['channel_type']]; ?></span></td>
                            <td>
                                <?php if ($item['is_show']): ?>
                                <span class="channel-status-text is-show">显示</span>
                                <?php else: ?>
                                <span class="channel-status-text is-hide">隐藏</span>
                                <?php endif; ?>
                            </td>
                            <td>
                                <input type="number" value="<?php echo $item['list_order']; ?>" min="0" class="sort-input" onchange="onSortChange(<?php echo $item['id']; ?>, this)" style="width:60px;padding:4px 8px;border:1px solid #e2e8f0;border-radius:6px;font-size:13px;text-align:center;" title="数字越大越靠前">
                            </td>
                            <td style="width:250px;">
                                <div class="btn-group channel-row-actions">
                                    <a href="<?php echo $previewUrl; ?>" target="_blank" class="btn btn-sm channel-btn-lite" title="在新窗口打开">预览</a>
                                    <a href="?act=channel&action=edit&id=<?php echo $item['id']; ?>" class="btn btn-primary btn-sm" style="min-width:64px;text-align:center;">编辑</a>
                                    <?php
                                    $ct = intval($item['channel_type']);
                                    $typeActs = [1=>'article', 2=>'product', 3=>'page', 4=>'image', 5=>'download', 7=>'video', 9=>'recruit'];
                                    $typeLabels = [1=>'文章', 2=>'产品', 3=>'单页', 4=>'图集', 5=>'下载', 7=>'视频', 9=>'招聘'];
                                    $typeColors = ['1'=>'#ede9fe:#7c3aed', '2'=>'#fef3c7:#d97706', '3'=>'#f0fdf4:#16a34a', '4'=>'#dbeafe:#2563eb', '5'=>'#dcfce7:#16a34a', '7'=>'#fce7f3:#db2777', '9'=>'#fed7aa:#ea580c'];
                                    if (isset($typeActs[$ct])):
                                        $act = $typeActs[$ct];
                                        list($bg, $color) = explode(':', $typeColors[strval($ct)]);
                                    ?>
                                    <a href="?act=<?php echo $act; ?>&action=add&channel_id=<?php echo $item['id']; ?>" class="btn btn-sm" style="min-width:60px;text-align:center;background:<?php echo $bg; ?>;color:<?php echo $color; ?>;" title="添加<?php echo $typeLabels[$ct]; ?>">新增</a>
                                    <?php endif; ?>
                                    <a href="javascript:deleteChannel(<?php echo $item['id']; ?>);" class="btn btn-sm channel-btn-danger">删除</a>
                                </div>
                            </td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
            <?php endif; ?>
        </div>
    </div>

    <!-- 批量移动弹窗 -->
    <div id="moveModal" class="channel-move-modal" style="display:none;">
        <div class="channel-move-card">
            <h3 style="font-size:16px;font-weight:600;margin:0 0 16px 0;color:#1e293b;">批量移动栏目</h3>
            <div class="channel-move-field">
                <label style="display:block;font-size:13px;color:#64748b;margin-bottom:6px;">目标上级栏目</label>
                <select id="targetParent" class="form-control">
                    <option value="0">移至顶级</option>
                    <?php foreach ($channels as $ch): ?>
                    <option value="<?php echo $ch['id']; ?>"><?php echo str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $ch['parent_id'] > 0 ? 1 : 0) . htmlspecialchars($ch['channel_name']); ?></option>
                    <?php endforeach; ?>
                </select>
            </div>
            <div class="channel-move-actions">
                <button onclick="closeMoveModal()" class="btn btn-secondary">取消</button>
                <button onclick="confirmMove()" class="btn btn-primary">确认移动</button>
            </div>
        </div>
    </div>

    <script>
    var currentSortMode = 'drag';
    var changedSorts = {};

    function setSortMode(mode) {
        currentSortMode = mode;
        var handleCols = document.querySelectorAll('.drag-handle');
        var saveBtn = document.getElementById('saveSortBtn');
        var sortInputs = document.querySelectorAll('.sort-input');
        if (mode === 'drag') {
            handleCols.forEach(function(h) { h.style.display = 'none'; });
            saveBtn.style.display = 'none';
            sortInputs.forEach(function(inp) { inp.readOnly = true; inp.style.background = '#f8fafc'; });
            initDragSort();
        } else {
            handleCols.forEach(function(h) { h.style.display = 'block'; });
            saveBtn.style.display = 'none';
            sortInputs.forEach(function(inp) { inp.readOnly = false; inp.style.background = '#fff'; });
            // 移除拖拽
            var tbody = document.getElementById('channelTableBody');
            if (tbody._sortable) { tbody._sortable.destroy(); }
        }
    }

    function initDragSort() {
        var tbody = document.getElementById('channelTableBody');
        if (tbody._sortable) { tbody._sortable.destroy(); }
        // 简单拖拽实现
        var rows = document.querySelectorAll('.channel-row');
        var draggedRow = null;
        rows.forEach(function(row) {
            row.draggable = true;
            row.ondragstart = function(e) {
                draggedRow = this;
                this.style.opacity = '0.5';
                e.dataTransfer.effectAllowed = 'move';
            };
            row.ondragend = function() {
                this.style.opacity = '1';
                draggedRow = null;
            };
            row.ondragover = function(e) {
                e.preventDefault();
                this.style.borderTop = '2px solid #2563eb';
            };
            row.ondragleave = function() {
                this.style.borderTop = '';
            };
            row.ondrop = function(e) {
                e.preventDefault();
                this.style.borderTop = '';
                if (draggedRow && draggedRow !== this) {
                    var tbody = document.getElementById('channelTableBody');
                    var nextRow = this.nextElementSibling;
                    if (nextRow === draggedRow) nextRow = this.nextElementSibling;
                    if (nextRow) {
                        tbody.insertBefore(draggedRow, nextRow);
                    } else {
                        tbody.appendChild(draggedRow);
                    }
                    document.getElementById('saveSortBtn').style.display = 'block';
                }
            };
        });
    }

    function onSortChange(id, input) {
        changedSorts[id] = input.value;
        document.getElementById('saveSortBtn').style.display = 'block';
    }

    function deleteChannel(id) {
        if (!confirm('确定删除此栏目？其下级栏目也会一并删除。')) return;
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '?act=channel', true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    try {
                        var d = JSON.parse(xhr.responseText);
                        alert(d.msg || '操作完成');
                        if (d.code == 200) location.reload();
                    } catch(e) {
                        alert('JSON解析失败: ' + e.message + '\n\n原始响应:\n' + xhr.responseText.substring(0, 500));
                    }
                } else {
                    alert('请求失败，状态: ' + xhr.status + '\n\n响应:\n' + xhr.responseText.substring(0, 300));
                }
            }
        };
        xhr.send('ajax_action=delete&id=' + id);
    }

    function saveSort() {
        var rows = document.querySelectorAll('.channel-row');
        var orders = {};
        rows.forEach(function(row, index) {
            var id = parseInt(row.dataset.id);
            orders[id] = rows.length - index;
        });
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '?act=channel', true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    try {
                        var d = JSON.parse(xhr.responseText);
                        alert(d.msg || '操作完成');
                        if (d.code == 200) location.reload();
                    } catch(e) {
                        alert('JSON解析失败: ' + e.message + '\n\n原始响应:\n' + xhr.responseText.substring(0, 500));
                    }
                } else {
                    alert('请求失败，状态: ' + xhr.status + '\n\n响应:\n' + xhr.responseText.substring(0, 300));
                }
            }
        };
        xhr.send('ajax_action=batch_sort&orders=' + encodeURIComponent(JSON.stringify(orders)));
    }

    function toggleCheckAll(cb) {
        document.querySelectorAll('.row-check').forEach(function(c) { c.checked = cb.checked; });
    }

    function getSelectedIds() {
        var ids = [];
        document.querySelectorAll('.row-check:checked').forEach(function(c) { ids.push(c.value); });
        return ids;
    }

    function batchAction(action) {
        var ids = getSelectedIds();
        if (ids.length === 0) { alert('请先勾选要操作的栏目'); return; }
        if (action === 'hide') {
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '?act=channel', true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        try {
                            var d = JSON.parse(xhr.responseText);
                            alert(d.msg || '操作完成');
                            if (d.code == 200) location.reload();
                        } catch(e) {
                            alert('响应不是JSON:\n' + xhr.responseText.substring(0, 500));
                        }
                    } else {
                        alert('请求失败，状态: ' + xhr.status);
                    }
                }
            };
            xhr.send('ajax_action=batch_hide&ids=' + encodeURIComponent(JSON.stringify(ids)));
            return;
        }
        if (action === 'show') {
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '?act=channel', true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        try {
                            var d = JSON.parse(xhr.responseText);
                            alert(d.msg || '操作完成');
                            if (d.code == 200) location.reload();
                        } catch(e) {
                            alert('响应不是JSON:\n' + xhr.responseText.substring(0, 500));
                        }
                    } else {
                        alert('请求失败，状态: ' + xhr.status);
                    }
                }
            };
            xhr.send('ajax_action=batch_show&ids=' + encodeURIComponent(JSON.stringify(ids)));
            return;
        }
        if (action === 'delete') {
            if (!confirm('确定删除选中的 ' + ids.length + ' 个栏目？其下级栏目也会一并删除。')) return;
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '?act=channel', true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        try {
                            var d = JSON.parse(xhr.responseText);
                            alert(d.msg || '操作完成');
                            if (d.code == 200) location.reload();
                        } catch(e) {
                            alert('响应不是JSON:\n' + xhr.responseText.substring(0, 500));
                        }
                    } else {
                        alert('请求失败，状态: ' + xhr.status);
                    }
                }
            };
            xhr.send('ajax_action=batch_delete&ids=' + encodeURIComponent(JSON.stringify(ids)));
            return;
        }
    }

    function closeMoveModal() {
        document.getElementById('moveModal').style.display = 'none';
    }

    function confirmMove() {
        var ids = getSelectedIds();
        var targetParent = document.getElementById('targetParent').value;
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '?act=channel', true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    try {
                        var d = JSON.parse(xhr.responseText);
                        alert(d.msg || '操作完成');
                        if (d.code == 200) location.reload();
                    } catch(e) {
                        alert('响应不是JSON:\n' + xhr.responseText.substring(0, 500));
                    }
                } else {
                    alert('请求失败，状态: ' + xhr.status);
                }
            }
        };
        xhr.send('ajax_action=batch_move&ids=' + encodeURIComponent(JSON.stringify(ids)) + '&target_parent=' + encodeURIComponent(targetParent));
    }

    function toggleShow(id, label) {
        var sw = label.querySelector('div');
        var cb = label.querySelector('.show-toggle');
        var newVal = cb.checked ? 0 : 1;
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/admin/main.php?act=channel&action=toggle', true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    try {
                        var d = JSON.parse(xhr.responseText);
                        if (d.code == 200) {
                            cb.checked = !cb.checked;
                            sw.style.background = newVal ? '#10b981' : '#cbd5e1';
                            sw.querySelector('div').style.left = newVal ? '19px' : '3px';
                        } else {
                            alert(d.msg);
                        }
                    } catch(e) {
                        // 状态已改前端同步，无视解析错误
                    }
                }
            }
        };
        xhr.send('id=' + id + '&is_show=' + newVal);
    }

    document.addEventListener('DOMContentLoaded', function() {
        setSortMode('drag');
    });
    </script>
    <?php
}

// ========== 新增/编辑页 ==========
if ($action === 'add' || $action === 'edit') {
    $defaults = [
        'id' => '', 'channel_name' => '', 'channel_dir' => '', 'parent_id' => 0,
        'channel_type' => 1, 'list_template' => '', 'article_template' => '',
        'redirect_url' => '', 'seo_title' => '', 'seo_keywords' => '',
        'seo_description' => '', 'view_level' => 0, 'list_order' => 100,
        'is_show' => 1, 'channel_thumb' => '', 'channel_intro' => ''
    ];
    if ($action === 'edit' && isset($_GET['id'])) {
        $editData = array_merge($defaults, $db->fetch("SELECT * FROM {$db->table('channel')} WHERE id = ?", [intval($_GET['id'])]));
    } else {
        $editData = $defaults;
    }
    $isEdit = $action === 'edit';

    // 获取模板文件列表
    $templateFiles = [];
    $tplDir = dirname(__DIR__, 2) . '/template/default/';
    if (is_dir($tplDir)) {
        foreach (glob($tplDir . '*.html') as $f) {
            $templateFiles[] = basename($f);
        }
    }

    // 所有栏目（用于父级选择，排除自己及下级）
    $allChannels = $db->fetchAll("SELECT id, channel_name, parent_id FROM {$db->table('channel')} ORDER BY list_order ASC");
    if ($isEdit) {
        $excludeIds = array_merge([$editData['id']], getChildIds($editData['id']));
    } else {
        $excludeIds = [];
    }

    function renderParentOptions($channels, $parentId = 0, $selected = 0, $depth = 0, $exclude = []) {
        foreach ($channels as $ch) {
            if ($ch['parent_id'] == $parentId && !in_array($ch['id'], $exclude)) {
                echo '<option value="'.$ch['id'].'"'.($selected == $ch['id'] ? ' selected' : '').'>'.str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $depth).'├ '.$ch['channel_name'].'</option>';
                renderParentOptions($channels, $ch['id'], $selected, $depth + 1, $exclude);
            }
        }
    }
    ?>
    <div class="page-container fade-in">
        <div class="page-header">
            <div class="page-title">
                <div class="page-icon" style="font-size:22px;"><?php echo $isEdit ? '✏️' : '➕'; ?></div>
                <div><h1><?php echo $isEdit ? '编辑栏目' : '添加栏目'; ?></h1><p style="font-size:12px;color:#64748b;margin:0;">填写栏目信息</p></div>
            </div>
            <div class="page-actions"><a href="?act=channel" class="btn btn-secondary">&larr; 返回列表</a></div>
        </div>

        <form id="channelForm" onsubmit="return false;">
            <input type="hidden" name="id" value="<?php echo $editData['id']; ?>">

            <!-- 基本信息 -->
            <div class="form-section">
                <div class="form-section-header">ℹ️ 基本信息</div>
                <div class="form-section-body">
                    <div class="form-row">
                        <div class="form-group">
                            <label>栏目名称 <span class="required">*</span></label>
                            <input type="text" name="channel_name" class="form-control" value="<?php echo htmlspecialchars($editData['channel_name']); ?>" placeholder="请输入栏目名称" required>
                        </div>
                        <div class="form-group">
                            <label>栏目别名 <span class="required">*</span></label>
                            <input type="text" name="channel_dir" class="form-control" value="<?php echo htmlspecialchars($editData['channel_dir']); ?>" placeholder="英文小写，唯一不重复" required>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-group">
                            <label>上级栏目</label>
                            <select name="parent_id" class="form-control">
                                <option value="0">顶级栏目（无上级）</option>
                                <?php renderParentOptions($allChannels, 0, $editData['parent_id'], 0, $excludeIds); ?>
                            </select>
                        </div>
                        <div class="form-group">
                            <label>栏目模型</label>
                            <select name="channel_type" class="form-control">
                                <option value="1" <?php echo $editData['channel_type']==1?'selected':''; ?>>📄 文章模型</option>
                                <option value="2" <?php echo $editData['channel_type']==2?'selected':''; ?>>🛒 产品模型</option>
                                <option value="3" <?php echo $editData['channel_type']==3?'selected':''; ?>>📋 单页模型</option>
                                <option value="4" <?php echo $editData['channel_type']==4?'selected':''; ?>>🖼️ 图集模型</option>
                                <option value="5" <?php echo $editData['channel_type']==5?'selected':''; ?>>📥 下载模型</option>
                                <option value="7" <?php echo $editData['channel_type']==7?'selected':''; ?>>🎬 视频模型</option>
                                <option value="8" <?php echo $editData['channel_type']==8?'selected':''; ?>>💬 留言模型</option>
                                <option value="9" <?php echo $editData['channel_type']==9?'selected':''; ?>>👔 招聘模型</option>
                            </select>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 模板设置 -->
            <div class="form-section">
                <div class="form-section-header">🎨 模板设置</div>
                <div class="form-section-body">
                    <div class="form-row">
                        <div class="form-group">
                            <label>列表模板</label>
                            <select name="list_template" class="form-control">
                                <option value="">使用默认模板</option>
                                <?php foreach ($templateFiles as $tpl): ?>
                                <option value="<?php echo htmlspecialchars($tpl); ?>" <?php echo $editData['list_template']==$tpl?'selected':''; ?>><?php echo htmlspecialchars($tpl); ?></option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                        <div class="form-group">
                            <label>内容模板</label>
                            <select name="article_template" class="form-control">
                                <option value="">使用默认模板</option>
                                <?php foreach ($templateFiles as $tpl): ?>
                                <option value="<?php echo htmlspecialchars($tpl); ?>" <?php echo $editData['article_template']==$tpl?'selected':''; ?>><?php echo htmlspecialchars($tpl); ?></option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                    </div>
                    <div class="form-group">
                        <label>跳转链接</label>
                        <input type="text" name="redirect_url" class="form-control" value="<?php echo htmlspecialchars($editData['redirect_url']); ?>" placeholder="填写后前台直接跳转，不展示内容">
                    </div>
                </div>
            </div>

            <!-- SEO设置 -->
            <div class="form-section">
                <div class="form-section-header">🔍 SEO设置</div>
                <div class="form-section-body">
                    <div class="form-row">
                        <div class="form-group">
                            <label>SEO标题</label>
                            <input type="text" name="seo_title" class="form-control" value="<?php echo htmlspecialchars($editData['seo_title']); ?>" placeholder="独立填写SEO标题">
                        </div>
                        <div class="form-group">
                            <label>SEO关键词</label>
                            <input type="text" name="seo_keywords" class="form-control" value="<?php echo htmlspecialchars($editData['seo_keywords']); ?>" placeholder="关键字1,关键字2,关键字3">
                        </div>
                    </div>
                    <div class="form-group">
                        <label>SEO描述</label>
                        <textarea name="seo_description" class="form-control" rows="3" placeholder="独立填写SEO描述"><?php echo htmlspecialchars($editData['seo_description']); ?></textarea>
                    </div>
                </div>
            </div>

            <!-- 权限与显示 -->
            <div class="form-section">
                <div class="form-section-header">🛡️ 权限与显示</div>
                <div class="form-section-body">
                    <div class="form-row">
                        <div class="form-group">
                            <label>浏览权限</label>
                            <select name="view_level" class="form-control">
                                <option value="0" <?php echo $editData['view_level']==0?'selected':''; ?>>🌐 游客可浏览</option>
                                <option value="1" <?php echo $editData['view_level']==1?'selected':''; ?>>👤 仅会员浏览</option>
                                <option value="2" <?php echo $editData['view_level']==2?'selected':''; ?>>⭐ 初级会员+</option>
                                <option value="3" <?php echo $editData['view_level']==3?'selected':''; ?>>💎 中级会员+</option>
                                <option value="4" <?php echo $editData['view_level']==4?'selected':''; ?>>👑 高级会员+</option>
                            </select>
                        </div>
                        <div class="form-group">
                            <label>排序数字</label>
                            <input type="number" name="list_order" class="form-control" value="<?php echo $editData['list_order']; ?>" min="0" placeholder="数字越大越靠前" style="width:150px;">
                        </div>
                    </div>
                    <div style="display:flex;align-items:center;gap:16px;margin-top:8px;">
                        <label style="display:flex;align-items:center;gap:10px;cursor:pointer;">
                            <input type="checkbox" name="is_show" value="1" <?php echo $editData['is_show']?'checked':''; ?> id="isShowToggle" style="display:none;">
                            <div id="isShowSwitch" style="width:44px;height:24px;background:<?php echo $editData['is_show']?'#10b981':'#cbd5e1'; ?>;border-radius:12px;position:relative;transition:all 0.2s;cursor:pointer;">
                                <div style="width:18px;height:18px;background:#fff;border-radius:50%;position:absolute;top:3px;left:<?php echo $editData['is_show']?'23px':'3px'; ?>;transition:all 0.2s;box-shadow:0 1px 3px rgba(0,0,0,0.2);"></div>
                            </div>
                            <span id="isShowLabel" style="font-weight:500;color:<?php echo $editData['is_show']?'#10b981':'#64748b'; ?>;"><?php echo $editData['is_show']?'前台显示':'前台隐藏'; ?></span>
                        </label>
                    </div>
                </div>
            </div>

            <!-- 栏目图标与简介 -->
            <div class="form-section">
                <div class="form-section-header">🖼️ 图文设置</div>
                <div class="form-section-body">
                    <div class="form-group">
                        <label>栏目缩略图</label>
                        <div style="display:flex;align-items:center;gap:12px;">
                            <div id="thumbPreview" onclick="document.getElementById('thumbInput').click();" style="width:80px;height:80px;border:2px dashed #e2e8f0;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;overflow:hidden;background:#f8fafc;transition:all 0.2s;" onmouseover="this.style.borderColor='#2563eb';" onmouseout="this.style.borderColor='#e2e8f0';">
                                <?php if (!empty($editData['channel_thumb'])): ?>
                                <img src="<?php echo htmlspecialchars($editData['channel_thumb']); ?>" style="width:100%;height:100%;object-fit:cover;" onerror="this.parentElement.innerHTML='<div style=\'text-align:center;color:#94a3b8;\'><div style=\'font-size:24px;margin-bottom:4px;\'>🖼</div><div style=\'font-size:11px;\'>点击上传</div></div>';">
                                <?php else: ?>
                                <div style="text-align:center;color:#94a3b8;">
                                    <div style="font-size:24px;margin-bottom:4px;">🖼</div>
                                    <div style="font-size:11px;">点击上传</div>
                                </div>
                                <?php endif; ?>
                            </div>
                            <input type="file" id="thumbInput" accept="image/*" style="display:none;" onchange="uploadThumb(this)">
                            <input type="text" name="channel_thumb" id="thumbUrl" class="form-control" value="<?php echo htmlspecialchars($editData['channel_thumb']); ?>" placeholder="或直接输入图片URL" style="flex:1;">
                        </div>
                    </div>
                    <div class="form-group">
                        <label>栏目简介</label>
                        <textarea name="channel_intro" class="form-control" rows="3" placeholder="简短介绍前台可调用"><?php echo htmlspecialchars($editData['channel_intro']); ?></textarea>
                    </div>
                </div>
            </div>

            <div class="form-actions">
                <button type="button" class="btn btn-success btn-lg" onclick="submitChannelForm()">
                    ✅ <?php echo $isEdit ? '保存修改' : '确认添加'; ?>
                </button>
                <a href="?act=channel" class="btn btn-secondary btn-lg">取消</a>
            </div>
        </form>
    </div>

    <script>
    // 显示/隐藏开关
    document.getElementById('isShowToggle').addEventListener('change', function() {
        var sw = document.getElementById('isShowSwitch');
        var lb = document.getElementById('isShowLabel');
        if (this.checked) {
            sw.style.background = '#10b981';
            sw.querySelector('div').style.left = '23px';
            lb.textContent = '前台显示';
            lb.style.color = '#10b981';
        } else {
            sw.style.background = '#cbd5e1';
            sw.querySelector('div').style.left = '3px';
            lb.textContent = '前台隐藏';
            lb.style.color = '#64748b';
        }
    });

    // 点击switch也能切换
    document.getElementById('isShowSwitch').addEventListener('click', function() {
        var cb = document.getElementById('isShowToggle');
        cb.checked = !cb.checked;
        cb.dispatchEvent(new Event('change'));
    });

    // 缩略图上传
    function uploadThumb(input) {
        if (!input.files || !input.files[0]) return;
        var formData = new FormData();
        formData.append('file', input.files[0]);
        formData.append('upload_type', 'image');
        formData.append('csrf_token', '<?php echo rawurlencode(getAdminCsrfToken()); ?>');
        fetch('/admin/main.php?act=upload', {method:'POST', body:formData})
            .then(function(r) { return r.json(); })
            .then(function(d) {
                if (d.code == 200) {
                    document.getElementById('thumbUrl').value = d.data.url;
                    document.getElementById('thumbPreview').innerHTML = '<img src="' + d.data.url + '" style="width:100%;height:100%;object-fit:cover;">';
                } else {
                    alert(d.msg);
                }
            });
    }

    // 缩略图URL变化时更新预览
    document.getElementById('thumbUrl').addEventListener('input', function() {
        var url = this.value;
        var preview = document.getElementById('thumbPreview');
        if (url) {
            preview.innerHTML = '<img src="' + url + '" style="width:100%;height:100%;object-fit:cover;" onerror="this.parentElement.innerHTML=\'<div style=text-align:center;color:#94a3b8;><div style=font-size:24px;margin-bottom:4px;>🖼</div><div style=font-size:11px;>图片失效</div></div>\';">';
        } else {
            preview.innerHTML = '<div style="text-align:center;color:#94a3b8;"><div style="font-size:24px;margin-bottom:4px;">🖼</div><div style="font-size:11px;">点击上传</div></div>';
        }
    });

    // 提交表单
    function submitChannelForm() {
        var form = document.getElementById('channelForm');
        var formData = new FormData(form);
        formData.append('ajax_action', 'save');
        fetch('?act=channel', {method:'POST', body: formData})
            .then(function(r) { return r.json(); })
            .then(function(d) {
                if (d.code == 200) {
                    alert(d.msg);
                    location.href = '?act=channel';
                } else {
                    alert(d.msg);
                }
            }).catch(function() { alert('提交失败，请重试'); });
    }

    if (window.lucide && typeof window.lucide.createIcons === 'function') { window.lucide.createIcons(); }
    </script>
    <?php
}
?>
