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

if (!defined('ADMIN_LOADED')) {
    header('HTTP/1.1 403 Forbidden');
    exit('Access Denied');
}

global $conn;

$action = isset($_GET['action']) ? (string)$_GET['action'] : '';
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;

if ($action === 'approve' && $id > 0) {
    $stmt = $conn->prepare("UPDATE publish SET status = 1 WHERE id = ?");
    $stmt->bind_param('i', $id);
    $stmt->execute();
    $ok = $stmt->affected_rows >= 0;
    $stmt->close();
    if ($ok) $success = '已通过';
    else $error = '操作失败';
}

if ($action === 'reject' && $id > 0) {
    $stmt = $conn->prepare("UPDATE publish SET status = 2 WHERE id = ?");
    $stmt->bind_param('i', $id);
    $stmt->execute();
    $ok = $stmt->affected_rows >= 0;
    $stmt->close();
    if ($ok) $success = '已驳回';
    else $error = '操作失败';
}

if ($action === 'pending' && $id > 0) {
    $stmt = $conn->prepare("UPDATE publish SET status = 0 WHERE id = ?");
    $stmt->bind_param('i', $id);
    $stmt->execute();
    $ok = $stmt->affected_rows >= 0;
    $stmt->close();
    if ($ok) $success = '已设为待审核';
    else $error = '操作失败';
}

if ($action === 'delete' && $id > 0) {
    $stmt = $conn->prepare("DELETE FROM publish WHERE id = ?");
    $stmt->bind_param('i', $id);
    $stmt->execute();
    $ok = $stmt->affected_rows > 0;
    $stmt->close();
    if ($ok) $success = '已删除';
    else $error = '删除失败';
}

$edit_row = null;
if ($action === 'edit' && $id > 0) {
    $edit_row = get_single_row($conn, "SELECT id, category_id, title, keywords, description, content, thumbnail FROM publish WHERE id = ? LIMIT 1", array($id));
    if (!$edit_row) {
        $error = '投稿不存在';
        $action = '';
    }
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['edit_publish']) && $_POST['edit_publish'] === '1') {
    $edit_id = isset($_POST['publish_id']) ? intval($_POST['publish_id']) : 0;
    $publish_title = isset($_POST['publish_title']) ? trim($_POST['publish_title']) : '';
    $publish_keywords = isset($_POST['publish_keywords']) ? trim($_POST['publish_keywords']) : '';
    $publish_description = isset($_POST['publish_description']) ? trim($_POST['publish_description']) : '';
    $publish_content = isset($_POST['publish_content']) ? $_POST['publish_content'] : '';
    $publish_thumbnail = isset($_POST['publish_thumbnail']) ? trim($_POST['publish_thumbnail']) : '';
    $publish_category_id = isset($_POST['publish_category_id']) ? intval($_POST['publish_category_id']) : 0;
    if ($edit_id <= 0 || $publish_title === '') {
        $error = '参数错误';
    } else {
        $stmt = $conn->prepare("UPDATE publish SET title=?, keywords=?, description=?, content=?, thumbnail=?, category_id=? WHERE id=?");
        $stmt->bind_param('sssssii', $publish_title, $publish_keywords, $publish_description, $publish_content, $publish_thumbnail, $publish_category_id, $edit_id);
        $stmt->execute();
        $ok = $stmt->affected_rows >= 0;
        $stmt->close();
        if ($ok) {
            $success = '更新成功';
            $action = '';
        } else {
            $error = '更新失败';
        }
    }
}

$page = isset($current_page) ? intval($current_page) : 1;
$posts_per_page = isset($posts_per_page) ? intval($posts_per_page) : 30;
$search_query = isset($search) ? trim((string)$search) : (isset($_GET['search']) ? trim((string)$_GET['search']) : '');
$status_filter = isset($_GET['status']) ? trim((string)$_GET['status']) : 'all';

$page = max(1, $page);
$posts_per_page = max(1, min(1000, $posts_per_page));
$offset = ($page - 1) * $posts_per_page;

$where = '1=1';
$params = [];
$types = '';

if ($status_filter !== '' && $status_filter !== 'all') {
    $sf = intval($status_filter);
    if (in_array($sf, [0, 1, 2], true)) {
        $where .= ' AND p.status = ?';
        $params[] = $sf;
        $types .= 'i';
    }
}

if ($search_query !== '') {
    $like = '%' . $search_query . '%';
    $where .= ' AND (p.title LIKE ? OR u.username LIKE ?)';
    $params[] = $like;
    $params[] = $like;
    $types .= 'ss';
}

$total_rows = 0;
$total_pages = 1;

$count_sql = "SELECT COUNT(*) AS total FROM publish p LEFT JOIN users u ON p.user_id = u.id WHERE $where";
$count_stmt = $conn->prepare($count_sql);
if ($count_stmt) {
    if ($types !== '') $count_stmt->bind_param($types, ...$params);
    $count_stmt->execute();
    $count_result = $count_stmt->get_result();
    $count_row = $count_result ? $count_result->fetch_assoc() : null;
    $total_rows = $count_row ? intval($count_row['total']) : 0;
    $count_stmt->close();
    $total_pages = max(1, (int)ceil($total_rows / $posts_per_page));
}

$sql = "SELECT p.id, p.user_id, p.category_id, p.title, p.thumbnail, p.status, p.created_at, u.username, IFNULL(c.name,'') AS category_name
        FROM publish p
        LEFT JOIN users u ON p.user_id = u.id
        LEFT JOIN categories c ON p.category_id = c.id
        WHERE $where
        ORDER BY p.id DESC
        LIMIT ?, ?";

$list = [];
$stmt = $conn->prepare($sql);
if ($stmt) {
    $final_params = $params;
    $final_params[] = $offset;
    $final_params[] = $posts_per_page;
    $final_types = $types . 'ii';
    $stmt->bind_param($final_types, ...$final_params);
    $stmt->execute();
    $result = $stmt->get_result();
    if ($result) {
        while ($row = $result->fetch_assoc()) {
            $list[] = $row;
        }
    }
    $stmt->close();
} else {
    $error = '投稿数据加载失败';
}

$build_base = '?tab=publish';
$p_param = 'p' . $page . '_s' . $posts_per_page;
$common_qs = $build_base . '&' . $p_param;
if ($search_query !== '') $common_qs .= '&search=' . urlencode($search_query);
if ($status_filter !== '' && $status_filter !== 'all') $common_qs .= '&status=' . urlencode($status_filter);

$categories = array();
if (function_exists('getCategories')) {
    $categories = getCategories();
    if (!is_array($categories)) $categories = array();
}

$auditFilterText = '审核';
if ($status_filter === '0' || $status_filter === 0) $auditFilterText = '未审核';
if ($status_filter === '1' || $status_filter === 1) $auditFilterText = '已通过';
?>

<div class="section-header" style="display:flex;align-items:center;justify-content:space-between;">
    <h2>投稿管理</h2>
</div>

<style>
    .admin-table.publish-manage th,
    .admin-table.publish-manage td {
        vertical-align: middle !important;
    }

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

    .admin-table.publish-manage th:first-child,
    .admin-table.publish-manage td:first-child {
        width: 80px !important;
        min-width: 80px !important;
        max-width: 80px !important;
    }

    .admin-table.publish-manage th:nth-child(2),
    .admin-table.publish-manage td:nth-child(2) {
        text-align: center !important;
        width: 100px !important;
        min-width: 100px !important;
        max-width: 100px !important;
    }

    .admin-table.publish-manage td:nth-child(2) img {
        display: block;
        margin: 0 auto;
    }

    .admin-table.publish-manage th.audit-col,
    .admin-table.publish-manage td.audit-col {
        width: 90px !important;
        min-width: 90px !important;
        max-width: 90px !important;
    }

    .admin-table.publish-manage td.audit-col {

        line-height: normal !important;
    }

    .admin-table.publish-manage th.author-col,
    .admin-table.publish-manage td.author-col {
        width: 110px !important;
        min-width: 110px !important;
        max-width: 110px !important;
        text-align: center !important;
    }

    .admin-table.publish-manage th.category-col,
    .admin-table.publish-manage td.category-col {
        width: 150px !important;
        min-width: 150px !important;
        max-width: 150px !important;
    }

    .admin-table.publish-manage th.time-col,
    .admin-table.publish-manage td.time-col {
        width: 200px !important;
        min-width: 200px !important;
        max-width: 200px !important;
        white-space: nowrap !important;
    }

    .admin-table.publish-manage th.fixed-action-column,
    .admin-table.publish-manage td.fixed-action-column {
        width: 180px !important;
        min-width: 180px !important;
        max-width: 180px !important;
        text-align: right !important;
    }

    .admin-table.publish-manage th.title-col,
    .admin-table.publish-manage td.title-col {
        width: auto !important;
    }

    .admin-table.publish-manage td.title-col {
        white-space: nowrap !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
    }

    .admin-table.publish-manage .publish-title-text[data-qk-tip] {
        display: inline;
        line-height: 1.4 !important;
        vertical-align: middle;
        cursor: default;
    }

    .admin-table.publish-manage .publish-category-select {
        width: 100px !important;
        min-width: 100px !important;
        max-width: 100px !important;
        height: 34px !important;
        line-height: 34px !important;
        padding-top: 0 !important;
        padding-bottom: 0 !important;
        padding-left: 10px !important;
        padding-right: 28px !important;
        box-sizing: border-box !important;
        white-space: nowrap !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
    }

    .admin-table.publish-manage .audit-header-wrap {
        position: relative;
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    #publish-audit-header.publish-audit-header-trigger {
        display: inline-flex;
        align-items: center;
        position: relative;
        padding-right: 30px;
        cursor: pointer;
        font-weight: 600;
    }

    #publish-audit-header.publish-audit-header-trigger::after {
        content: '';
        position: absolute;
        right: 6px;
        top: 50%;
        transform: translateY(-50%);
        width: 16px;
        height: 16px;
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23666' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M3 6l5 5 5-5'/%3E%3C/svg%3E");
        background-repeat: no-repeat;
        background-position: center;
        background-size: 16px;
        pointer-events: none;
    }

    #publish-audit-dropdown-menu.publish-audit-dropdown-menu {
        border: 1px solid #ddd;
        border-radius: 0px;
        background-color: #fff;
        box-shadow: none;
        max-height: 300px;
        overflow-y: auto;
        padding: 0;
        width: 125px;
    }

    #publish-audit-dropdown-menu .publish-audit-dropdown-item {
        height: 30px;
        line-height: 30px;
        padding: 0 10px;
        font-size: 12px;
        cursor: pointer;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        color: #333;
    }

    #publish-audit-dropdown-menu .publish-audit-dropdown-item:hover {
        background-color: var(--primary-color);
        color: #fff;
    }
</style>

<div class="admin-card">
    <div class="table-container">
        <div class="admin-table-wrapper">
            <div class="admin-table-scroll">
                <table class="admin-table section-manage publish-manage">
                    <colgroup>
                        <col style="width:80px">
                        <col style="width:100px">
                        <col style="width:110px">
                        <col>
                        <col style="width:150px">
                        <col style="width:200px">
                        <col style="width:90px">
                        <col style="width:180px">
                    </colgroup>
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>缩略图</th>
                            <th class="author-col">投稿用户</th>
                            <th class="title-col">标题</th>
                            <th class="category-col">分类栏目</th>
                            <th class="time-col">提交时间</th>
                            <th class="audit-col">
                                <div class="audit-header-wrap">
                                    <span id="publish-audit-header" class="publish-audit-header-trigger" onclick="togglePublishAuditMenu()"><?php echo $auditFilterText; ?></span>
                                    <div id="publish-audit-dropdown-menu" class="publish-audit-dropdown-menu" style="display:none;">
                                        <div class="publish-audit-dropdown-item" onclick="filterPublishAuditStatus('all')">全部投稿</div>
                                        <div class="publish-audit-dropdown-item" onclick="filterPublishAuditStatus('1')">已通过</div>
                                        <div class="publish-audit-dropdown-item" onclick="filterPublishAuditStatus('0')">未审核</div>
                                    </div>
                                </div>
                            </th>
                            <th class="fixed-action-column">操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php if (!$list): ?>
                            <tr>
                                <td colspan="8" class="empty-state" style="text-align:center !important;height:75px;line-height:75px;font-size:16px;color:#64748b;">当前列表暂无数据</td>
                            </tr>
                        <?php else: ?>
                            <?php foreach ($list as $row):
                                $sid = intval($row['id']);
                                $suser = intval($row['user_id'] ?? 0);
                                $susername = htmlspecialchars($row['username'] ?? '', ENT_QUOTES);
                                $stitle_raw = (string)($row['title'] ?? '');
                                $stitle = htmlspecialchars($stitle_raw, ENT_QUOTES);
                                $scategory_id = intval($row['category_id'] ?? 0);
                                $sstatus = intval($row['status'] ?? 0);
                                $screated = htmlspecialchars($row['created_at'] ?? '', ENT_QUOTES);
                                $thumb = !empty($row['thumbnail']) ? htmlspecialchars($row['thumbnail'], ENT_QUOTES) : '/assets/images/moren.jpg';
                                $checked = $sstatus === 1 ? 'checked' : '';
                                $auditDisabled = $sstatus === 1 ? 'disabled' : '';
                                $authorText = $susername !== '' ? $susername : ($suser > 0 ? (string)$suser : '-');
                                $selectedCategoryName = '';
                            ?>
                                <tr>
                                    <td><?php echo $sid; ?></td>
                                    <td><img src="<?php echo $thumb; ?>" style="width:60px;height:45px;object-fit:cover;border-radius:4px;" loading="lazy" alt=""></td>
                                    <td class="author-col"><?php echo $authorText; ?></td>
                                    <td class="title-col"><span class="publish-title-text" data-qk-tip="<?php echo htmlspecialchars($stitle_raw, ENT_QUOTES); ?>"><?php echo $stitle; ?></span></td>
                                    <td class="category-col">
                                        <select class="form-control category-select publish-category-select" data-id="<?php echo $sid; ?>" onchange="togglePublishCategory(this)" title="<?php echo htmlspecialchars($selectedCategoryName, ENT_QUOTES); ?>">
                                            <?php foreach ($categories as $cat):
                                                $cid = intval($cat['id'] ?? 0);
                                                if ($cid <= 0) continue;
                                                $cname = htmlspecialchars($cat['name'] ?? '', ENT_QUOTES);
                                                $sel = $cid === $scategory_id ? 'selected' : '';
                                                if ($sel !== '') $selectedCategoryName = $cname;
                                            ?>
                                                <option value="<?php echo $cid; ?>" <?php echo $sel; ?>><?php echo $cname; ?></option>
                                            <?php endforeach; ?>
                                        </select>
                                    </td>
                                    <td class="time-col"><?php echo $screated; ?></td>
                                    <td class="audit-col">
                                        <label class="theme-switch">
                                            <input type="checkbox" class="publish-approve-switch" data-id="<?php echo $sid; ?>" <?php echo $checked; ?> <?php echo $auditDisabled; ?> onchange="togglePublishApproved(this)">
                                            <span class="slider round"></span>
                                        </label>
                                    </td>
                                    <td class="fixed-action-column">
                                        <button type="button" class="btn btn-sm btn-primary" onclick="openPublishEditModal(<?php echo $sid; ?>)">编辑</button>
                                        <a class="btn btn-sm btn-danger" href="<?php echo $common_qs . '&action=delete&id=' . $sid; ?>">删除</a>
                                    </td>
                                </tr>
                            <?php endforeach; ?>
                        <?php endif; ?>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>

<script>
    window.isDemoAdminPublishPage = <?php echo function_exists('isDemoAdmin') && isDemoAdmin() ? 'true' : 'false'; ?>;

    function escapeHtml(text) {
        if (text === null || text === undefined) return '';
        return String(text)
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;');
    }

    function handlePublishAjaxResult(result, successMessage, onSuccess) {
        if (result && result.success === false) {
            if (typeof showToast === 'function') showToast(result.message || result.error || '演示账号无权限操作', 'error', 1500);
            return false;
        }
        if (result && result.success === true) {
            if (typeof showToast === 'function') showToast(result.message || successMessage, 'success', 1200);
            if (typeof onSuccess === 'function') onSuccess(result);
            return true;
        }
        if (typeof showToast === 'function') showToast(successMessage, 'success', 1200);
        if (typeof onSuccess === 'function') onSuccess(result || {});
        return true;
    }

    const publishCategories = <?php
                                $simpleCats = array();
                                foreach ($categories as $cat) {
                                    $cid = intval($cat['id'] ?? 0);
                                    if ($cid <= 0) continue;
                                    $simpleCats[] = array('id' => $cid, 'name' => (string)($cat['name'] ?? ''));
                                }
                                echo json_encode($simpleCats, JSON_UNESCAPED_UNICODE);
                                ?>;

    function closeAllPublishMenus() {
        const menu = document.getElementById('publish-audit-dropdown-menu');
        if (menu) {
            menu.style.display = 'none';
        }
    }

    window.addEventListener('scroll', function() {
        closeAllPublishMenus();
    }, {
        passive: true
    });

    function togglePublishAuditMenu() {
        const auditHeader = document.getElementById('publish-audit-header');
        const auditDropdownMenu = document.getElementById('publish-audit-dropdown-menu');
        if (!auditHeader || !auditDropdownMenu) return;

        const isOpen = auditDropdownMenu.style.display === 'block';
        if (isOpen) {
            auditDropdownMenu.style.display = 'none';
            return;
        }

        if (auditDropdownMenu.parentElement !== document.body) {
            document.body.appendChild(auditDropdownMenu);
        }

        const rect = auditHeader.getBoundingClientRect();
        auditDropdownMenu.style.position = 'fixed';
        auditDropdownMenu.style.top = (rect.bottom - 23) + 'px';
        auditDropdownMenu.style.left = rect.left + 'px';
        auditDropdownMenu.style.zIndex = '2147483647';
        auditDropdownMenu.style.display = 'block';
    }

    function filterPublishAuditStatus(status) {
        const auditDropdownMenu = document.getElementById('publish-audit-dropdown-menu');
        if (auditDropdownMenu) auditDropdownMenu.style.display = 'none';
        changePublishAuditStatus(status);
    }

    function changePublishAuditStatus(status) {
        if (typeof HeaderPagination !== 'undefined') {
            const urlParams = new URLSearchParams(window.location.search);
            if (status === 'all') {
                urlParams.delete('status');
            } else {
                urlParams.set('status', status);
            }
            urlParams.delete('page');
            urlParams.delete('posts_per_page');
            for (const key of Array.from(urlParams.keys())) {
                if (key.match(/^p\\d+_s\\d+$/)) urlParams.delete(key);
            }
            const pageSize = HeaderPagination.state && HeaderPagination.state.pageSize ? HeaderPagination.state.pageSize : 30;
            let newUrl = '?tab=publish&p1_s' + pageSize;
            for (const [key, value] of urlParams.entries()) {
                if (key !== 'tab') newUrl += '&' + key + '=' + encodeURIComponent(value);
            }
            window.history.pushState({}, document.title, newUrl);

            HeaderPagination.state.page = 1;
            HeaderPagination.load();
        }
    }

    function togglePublishApproved(el) {
        const id = parseInt(el.getAttribute('data-id') || '0', 10) || 0;
        if (id <= 0) return;
        const approved = !!el.checked;
        const fd = new URLSearchParams();
        fd.set('action', 'update_publish_status');
        fd.set('id', String(id));
        fd.set('status', approved ? '1' : '0');
        el.disabled = true;
        fetch('/admin/ajaxx.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            body: fd.toString(),
            credentials: 'include'
        }).then(r => r.json()).then(d => {
            if (!d || !d.success) {
                const msg = d && d.message ? d.message : '更新失败';
                throw new Error(msg);
            }
            if (approved && d.data && (d.data.migrated || d.data.deleted)) {
                if (typeof showToast === 'function') showToast('已通过并发布', 'success', 1200);
                if (typeof HeaderPagination !== 'undefined' && HeaderPagination.load) {
                    HeaderPagination.load();
                } else {
                    const tr = el.closest('tr');
                    if (tr) tr.remove();
                }
                return;
            }
            if (typeof showToast === 'function') showToast('已更新', 'success', 1200);
        }).catch(err => {
            el.checked = !approved;
            if (typeof showToast === 'function') showToast((err && err.message) ? err.message : '更新失败', 'error', 1500);
        }).finally(() => {
            el.disabled = false;
        });
    }

    function togglePublishCategory(el) {
        const id = parseInt(el.getAttribute('data-id') || '0', 10) || 0;
        const categoryId = parseInt(el.value || '0', 10) || 0;
        if (id <= 0 || categoryId <= 0) return;
        const fd = new URLSearchParams();
        fd.set('action', 'update_publish_category');
        fd.set('id', String(id));
        fd.set('category_id', String(categoryId));
        el.disabled = true;
        fetch('/admin/ajaxx.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            body: fd.toString(),
            credentials: 'include'
        }).then(r => r.json()).then(d => {
            if (!d || !d.success) {
                const msg = d && d.message ? d.message : '更新失败';
                throw new Error(msg);
            }
            try {
                el.title = el.options && el.selectedIndex >= 0 ? (el.options[el.selectedIndex].text || '') : '';
            } catch (e) {}
            if (typeof showToast === 'function') showToast('已更新', 'success', 1200);
        }).catch(err => {
            if (typeof showToast === 'function') showToast((err && err.message) ? err.message : '更新失败', 'error', 1500);
        }).finally(() => {
            el.disabled = false;
        });
    }

    function renderPublishList(pageData) {
        const d = pageData && (pageData.data || pageData) || {};
        const list = d.publish || [];
        const tbody = document.querySelector('.admin-table.publish-manage tbody');
        if (!tbody) return;

        function escapeHtml(text) {
            if (text === null || text === undefined) return '';
            const div = document.createElement('div');
            div.textContent = String(text);
            return div.innerHTML;
        }

        function buildCommonQs() {
            const urlParams = new URLSearchParams(window.location.search);
            const p = (typeof HeaderPagination !== 'undefined' && HeaderPagination.state && HeaderPagination.state.page) ? HeaderPagination.state.page : 1;
            const s = (typeof HeaderPagination !== 'undefined' && HeaderPagination.state && HeaderPagination.state.pageSize) ? HeaderPagination.state.pageSize : 30;
            let qs = '?tab=publish&p' + p + '_s' + s;
            if (urlParams.get('search')) qs += '&search=' + encodeURIComponent(urlParams.get('search'));
            if (urlParams.get('status')) qs += '&status=' + encodeURIComponent(urlParams.get('status'));
            return qs;
        }

        if (!list.length) {
            tbody.innerHTML = '<tr><td colspan="8" class="empty-state" style="text-align:center !important;height:75px;line-height:75px;font-size:16px;color:#64748b;">当前列表暂无数据</td></tr>';
            return;
        }

        const base = buildCommonQs();
        let html = '';
        list.forEach(row => {
            const sid = parseInt(row.id, 10) || 0;
            const uid = parseInt(row.user_id, 10) || 0;
            const uname = row.username ? String(row.username) : '';
            const authorText = uname !== '' ? uname : (uid > 0 ? String(uid) : '-');
            const thumb = row.thumbnail ? String(row.thumbnail) : '/assets/images/moren.jpg';
            const title = row.title ? String(row.title) : '';
            const categoryId = parseInt(row.category_id, 10) || 0;
            const st = parseInt(row.status, 10) || 0;
            const created = row.created_at ? String(row.created_at) : '';
            const checked = st === 1 ? ' checked' : '';
            const disabled = st === 1 ? ' disabled' : '';
            let selectedName = '';
            let options = '';
            if (Array.isArray(publishCategories)) {
                publishCategories.forEach(c => {
                    const cid = parseInt(c.id, 10) || 0;
                    if (cid <= 0) return;
                    const cname = c.name ? String(c.name) : '';
                    const sel = cid === categoryId ? ' selected' : '';
                    if (sel) selectedName = cname;
                    options += '<option value="' + cid + '"' + sel + '>' + escapeHtml(cname) + '</option>';
                });
            }

            html += '<tr>' +
                '<td>' + sid + '</td>' +
                '<td><img src="' + escapeHtml(thumb) + '" style="width:60px;height:45px;object-fit:cover;border-radius:4px;" loading="lazy" alt=""></td>' +
                '<td class="author-col">' + escapeHtml(authorText) + '</td>' +
                '<td class="title-col"><span class="publish-title-text" data-qk-tip="' + escapeHtml(title) + '">' + escapeHtml(title) + '</span></td>' +
                '<td class="category-col"><select class="form-control category-select publish-category-select" data-id="' + sid + '" onchange="togglePublishCategory(this)" title="' + escapeHtml(selectedName) + '">' + options + '</select></td>' +
                '<td class="time-col">' + escapeHtml(created) + '</td>' +
                '<td class="audit-col"><label class="theme-switch"><input type="checkbox" class="publish-approve-switch" data-id="' + sid + '"' + checked + disabled + ' onchange="togglePublishApproved(this)"><span class="slider round"></span></label></td>' +
                '<td class="fixed-action-column">' +
                '<button type="button" class="btn btn-sm btn-primary" onclick="openPublishEditModal(' + sid + ')">编辑</button> ' +
                '<a class="btn btn-sm btn-danger" href="' + base + '&action=delete&id=' + sid + '">删除</a>' +
                '</td>' +
                '</tr>';
        });
        tbody.innerHTML = html;
    }

    document.addEventListener('DOMContentLoaded', function() {
        if (typeof HeaderPagination !== 'undefined') {
            HeaderPagination.state.page = <?php echo intval($page); ?>;
            HeaderPagination.state.pageSize = <?php echo intval($posts_per_page); ?>;
            HeaderPagination.state.total = <?php echo intval($total_rows); ?>;
            HeaderPagination.state.totalPages = <?php echo intval($total_pages); ?>;

            HeaderPagination.cache.page = <?php echo intval($page); ?>;
            HeaderPagination.cache.pageSize = <?php echo intval($posts_per_page); ?>;
            HeaderPagination.cache.totalPages = <?php echo intval($total_pages); ?>;

            HeaderPagination.init();
            HeaderPagination.updateUI();
        }
    });

    let publishEditModal = null;
    let publishQuill = null;
    let quillLoaded = false;

    function openPublishEditModal(id) {
        if (!id || id <= 0) {
            if (typeof showToast === 'function') showToast('无效的ID', 'error');
            return;
        }
        let container = document.getElementById('publish-edit-modal-container');
        if (!container) {
            container = document.createElement('div');
            container.id = 'publish-edit-modal-container';
            document.body.appendChild(container);
        }
        container.innerHTML = '';
        const modal = document.createElement('div');
        modal.className = 'modal';
        let catOptions = '';
        if (Array.isArray(publishCategories)) {
            publishCategories.forEach(function(c) {
                catOptions += '<option value="' + c.id + '">' + escapeHtml(c.name) + '</option>';
            });
        }
        modal.innerHTML = '<div class="modal-backdrop"></div>' +
        '<div class="modal-content" style="width:1000px;max-width:95%;max-height:none;overflow:hidden;">' +
        '<div class="modal-header"><h3>编辑投稿</h3><button type="button" class="modal-close">&times;</button></div>' +
        '<div class="modal-body" style="overflow:hidden;padding:20px 30px;">' +
        '<div class="form-section">' +
        '<div class="form-group" style="display:flex; align-items:end; gap:10px;">' +
        '<div style="flex:1;"><label for="pub_edit_title">标题</label><input type="text" id="pub_edit_title" class="form-control" required></div>' +
        '<div style="flex:1;position:relative;"><label for="pub_edit_thumbnail">缩略图</label><div style="position:relative;"><input type="text" id="pub_edit_thumbnail" class="form-control" placeholder="图片URL" style="padding-right:40px;"><button type="button" id="pub_thumb_upload" style="position:absolute;right:8px;bottom:6px;width:28px;height:28px;border-radius:50%;border:none;background:transparent;color:var(--text-color);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease;padding:0;" onmouseover="this.style.background=\'var(--primary-color)\';this.style.color=\'#fff\'" onmouseout="this.style.background=\'transparent\';this.style.color=\'var(--text-color)\'"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg></button><input type="file" id="pub_hidden_file" accept="image/*" style="display:none;"></div></div>' +
        '<div style="flex:0 0 120px;"><label for="pub_edit_category">栏目</label><select id="pub_edit_category" class="form-control">' + catOptions + '</select></div>' +
        '</div>' +
        '<div class="form-group" style="display:flex; align-items:end; gap:10px;">' +
        '<div style="flex:1;"><label for="pub_edit_keywords">关键词</label><input type="text" id="pub_edit_keywords" class="form-control"></div>' +
        '<div style="flex:1;"><label for="pub_edit_description">简介</label><input type="text" id="pub_edit_description" class="form-control"></div>' +
        '<div style="flex:0 0 120px;"><button type="button" id="pub_edit_submit" style="width:100%;background:var(--primary-color);color:#fff;border:none;padding:10px 0;font-size:14px;font-weight:500;border-radius:5px;cursor:pointer;transition:opacity .2s ease;height:39px;" onmouseover="this.style.opacity=\'0.9\'" onmouseout="this.style.opacity=\'1\'">立即保存</button></div>' +
        '</div>' +
        '<div class="form-group">' +
        '<label>正文内容（富文本）</label>' +
        '<div style="display:flex;align-items:center;border:1px solid var(--border-color);border-bottom:none;border-radius:6px 6px 0 0;background:#fff;" id="pub_quill_toolbar_wrap">' +
        '<div id="pub_quill_toolbar" style="flex:1;border:none;"></div>' +
        '</div>' +
        '<div id="pub_quill_editor" style="height:220px;border:1px solid var(--border-color);border-radius:0 0 6px 6px;"></div>' +
        '<textarea id="pub_edit_content" style="display:none;"></textarea>' +
        '</div>' +
        '</div>' +
        '</div>' +
        '</div>';
        container.appendChild(modal);
        modal.style.display = 'flex';
        setTimeout(() => {
            modal.classList.add('modal-visible');
        }, 10);

        function initQuillEditor(r) {
            document.getElementById('pub_edit_content').value = r.content || '';
            if (typeof Quill !== 'undefined') {
                publishQuill = new Quill('#pub_quill_editor', {
                    theme: 'snow',
                    placeholder: '请输入正文内容...',
                    modules: {
                        toolbar: [
                            ['bold', 'italic', 'underline'],
                            [{
                                'header': 1
                            }, {
                                'header': 2
                            }],
                            [{
                                'list': 'ordered'
                            }, {
                                'list': 'bullet'
                            }],
                            [{
                                'color': []
                            }, {
                                'background': []
                            }]
                        ]
                    }
                });
                publishQuill.root.innerHTML = r.content || '';
                publishQuill.on('text-change', function() {
                    document.getElementById('pub_edit_content').value = publishQuill.root.innerHTML;
                });
                var qt = document.querySelector('#pub_quill_editor .ql-toolbar');
                var tc = document.getElementById('pub_quill_toolbar');
                if (qt && tc) {
                    tc.appendChild(qt);
                    qt.style.border = 'none';
                    qt.style.display = 'flex';
                    qt.style.justifyContent = 'flex-start';
                }
            }
        }

        fetch('/admin/ajaxx.php?action=get_publish_detail&id=' + id, {
                credentials: 'same-origin'
            })
            .then(function(r) {
                return r.json();
            }).then(function(data) {
                if (!data || !data.success) {
                    if (typeof showToast === 'function') showToast('获取数据失败', 'error');
                    closeModalPublishEdit();
                    return;
                }
                const r = data.data || {};
                document.getElementById('pub_edit_title').value = r.title || '';
                document.getElementById('pub_edit_thumbnail').value = r.thumbnail || '';
                document.getElementById('pub_edit_keywords').value = r.keywords || '';
                document.getElementById('pub_edit_description').value = r.description || '';
                const catSel = document.getElementById('pub_edit_category');
                if (r.category_id) {
                    for (let i = 0; i < catSel.options.length; i++) {
                        if (parseInt(catSel.options[i].value) === parseInt(r.category_id)) {
                            catSel.selectedIndex = i;
                            break;
                        }
                    }
                }

                if (quillLoaded) {
                    initQuillEditor(r);
                    return;
                }
                var cssLink = document.createElement('link');
                cssLink.rel = 'stylesheet';
                cssLink.href = '/assets/quill/quill.snow.css';
                cssLink.onload = function() {
                    var jsScript = document.createElement('script');
                    jsScript.src = '/assets/quill/quill.min.js';
                    jsScript.onload = function() {
                        quillLoaded = true;
                        initQuillEditor(r);
                    };
                    document.head.appendChild(jsScript);
                };
                document.head.appendChild(cssLink);
            }).catch(function() {
                if (typeof showToast === 'function') showToast('请求失败', 'error');
                closeModalPublishEdit();
            });

        function closeModalPublishEdit() {
            modal.classList.remove('modal-visible');
            setTimeout(() => {
                container.innerHTML = '';
            }, 300);
            publishQuill = null;
        }
        modal.querySelectorAll('.modal-close,.modal-close-btn').forEach(function(btn) {
            btn.addEventListener('click', closeModalPublishEdit);
        });
        modal.querySelector('.modal-backdrop').addEventListener('click', closeModalPublishEdit);
        document.addEventListener('keydown', function escHandler(e) {
            if (e.key === 'Escape') {
                closeModalPublishEdit();
                document.removeEventListener('keydown', escHandler);
            }
        });

        const uploadBtn = document.getElementById('pub_thumb_upload');
        const hiddenInput = document.getElementById('pub_hidden_file');
        const thumbInput = document.getElementById('pub_edit_thumbnail');
        if (uploadBtn && hiddenInput) {
            uploadBtn.addEventListener('click', function() {
                hiddenInput.click();
            });
            hiddenInput.addEventListener('change', function() {
                const file = this.files[0];
                if (!file) return;
                if (!file.type.match(/^image\/(jpeg|png|gif|webp)$/i)) {
                    if (typeof showToast === 'function') showToast('只支持JPG/PNG/GIF/WebP', 'error');
                    this.value = '';
                    return;
                }
                if (file.size > 2 * 1024 * 1024) {
                    if (typeof showToast === 'function') showToast('图片不能超过2MB', 'error');
                    this.value = '';
                    return;
                }
                const fd = new FormData();
                fd.append('upload_category_thumbnail', '1');
                fd.append('thumbnail', file);
                uploadBtn.disabled = true;
                uploadBtn.textContent = '上传中...';
                fetch('/admin/ajaxx.php', {
                        method: 'POST',
                        body: fd,
                        credentials: 'same-origin',
                        headers: {
                            'X-Requested-With': 'XMLHttpRequest'
                        }
                    })
                    .then(r => r.json()).then(function(d) {
                        uploadBtn.disabled = false;
                        uploadBtn.textContent = '上传';
                        if (d && d.success && d.data && d.data.thumbnail_url) {
                            thumbInput.value = d.data.thumbnail_url;
                            if (typeof showToast === 'function') showToast('上传成功', 'success');
                        } else {
                            if (typeof showToast === 'function') showToast(d && (d.message || d.error) ? (d.message || d.error) : '上传失败', 'error');
                        }
                        hiddenInput.value = '';
                    }).catch(function() {
                        uploadBtn.disabled = false;
                        uploadBtn.textContent = '上传';
                        if (typeof showToast === 'function') showToast('请求失败', 'error');
                        hiddenInput.value = '';
                    });
            });
        }

        document.getElementById('pub_edit_submit').addEventListener('click', function() {
            const title = document.getElementById('pub_edit_title').value.trim();
            if (!title) {
                if (typeof showToast === 'function') showToast('标题不能为空', 'error');
                return;
            }
            const fd = new FormData();
            fd.append('action', 'edit_publish');
            fd.append('publish_id', String(id));
            fd.append('publish_title', title);
            fd.append('publish_keywords', document.getElementById('pub_edit_keywords').value.trim());
            fd.append('publish_description', document.getElementById('pub_edit_description').value.trim());
            fd.append('publish_content', document.getElementById('pub_edit_content').value);
            fd.append('publish_thumbnail', document.getElementById('pub_edit_thumbnail').value.trim());
            fd.append('publish_category_id', document.getElementById('pub_edit_category').value);
            const submitBtn = this;
            submitBtn.disabled = true;
            submitBtn.textContent = '保存中...';
            fetch('/admin/ajaxx.php', {
                    method: 'POST',
                    body: fd,
                    credentials: 'same-origin',
                    headers: {
                        'X-Requested-With': 'XMLHttpRequest'
                    }
                })
                .then(r => r.json()).then(function(d) {
                    submitBtn.disabled = false;
                    submitBtn.textContent = '保存';
                    if (handlePublishAjaxResult(d, '投稿更新成功', function() {
                        closeModalPublishEdit();
                        if (typeof HeaderPagination !== 'undefined' && typeof HeaderPagination.load === 'function') HeaderPagination.load();
                        else location.reload();
                    })) return;
                }).catch(function() {
                    submitBtn.disabled = false;
                    submitBtn.textContent = '保存';
                    if (typeof showToast === 'function') showToast('请求失败', 'error');
                });
        });
    }

    document.addEventListener('click', function(e) {
        const deleteLink = e.target.closest('.publish-manage a.btn.btn-sm.btn-danger');
        if (!deleteLink) return;
        if (!window.isDemoAdminPublishPage) return;
        e.preventDefault();
        if (typeof showToast === 'function') showToast('演示账号无权限操作', 'error', 1500);
    });
</script>
