<?php
session_start();
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Pragma: no-cache");
header("Expires: Thu, 01 Jan 1970 00:00:00 GMT");

require_once 'auth.php';

$expire = 1800;
if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) {
    session_destroy();
    header("Location: login.php");
    exit;
}
$_SESSION['login_time'] = time();
$userName = htmlspecialchars($_SESSION['username']);
$userRole = $_SESSION['role'];
$roleText = $userRole === 'admin' ? '管理员' : '超级管理员';

$dbHost = "10.150.117.190";
$dbUser = "root";
$dbPwd = "hp93000";
$dbName = "alert_mail_stat";
$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName);
mysqli_set_charset($connConfig, "utf8mb4");
$configSql = "SELECT k,v FROM sys_config";
$configRes = mysqli_query($connConfig, $configSql);
$sysConfig = [];
while ($row = mysqli_fetch_assoc($configRes)) {
    $sysConfig[$row['k']] = $row['v'];
}
mysqli_close($connConfig);

$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统");
$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff");
$pageSize = $sysConfig['page_size'] ?? "20";
$footerText = htmlspecialchars($sysConfig['footer_text'] ?? "");
$sidebarRawLinks = $sysConfig['sidebar_links'] ?? "";
$currentLang = $sysConfig['lang'] ?? "zh";

$langMap = [
    'zh' => [
        'html_lang' => 'zh-CN',
        'page_subtitle' => '爱德万测试 · 运维告警监控平台',
        'monitor_panel' => '监控面板',
        'alert_overview' => '告警监控总览',
        'alert_list_page' => '历史告警查询',
        'work_order_mgr' => '工单系统',
        'docker_mgr' => 'Docker容器管理',
        'system_manager' => '角色管理',
        'quick_link' => '快捷外链',
        'system_manage' => '系统管理',
        'system_config' => '后台配置管理',
        'current_user' => '当前用户：',
        'sys_time' => '系统时间：',
        'refresh_all' => '刷新全部数据',
        'logout' => '退出登录',
        'lang_text' => '语言：',
        'container_list' => '容器列表',
        'image_list' => '镜像列表',
        'container_log' => '容器日志',
        'network_info' => '网络详情',
        'exec_container' => '进入容器执行命令',
        'restart' => '重启',
        'stop' => '停止',
        'remove' => '强制删除',
        'remove_image' => '删除镜像',
        'bind_repo' => '绑定镜像仓库',
        'input_cmd' => '仅允许 ls/pwd/cat/ps/df/free/top/du/whoami/env，禁止rm/wget/curl/chmod等高危指令',
        'execute' => '执行',
        'close' => '关闭',
        'loading' => '加载中...',
        'no_container' => '暂无容器',
        'no_image' => '无本地镜像',
        'request_fail' => '接口请求失败',
        'container_id' => '容器ID',
        'container_name' => '容器名称',
        'image_name' => '镜像',
        'status' => '运行状态',
        'port_mapping' => '端口映射',
        'operate' => '操作',
        'repo' => '镜像仓库',
        'tag' => '镜像标签',
        'image_id' => '镜像ID',
        'size' => '镜像大小',
        'create_time' => '创建时间',
        'confirm_remove' => '确认强制删除容器？操作不可恢复！',
        'confirm_remove_img' => '确认删除本地镜像？不可恢复！',
        'op_success' => '操作成功，已刷新状态',
        'op_failed' => '操作执行失败',
        'loading_mask' => '数据加载中，请稍候...',
        'create_container' => '新建容器',
        'batch_restart' => '批量重启',
        'batch_stop' => '批量停止',
        'batch_remove' => '批量删除',
        'search_placeholder' => '搜索容器名称/镜像',
        'op_menu' => '操作 ▼',
        'view_log' => '查看日志',
        'view_network' => '查看网络',
        'enter_exec' => '交互式终端',
        'stat_total' => '容器总数',
        'stat_running' => '运行中',
        'stat_stopped' => '已停止',
        'stat_image' => '本地镜像',
        'tip_exec_once' => '单次命令执行',
        'tip_websocket' => '实时交互式TTY终端，支持输入、复制、窗口自适应',
        'repo_addr' => '仓库地址',
        'repo_user' => '仓库账号',
        'repo_pwd' => '仓库密码',
        'repo_name' => '仓库名称',
        'bind_repo_title' => '绑定私有镜像仓库'
    ],
    'en' => [
        'html_lang' => 'en',
        'page_subtitle' => 'Advantest · O&M Alert Monitor Platform',
        'monitor_panel' => 'Monitor Panel',
        'alert_overview' => 'Alert Overview',
        'alert_list_page' => 'Alert Pagination List',
        'work_order_mgr' => 'Work Order System',
        'docker_mgr' => 'Docker Manager',
        'system_manager' => 'Role & Permission Manage',
        'quick_link' => 'Quick Links',
        'system_manage' => 'System Manage',
        'system_config' => 'System Config',
        'current_user' => 'User: ',
        'sys_time' => 'System Time: ',
        'refresh_all' => 'Refresh All Data',
        'logout' => 'Logout',
        'lang_text' => 'Lang: ',
        'container_list' => 'Container List',
        'image_list' => 'Image List',
        'container_log' => 'Container Logs',
        'network_info' => 'Network Info',
        'exec_container' => 'Exec Container Command',
        'restart' => 'Restart',
        'stop' => 'Stop',
        'remove' => 'Force Remove',
        'remove_image' => 'Remove Image',
        'bind_repo' => 'Bind Registry',
        'input_cmd' => 'Only allow ls/pwd/cat/ps/df/free/top/du/whoami/env, ban rm/wget/curl/chmod',
        'execute' => 'Run',
        'close' => 'Close',
        'loading' => 'Loading...',
        'no_container' => 'No Containers',
        'no_image' => 'No Local Images',
        'request_fail' => 'API Request Failed',
        'container_id' => 'Container ID',
        'container_name' => 'Name',
        'image_name' => 'Image',
        'status' => 'Status',
        'port_mapping' => 'Ports',
        'operate' => 'Operate',
        'repo' => 'Repository',
        'tag' => 'Tag',
        'image_id' => 'Image ID',
        'size' => 'Size',
        'create_time' => 'Created At',
        'confirm_remove' => 'Confirm force delete container? Irreversible!',
        'confirm_remove_img' => 'Confirm delete local image? Irreversible!',
        'op_success' => 'Operation succeeded, refreshed status',
        'op_failed' => 'Operation failed',
        'loading_mask' => 'Loading data, please wait...',
        'create_container' => 'Create Container',
        'batch_restart' => 'Batch Restart',
        'batch_stop' => 'Batch Stop',
        'batch_remove' => 'Batch Remove',
        'search_placeholder' => 'Search container / image',
        'op_menu' => 'Operate ▼',
        'view_log' => 'Logs',
        'view_network' => 'Network',
        'enter_exec' => 'Interactive Terminal',
        'stat_total' => 'Total Containers',
        'stat_running' => 'Running',
        'stat_stopped' => 'Stopped',
        'stat_image' => 'Local Images',
        'tip_exec_once' => 'Single command execution',
        'tip_websocket' => 'Real-time interactive TTY terminal, input & resize support',
        'repo_addr' => 'Registry Address',
        'repo_user' => 'Username',
        'repo_pwd' => 'Password',
        'repo_name' => 'Registry Name',
        'bind_repo_title' => 'Bind Private Registry'
    ]
];
$t = $langMap[$currentLang];

$sidebarLinkList = [];
if (!empty($sidebarRawLinks)) {
    $lines = explode("\n", $sidebarRawLinks);
    foreach ($lines as $line) {
        $line = trim($line);
        if (empty($line)) continue;
        $item = explode("|", $line, 2);
        if (count($item) === 2) {
            $sidebarLinkList[] = [
                "name" => trim($item[0]),
                "url" => trim($item[1])
            ];
        }
    }
}
$pageSid = session_id();

// WebSocket HMAC 签名参数（和docker_api.py密钥完全一致）
$WS_SECRET = "DockerAdminPlatform2026SecretKey123456789";
$wsUser = $_SESSION['user_id'];
$wsRole = $_SESSION['role'];
$wsTs = time();
$wsRawSign = $wsUser . "|" . $wsRole . "|" . $wsTs;
$wsSign = hash_hmac("sha256", $wsRawSign, $WS_SECRET);
$wsClientIp = $_SERVER['REMOTE_ADDR'];
?>
<!DOCTYPE html>
<html lang="<?php echo $t['html_lang']; ?>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo $pageTitle; ?> - Advantest <?php echo $t['page_subtitle']; ?></title>
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
<link rel="stylesheet" href="/static/css/xterm.css">
<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/socket.io.min.js"></script>
<script src="/static/js/xterm.min.js"></script>
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{
    background:#f9fafc;
    font-family:"Inter","PingFang SC","Microsoft YaHei";
    color:#1d2939;
    line-height:1.6;
    display:flex;
    flex-direction:column;
    height:100vh;
    overflow:hidden;
}
.wrap-main{
    display:flex;
    flex:1;
    overflow:hidden;
}
.sidebar{
    width:240px;
    background:#1e293b;
    color:#e2e8f0;
    flex-shrink:0;
    overflow-y:auto;
}
.sidebar-brand{
    padding:26px 24px;
    border-bottom:1px solid rgba(255,255,255,0.1);
}
.sidebar-brand-en{
    font-size:20px;
    font-weight:700;
    letter-spacing:1px;
    color:#fff;
}
.sidebar-brand-cn{
    font-size:13px;
    color:#a5b4fc;
    margin-top:4px;
}
.sidebar-menu{
    padding:16px 0;
}
.menu-title{
    padding:10px 24px;
    font-size:12px;
    color:#94a3b8;
    letter-spacing:1px;
}
.menu-item{
    display:flex;
    align-items:center;
    gap:12px;
    padding:14px 24px;
    cursor:pointer;
    font-size:14px;
    transition:0.2s;
    color:#cbd5e1;
}
.menu-item i{
    font-size:16px;
    width:20px;
    text-align:center;
}
.menu-item.active{
    background:rgba(255,255,255,0.12);
    color:#fff;
    border-left:4px solid #3b82f6;
}
.menu-item:hover:not(.active){
    background:rgba(255,255,255,0.06);
    color:#fff;
}
.main-content{
    flex:1;
    overflow-y:auto;
    display:flex;
    flex-direction:column;
}
.header{
    height:64px;
    padding:0 40px;
    background:#ffffff;
    border-bottom:1px solid #eef2fb;
    color:#152c5b;
    display:flex;
    justify-content:space-between;
    align-items:center;
    box-shadow:0 2px 12px rgba(21,44,91,0.05);
    flex-shrink:0;
}
.header-left{
    display:flex;
    align-items:center;
    gap:14px;
}
.header-brand-en{
    font-size:24px;
    font-weight:700;
    letter-spacing:2px;
    color:#152c5b;
}
.header-brand-cn{
    font-size:15px;
    color:#64748b;
}
.header-right{
    display:flex;
    align-items:center;
    gap:18px;
    font-size:14px;
    flex-wrap:wrap;
}
.user-info,.time-info,.lang-box{
    color:#475569;
    display:flex;
    align-items:center;
    gap:6px;
}
.lang-box select{
    padding:4px 8px;
    border:1px solid #cbd5e1;
    border-radius:6px;
}
.btn-base{
    border:none;
    padding:9px 20px;
    border-radius:8px;
    cursor:pointer;
    font-size:14px;
    display:flex;
    align-items:center;
    gap:6px;
    transition:all 0.2s ease;
}
.btn-outline{
    background:#ffffff;
    color:#152c5b;
    border:1px solid #cbd5e1;
}
.btn-outline:hover{
    background:#f7f8fc;
    border-color:#152c5b;
}
.btn-primary{
    background:#152c5b;
    color:#fff;
}
.btn-primary:hover{
    background:#0f1e42;
}
.btn-danger{
    background:#dc2626;
    color:#fff;
}
.btn-danger:hover{
    background:#b91c1c;
}
.btn-base:disabled{
    opacity:0.6;
    cursor:not-allowed;
}
.container{
    padding:36px 40px;
    max-width:100%;
    flex:1;
}
.base-card{
    background:#fff;
    border-radius:16px;
    padding:32px;
    box-shadow:0 3px 18px rgba(21,44,91,0.06);
    border:1px solid #eef2fb;
    margin-bottom:36px;
}
.title-wrap{
    display:flex;
    justify-content:space-between;
    align-items:center;
    margin-bottom:26px;
    padding-bottom:16px;
    border-bottom:1px solid #eef2fb;
}
.title-left{
    display:flex;
    align-items:center;
    gap:12px;
    font-size:19px;
    font-weight:600;
    color:#152c5b;
}
.title-left i{color:#2563eb;font-size:21px}
.tab-bar{
    display:flex;
    border-bottom:1px solid #eef2fb;
    margin-bottom:24px;
}
.tab-item{
    padding:14px 24px;
    cursor:pointer;
    font-size:15px;
    color:#64748b;
}
.tab-item.active{
    border-bottom:2px solid #3b82f6;
    color:#152c5b;
    font-weight:500;
}
.tab-panel{display:none;}
.tab-panel.active{display:block;}
.stat-row{
    display:grid;
    grid-template-columns: repeat(4,1fr);
    gap:20px;
    margin-bottom:24px;
}
.stat-card{
    background:#fff;
    padding:20px;
    border-radius:12px;
    box-shadow:0 2px 12px rgba(21,44,91,0.05);
    border:1px solid #eef2fb;
}
.stat-label{
    font-size:14px;
    color:#64748b;
    margin-bottom:8px;
}
.stat-num{
    font-size:26px;
    font-weight:700;
    color:#152c5b;
}
.tool-bar{
    display:flex;
    justify-content:space-between;
    align-items:center;
    margin-bottom:16px;
}
.search-input{
    width:320px;
    height:40px;
    padding:0 14px;
    border:1px solid #cbd5e1;
    border-radius:8px;
    font-size:14px;
}
.batch-group{
    display:flex;
    gap:10px;
}
.table-wrap{overflow-x:auto}
table{width:100%;border-collapse:collapse;font-size:14px}
th{
    background:#f9fafc;
    color:#475569;
    font-weight:600;
    padding:16px 18px;
    text-align:left;
    border-bottom:2px solid #e2e8f0;
    white-space:nowrap;
}
td{
    padding:18px;
    border-bottom:1px solid #f1f5f9;
    color:#334155;
}
tbody tr{transition:background 0.2s}
tbody tr:hover{background:#f7f8fc}
tbody tr:nth-child(even){background:#fbfcfe}
.container-name{font-weight:600;color:#152c5b;}
.tag-success{
    background:#dcfce7;
    color:#15803d;
    padding:4px 10px;
    border-radius:6px;
    font-size:13px;
}
.tag-danger{
    background:#fee2e2;
    color:#b91c1c;
    padding:4px 10px;
    border-radius:6px;
    font-size:13px;
}
.tag-gray{
    background:#f3f4f6;
    color:#4b5563;
    padding:4px 10px;
    border-radius:6px;
    font-size:13px;
}
.op-dropdown{
    position:relative;
    display:inline-block;
}
.op-dropdown-menu{
    position:absolute;
    top:100%;
    left:0;
    background:#fff;
    border:1px solid #eef2fb;
    border-radius:8px;
    box-shadow:0 4px 16px rgba(21,44,91,0.1);
    z-index:99;
    min-width:130px;
    display:none;
}
.op-dropdown-item{
    padding:10px 16px;
    cursor:pointer;
    font-size:14px;
}
.op-dropdown-item:hover{background:#f7f8fc;}
.empty-state{
    text-align:center;
    padding:80px 20px;
    color:#94a3b8;
    font-size:15px;
}
.empty-icon{
    font-size:56px;
    margin-bottom:18px;
    opacity:0.35;
}
.modal-mask{
    position:fixed;
    left:0;top:0;
    width:100%;height:100%;
    background:rgba(0,0,0,0.55);
    display:none;
    z-index:999;
    align-items:center;
    justify-content:center;
}
.modal-box{
    width:88%;
    max-width:1200px;
    min-width:720px;
    background:#fff;
    border-radius:16px;
    overflow:hidden;
    border:1px solid #eef2fb;
    box-shadow:0 10px 40px rgba(21,44,91,0.15);
    display:flex;
    flex-direction:column;
}
.modal-head{
    height:56px;
    line-height:56px;
    padding:0 24px;
    border-bottom:1px solid #eef2fb;
    display:flex;
    justify-content:space-between;
    align-items:center;
    font-size:16px;
    font-weight:600;
    color:#152c5b;
    flex-shrink:0;
}
.modal-close{
    cursor:pointer;
    font-size:20px;
    color:#94a3b8;
}
.modal-body{
    padding:0;
    height:62vh;
    overflow:auto;
    background:#111827;
    color:#e5e7eb;
    white-space:pre-wrap;
    word-break:break-all;
    font-family:Consolas,Monaco,monospace;
    font-size:13px;
}
.modal-footer{
    padding:16px 24px;
    border-top:1px solid #eef2fb;
    display:flex;
    gap:12px;
    align-items:center;
    flex-shrink:0;
}
.cmd-input{
    flex:1;
    height:40px;
    padding:0 14px;
    border:1px solid #cbd5e1;
    border-radius:8px;
    font-size:14px;
}
.global-loading{
    position:fixed;
    inset:0;
    background:rgba(255,255,255,0.7);
    z-index:9999;
    display:none;
    align-items:center;
    justify-content:center;
    flex-direction:column;
    gap:16px;
}
.global-loading i{
    font-size:42px;
    color:#2563eb;
}
.sid-tip{
    padding:10px 40px;
    color:#64748b;
    font-size:13px;
}
#createModal .modal-body{
    background:#fff;
    color:#1d2939;
    height:auto;
    max-height:70vh;
    padding:24px;
}
#repoModal .modal-body{
    background:#fff;
    color:#1d2939;
    height:auto;
    max-height:70vh;
    padding:24px;
}
.form-item{
    margin-bottom:16px;
}
.form-item label{
    display:block;
    margin-bottom:6px;
    font-weight:500;
}
.form-input{
    width:100%;
    height:40px;
    padding:0 14px;
    border:1px solid #cbd5e1;
    border-radius:8px;
    font-size:14px;
}
@media (max-width:992px){
    .wrap-main{flex-direction:column;}
    .sidebar{width:100%;height:auto}
    .header{padding:0 24px;flex-direction:column;gap:16px;height:auto}
    .container{padding:24px}
    .base-card{padding:24px}
    .modal-box{width:96%;min-width:auto;}
    .stat-row{grid-template-columns: repeat(2,1fr);}
    .tool-bar{flex-direction:column;gap:12px;align-items:flex-start;}
}
</style>
</head>
<body>
<div class="global-loading" id="globalLoading">
    <i class="fa fa-spinner fa-spin"></i>
    <span><?php echo $t['loading_mask']; ?></span>
</div>

<div class="wrap-main">
    <div class="sidebar">
        <div class="sidebar-brand">
            <div class="sidebar-brand-en">Advantest</div>
            <div class="sidebar-brand-cn"><?php echo $t['page_subtitle']; ?></div>
        </div>
        <div class="sidebar-menu">
            <div class="menu-title"><?php echo $t['monitor_panel']; ?></div>
            <div class="menu-item" onclick="location.href='dashboard.php'">
                <i class="fa fa-line-chart"></i>
                <span><?php echo $t['alert_overview']; ?></span>
            </div>
            <div class="menu-item" onclick="location.href='alert_list.php'">
                <i class="fa fa-list"></i>
                <span><?php echo $t['alert_list_page']; ?></span>
            </div>
            <div class="menu-item" onclick="location.href='work_order.php'">
                <i class="fa fa-ticket"></i>
                <span><?php echo $t['work_order_mgr']; ?></span>
            </div>
            <div class="menu-item active" onclick="location.href='docker_mgr.php'">
                <i class="fa fa-cubes"></i>
                <span><?php echo $t['docker_mgr']; ?></span>
            </div>
            <?php if (!empty($sidebarLinkList)): ?>
            <div class="menu-title"><?php echo $t['quick_link']; ?></div>
            <?php foreach ($sidebarLinkList as $link): ?>
            <div class="menu-item" onclick="window.open('<?php echo htmlspecialchars($link['url']); ?>')">
                <i class="fa fa-external-link"></i>
                <span><?php echo htmlspecialchars($link['name']); ?></span>
            </div>
            <?php endforeach; ?>
            <?php endif; ?>
            <div class="menu-title"><?php echo $t['system_manage']; ?></div>
            <div class="menu-item" onclick="location.href='system_manage.php'">
                <i class="fa fa-users"></i>
                <span><?php echo $t['system_manager']; ?></span>
            </div>
            <div class="menu-item" onclick="location.href='admin.php'">
                <i class="fa fa-cog"></i>
                <span><?php echo $t['system_config']; ?></span>
            </div>
        </div>
    </div>

    <div class="main-content">
        <div class="header">
            <div class="header-left">
                <div>
                    <div class="header-brand-en">Advantest</div>
                    <div class="header-brand-cn"><?php echo $t['page_subtitle']; ?></div>
                </div>
            </div>
            <div class="header-right">
                <span class="user-info"><i class="fa fa-user-circle"></i><?php echo $t['current_user']; ?><?php echo $userName; ?>（<?php echo $roleRealName; ?>）</span>
                <span class="time-info"><i class="fa fa-clock-o"></i><?php echo $t['sys_time']; ?><span id="updateTime">--</span></span>
                <div class="lang-box">
                    <span><?php echo $t['lang_text']; ?></span>
                    <select id="langSwitch">
                        <option value="zh" <?php echo $currentLang==='zh'?'selected':''; ?>>中文</option>
                        <option value="en" <?php echo $currentLang==='en'?'selected':''; ?>>EN</option>
                    </select>
                </div>
                <button class="btn-base btn-outline" id="refreshAll"><i class="fa fa-refresh"></i><?php echo $t['refresh_all']; ?></button>
                <button class="btn-base btn-primary" id="logoutBtn"><i class="fa fa-sign-out"></i><?php echo $t['logout']; ?></button>
            </div>
        </div>

        <div class="sid-tip">
            当前页面SID：<?php echo $pageSid; ?> &nbsp;|&nbsp; 接口SID：<?php echo $pageSid; ?>（SID一致，会话互通）
        </div>

        <div class="container">
            <div class="base-card">
                <div class="title-wrap">
                    <div class="title-left"><i class="fa fa-cubes"></i><?php echo $t['docker_mgr']; ?></div>
                    <div style="display:flex;gap:12px;">
                        <button class="btn-base btn-outline" onclick="openRepoModal()"><i class="fa fa-database"></i><?php echo $t['bind_repo']; ?></button>
                        <button class="btn-base btn-primary" onclick="openCreateModal()"><i class="fa fa-plus"></i><?php echo $t['create_container']; ?></button>
                    </div>
                </div>

                <div class="stat-row">
                    <div class="stat-card">
                        <div class="stat-label"><?php echo $t['stat_total']; ?></div>
                        <div class="stat-num" id="statTotal">0</div>
                    </div>
                    <div class="stat-card">
                        <div class="stat-label"><?php echo $t['stat_running']; ?></div>
                        <div class="stat-num" id="statRunning">0</div>
                    </div>
                    <div class="stat-card">
                        <div class="stat-label"><?php echo $t['stat_stopped']; ?></div>
                        <div class="stat-num" id="statStopped">0</div>
                    </div>
                    <div class="stat-card">
                        <div class="stat-label"><?php echo $t['stat_image']; ?></div>
                        <div class="stat-num" id="statImage">0</div>
                    </div>
                </div>

                <div class="tab-bar">
                    <div class="tab-item active" data-tab="container"><?php echo $t['container_list']; ?></div>
                    <div class="tab-item" data-tab="image"><?php echo $t['image_list']; ?></div>
                </div>

                <div class="tab-panel active" id="panel-container">
                    <div class="tool-bar">
                        <input class="search-input" id="searchContainer" placeholder="<?php echo $t['search_placeholder']; ?>">
                        <div class="batch-group">
                            <button class="btn-base btn-outline" onclick="batchOp('restart')"><?php echo $t['batch_restart']; ?></button>
                            <button class="btn-base btn-outline" onclick="batchOp('stop')"><?php echo $t['batch_stop']; ?></button>
                            <button class="btn-base btn-danger" onclick="batchOp('rm')"><?php echo $t['batch_remove']; ?></button>
                        </div>
                    </div>
                    <div class="table-wrap">
                        <table>
                            <thead>
                                <tr>
                                    <th><input type="checkbox" id="checkAll"></th>
                                    <th><?php echo $t['container_id']; ?></th>
                                    <th><?php echo $t['container_name']; ?></th>
                                    <th><?php echo $t['image_name']; ?></th>
                                    <th><?php echo $t['status']; ?></th>
                                    <th><?php echo $t['port_mapping']; ?></th>
                                    <th><?php echo $t['operate']; ?></th>
                                </tr>
                            </thead>
                            <tbody id="dockerTable">
                                <tr>
                                    <td colspan="7">
                                        <div class="empty-state">
                                            <div class="empty-icon"><i class="fa fa-spinner fa-spin"></i></div>
                                            <div><?php echo $t['loading']; ?></div>
                                        </div>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>

                <div class="tab-panel" id="panel-image">
                    <div class="table-wrap">
                        <table>
                            <thead>
                                <tr>
                                    <th><?php echo $t['repo']; ?></th>
                                    <th><?php echo $t['tag']; ?></th>
                                    <th><?php echo $t['image_id']; ?></th>
                                    <th><?php echo $t['size']; ?></th>
                                    <th><?php echo $t['create_time']; ?></th>
                                    <th><?php echo $t['operate']; ?></th>
                                </tr>
                            </thead>
                            <tbody id="imageTable">
                                <tr>
                                    <td colspan="6">
                                        <div class="empty-state">
                                            <div class="empty-icon"><i class="fa fa-spinner fa-spin"></i></div>
                                            <div><?php echo $t['loading']; ?></div>
                                        </div>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<div class="modal-mask" id="modal">
    <div class="modal-box">
        <div class="modal-head">
            <span id="modalTitle">Info</span>
            <span class="modal-close" onclick="closeModal()">×</span>
        </div>
        <div class="modal-body" id="modalBody"></div>
        <div class="modal-footer">
            <div style="color:#2563eb;font-size:13px;margin-right:12px;" id="execTip"><?php echo $t['tip_websocket']; ?></div>
            <input class="cmd-input" id="cmdInput" placeholder="<?php echo $t['input_cmd']; ?>">
            <button class="btn-base btn-primary" onclick="runExec()" id="singleExecBtn"><?php echo $t['execute']; ?></button>
            <button class="btn-base btn-outline" onclick="closeModal()"><?php echo $t['close']; ?></button>
        </div>
    </div>
</div>

<div class="modal-mask" id="createModal">
    <div class="modal-box" style="max-width:760px;">
        <div class="modal-head">
            <span><?php echo $t['create_container']; ?></span>
            <span class="modal-close" onclick="closeCreateModal()">×</span>
        </div>
        <div class="modal-body">
            <div class="form-item">
                <label>容器名称（留空自动生成）</label>
                <input class="form-input" id="createName">
            </div>
            <div class="form-item">
                <label>镜像（必填，例 nginx:stable）</label>
                <input class="form-input" id="createImage">
            </div>
            <div class="form-item">
                <label>启动命令（可选，覆盖镜像默认CMD）</label>
                <input class="form-input" id="createCmd">
            </div>
            <div class="form-item">
                <label>端口映射 格式 主机端口:容器端口，多个逗号分隔（例 8080:80）</label>
                <input class="form-input" id="createPort">
            </div>
            <div class="form-item">
                <label>CPU核心数（默认1）</label>
                <input class="form-input" id="createCpu" value="1" type="number" min="1">
            </div>
            <div class="form-item">
                <label>内存限制（默认512m，例 1g/2g）</label>
                <input class="form-input" id="createMem" value="512m">
            </div>
        </div>
        <div class="modal-footer">
            <button class="btn-base btn-primary" onclick="submitCreate()"><?php echo $t['execute']; ?></button>
            <button class="btn-base btn-outline" onclick="closeCreateModal()"><?php echo $t['close']; ?></button>
        </div>
    </div>
</div>

<div class="modal-mask" id="repoModal">
    <div class="modal-box" style="max-width:760px;">
        <div class="modal-head">
            <span><?php echo $t['bind_repo_title']; ?></span>
            <span class="modal-close" onclick="closeRepoModal()">×</span>
        </div>
        <div class="modal-body">
            <div class="form-item">
                <label><?php echo $t['repo_name']; ?></label>
                <input class="form-input" id="repoName">
            </div>
            <div class="form-item">
                <label><?php echo $t['repo_addr']; ?></label>
                <input class="form-input" id="repoAddr" placeholder="harbor.example.com">
            </div>
            <div class="form-item">
                <label><?php echo $t['repo_user']; ?></label>
                <input class="form-input" id="repoUser">
            </div>
            <div class="form-item">
                <label><?php echo $t['repo_pwd']; ?></label>
                <input class="form-input" id="repoPwd" type="password">
            </div>
        </div>
        <div class="modal-footer">
            <button class="btn-base btn-primary" onclick="submitBindRepo()"><?php echo $t['execute']; ?></button>
            <button class="btn-base btn-outline" onclick="closeRepoModal()"><?php echo $t['close']; ?></button>
        </div>
    </div>
</div>

<script>
let socket = null;
let term = null;
const SOCKET_URL = "http://10.150.117.190:8090";
const WS_AUTH = {
    user: "<?=$wsUser?>",
    role: "<?=$wsRole?>",
    ts: "<?=$wsTs?>",
    sign: "<?=$wsSign?>",
    clientIp: "<?=$wsClientIp?>"
};

function initSocket(){
    socket = io(SOCKET_URL, {
        auth: WS_AUTH,
        transports: ['websocket']
    });
    socket.on("connect", function(){
        console.log("WebSocket连接成功");
    });
    socket.on("connect_error", function(err){
        console.error("WebSocket连接失败", err);
    });
    socket.on("terminal_output", function(res){
        if(term) term.write(res.data);
    });
    socket.on("disconnect", ()=>{
        if(term) term.write("\n\n🔌 终端连接已断开\n");
    });
}

function closeTerminalSession(){
    if(socket){
        socket.emit("terminal_close");
    }
    if(term){
        term.dispose();
        term = null;
    }
}

let currentFullId = '';
let opLock = false;
let refreshTimer = null;
let selectedContainers = [];
const BAN_CMD = ["rm","wget","curl","scp","chmod","chown","shutdown","systemctl","yum","apt","docker","nc"];

function showLoading(){ $("#globalLoading").css("display","flex"); }
function hideLoading(){ $("#globalLoading").hide(); }

function updateTime() {
    const now = new Date();
    const Y = now.getFullYear();
    const M = String(now.getMonth() + 1).padStart(2, '0');
    const D = String(now.getDate()).padStart(2, '0');
    const h = String(now.getHours()).padStart(2, '0');
    const m = String(now.getMinutes()).padStart(2, '0');
    const s = String(now.getSeconds()).padStart(2, '0');
    $("#updateTime").text(`${Y}-${M}-${D} ${h}:${m}:${s}`);
}

$("#langSwitch").change(function(){
    const newLang = $(this).val();
    $.post("./api/index.php",{act:"save_lang",lang:newLang},()=>{
        location.href = "docker_mgr.php?_t="+new Date().getTime();
    });
});

$(".tab-item").click(function(){
    let tab = $(this).data("tab");
    $(".tab-item").removeClass("active");
    $(this).addClass("active");
    $(".tab-panel").removeClass("active");
    $("#panel-"+tab).addClass("active");
    if(tab === "container") loadDockerList();
    if(tab === "image") loadImageList();
});

$("#refreshAll").click(function(){
    loadDockerList();
    loadImageList();
});

function renderStatusTag(status){
    let cls = "tag-gray";
    let text = status;
    switch(status){
        case "running":
            cls = "tag-success";
            text = "Running";
            break;
        case "exited":
            cls = "tag-danger";
            text = "Stopped";
            break;
    }
    return `<span class="${cls}">${text}</span>`;
}

function loadDockerList(){
    showLoading();
    $.ajax({
        url: "./api/docker.php?act=list",
        type:"GET",
        xhrFields: {withCredentials:true},
        dataType:"json",
        success:function(res){
            hideLoading();
            let html = "";
            let total = 0;
            let running = 0;
            let stopped = 0;
            if(typeof res !== "object" || res.code === undefined){
                html = `<tr><td colspan="7" class="empty-state" style="color:#dc2626">接口返回数据格式错误</td></tr>`;
            }else if(res.code !== 0){
                html = `<tr><td colspan="7" class="empty-state" style="color:#dc2626">${res.msg}</td></tr>`;
            }else if(!res.list || res.list.length === 0){
                html = `<tr><td colspan="7" class="empty-state"><div class="empty-icon"><i class="fa fa-folder-open-o"></i></div><div><?php echo $t['no_container']; ?></div></td></tr>`;
            }else{
                total = res.list.length;
                res.list.forEach(item=>{
                    try{
                        if(item.status === "running") running++;
                        else if(item.status === "exited") stopped++;
                        let portText = item.ports || "-";
                        let statusHtml = renderStatusTag(item.status);
                        html += `<tr data-name="${item.name}" data-image="${item.image}">
                            <td><input type="checkbox" class="container-check" data-cid="${item.full_id}"></td>
                            <td title="点击复制完整ID" onclick="copyId('${item.full_id}')">${item.id}</td>
                            <td class="container-name">${item.name}</td>
                            <td>${item.image}</td>
                            <td>${statusHtml}</td>
                            <td>${portText}</td>
                            <td>
                                <div class="op-dropdown">
                                    <button class="btn-base btn-outline op-trigger"><?php echo $t['op_menu']; ?></button>
                                    <div class="op-dropdown-menu">
                                        <div class="op-dropdown-item" onclick="openLogs('${item.full_id}','${item.name}')"><?php echo $t['view_log']; ?></div>
                                        <div class="op-dropdown-item" onclick="openNetwork('${item.full_id}','${item.name}')"><?php echo $t['view_network']; ?></div>
                                        <div class="op-dropdown-item" onclick="openExec('${item.full_id}','${item.name}')"><?php echo $t['enter_exec']; ?></div>
                                        <div class="op-dropdown-item" onclick="dockerOperate('restart','${item.full_id}')"><?php echo $t['restart']; ?></div>
                                        <div class="op-dropdown-item" onclick="dockerOperate('stop','${item.full_id}')"><?php echo $t['stop']; ?></div>
                                        <div class="op-dropdown-item" onclick="dockerOperate('rm','${item.full_id}')"><?php echo $t['remove']; ?></div>
                                    </div>
                                </div>
                            </td>
                        </tr>`;
                    }catch(e){}
                });
            }
            $("#dockerTable").html(html);
            $("#statTotal").text(total);
            $("#statRunning").text(running);
            $("#statStopped").text(stopped);
            $(".op-trigger").click(function(e){
                e.stopPropagation();
                $(".op-dropdown-menu").hide();
                $(this).next(".op-dropdown-menu").toggle();
            });
            $(document).click(()=>$(".op-dropdown-menu").hide());
            $("#checkAll").change(function(){
                $(".container-check").prop("checked", $(this).prop("checked"));
                syncSelected();
            });
            $(".container-check").change(syncSelected);
            $("#searchContainer").off("input").on("input",function(){
                let kw = $(this).val().toLowerCase();
                $("#dockerTable tr").each(function(){
                    let n = $(this).data("name")||"";
                    let img = $(this).data("image")||"";
                    if(n.toLowerCase().includes(kw) || img.toLowerCase().includes(kw)) $(this).show();
                    else $(this).hide();
                })
            })
        },
        error:function(xhr){
            hideLoading();
            let errMsg = "<?php echo $t['request_fail']; ?>";
            if(xhr.status === 401) errMsg = "会话失效，请刷新页面重新登录";
            $("#dockerTable").html(`<tr><td colspan="7" class="empty-state" style="color:#dc2626"><div class="empty-icon"><i class="fa fa-exclamation-circle"></i></div><div>${errMsg}</div></td></tr>`);
        }
    });
}

function loadImageList(){
    showLoading();
    $.ajax({
        url: "./api/docker.php?act=image_list",
        type:"GET",
        xhrFields: {withCredentials:true},
        dataType:"json",
        success:function(res){
            hideLoading();
            let html = "";
            if(typeof res !== "object" || res.code === undefined){
                html = `<tr><td colspan="6" class="empty-state" style="color:#dc2626">镜像接口数据异常</td></tr>`;
            }else if(res.code !== 0){
                html = `<tr><td colspan="6" class="empty-state" style="color:#dc2626">${res.msg}</td></tr>`;
            }else if(!res.list || res.list.length === 0){
                html = `<tr><td colspan="6" class="empty-state"><div class="empty-icon"><i class="fa fa-folder-open-o"></i></div><div><?php echo $t['no_image']; ?></div></td></tr>`;
            }else{
                $("#statImage").text(res.list.length);
                res.list.forEach(i=>{
                    html += `<tr>
                        <td>${i.repo}</td>
                        <td>${i.tag}</td>
                        <td title="点击复制完整ID" onclick="copyId('${i.full_id}')">${i.id}</td>
                        <td>${i.size}</td>
                        <td>${i.created}</td>
                        <td>
                            <div class="op-dropdown">
                                <button class="btn-base btn-outline op-trigger"><?php echo $t['op_menu']; ?></button>
                                <div class="op-dropdown-menu">
                                    <div class="op-dropdown-item" onclick="removeImage('${i.full_id}')"><?php echo $t['remove_image']; ?></div>
                                </div>
                            </div>
                        </td>
                    </tr>`;
                });
            }
            $("#imageTable").html(html);
            $(".op-trigger").click(function(e){
                e.stopPropagation();
                $(".op-dropdown-menu").hide();
                $(this).next(".op-dropdown-menu").toggle();
            });
            $(document).click(()=>$(".op-dropdown-menu").hide());
        },
        error:function(xhr){
            hideLoading();
            $("#imageTable").html(`<tr><td colspan="6" class="empty-state" style="color:#dc2626"><div class="empty-icon"><i class="fa fa-exclamation-circle"></i></div><div><?php echo $t['request_fail']; ?></div></td></tr>`);
        }
    });
}

function removeImage(imageId){
    if(!confirm("<?php echo $t['confirm_remove_img']; ?>")) return;
    showLoading();
    $.post("./api/docker.php",{act:"remove_image",image_id:imageId},function(res){
        hideLoading();
        alert(res.msg || "<?php echo $t['op_success']; ?>");
        loadImageList();
    }).fail(function(){
        hideLoading();
        alert("<?php echo $t['op_failed']; ?>");
    });
}

function copyId(fullId){
    let inp = document.createElement("input");
    inp.value = fullId;
    document.body.appendChild(inp);
    inp.select();
    document.execCommand("copy");
    document.body.removeChild(inp);
    alert("完整ID已复制剪贴板");
}
function syncSelected(){
    selectedContainers = [];
    $(".container-check:checked").each(function(){
        selectedContainers.push($(this).data("cid"));
    })
}

function batchOp(action){
    if(selectedContainers.length === 0){
        alert("请先勾选容器");
        return;
    }
    if(action === "rm" && !confirm("<?php echo $t['confirm_remove']; ?>")) return;
    showLoading();
    let idx = 0;
    function next(){
        if(idx >= selectedContainers.length){
            hideLoading();
            loadDockerList();
            alert("批量操作完成");
            return;
        }
        $.post("./api/docker.php",{act:action,container_id:selectedContainers[idx]},()=>{
            idx++; next();
        }).fail(()=>{idx++;next();})
    }
    next();
}

function dockerOperate(action,cid){
    if(opLock) return;
    if(action === "rm" && !confirm("<?php echo $t['confirm_remove']; ?>")) return;
    opLock = true;
    showLoading();
    $("button").prop("disabled",true);
    $.post("./api/docker.php",{act:action,container_id:cid},function(res){
        hideLoading();
        opLock = false;
        $("button").prop("disabled",false);
        alert(res.msg || "<?php echo $t['op_success']; ?>");
        loadDockerList();
    }).fail(function(){
        hideLoading();
        opLock = false;
        $("button").prop("disabled",false);
        alert("<?php echo $t['op_failed']; ?>");
    });
}

function openLogs(cid,name){
    currentFullId = cid;
    closeTerminalSession();
    $("#modalTitle").text(name + " - <?php echo $t['container_log']; ?>");
    $("#modal").css("display","flex");
    $("#modalBody").css("background","#111827").text("加载日志中...");
    $("#cmdInput").show();
    $("#singleExecBtn").show();
    $("#execTip").text("<?php echo $t['tip_exec_once']; ?>");
    $.ajax({
        url: "./api/docker.php?act=logs&container_id="+cid+"&lines=500",
        xhrFields: {withCredentials:true},
        dataType:"json",
        success:function(res){
            $("#modalBody").text(res.data);
        }
    });
}

function openNetwork(cid,name){
    currentFullId = cid;
    closeTerminalSession();
    $("#modalTitle").text(name + " - <?php echo $t['network_info']; ?>");
    $("#modal").css("display","flex");
    $("#modalBody").css("background","#111827").text("加载网络信息...");
    $("#cmdInput").show();
    $("#singleExecBtn").show();
    $("#execTip").text("<?php echo $t['tip_exec_once']; ?>");
    $.ajax({
        url: "./api/docker.php?act=network&container_id="+cid,
        xhrFields: {withCredentials:true},
        dataType:"json",
        success:function(res){
            $("#modalBody").text(res.data);
        }
    });
}

function openExec(cid,name){
    currentFullId = cid;
    closeTerminalSession();
    $("#modalTitle").text(name + " - <?php echo $t['enter_exec']; ?>");
    $("#modal").css("display","flex");
    $("#modalBody").css("background","#111827").empty();
    $("#cmdInput").hide();
    $("#singleExecBtn").hide();
    $("#execTip").text("<?php echo $t['tip_websocket']; ?>");

    term = new Terminal({
        rows:24,
        cols:80,
        theme:{background:"#111827",foreground:"#e5e7eb",cursor:"#60a5fa"},
        fontSize:13,
        fontFamily:"Consolas,Monaco,monospace"
    });
    term.open(document.getElementById("modalBody"));

    const resizeObserver = new ResizeObserver(()=>{
        const width = Math.floor($("#modalBody").width() / 9);
        const height = Math.floor($("#modalBody").height() / 18);
        term.resize(width, height);
        socket.emit("terminal_resize",{width:width,height:height});
    });
    resizeObserver.observe(document.getElementById("modalBody"));

    term.onData(function(data){
        socket.emit("terminal_input",{data:data});
    });

    socket.emit("terminal_start",{cid:cid});
}

function runExec(){
    let cmd = $("#cmdInput").val().trim();
    if(!cmd) return;
    let hit = false;
    BAN_CMD.forEach(b=>{if(cmd.includes(b)) hit=true;});
    if(hit){
        alert("禁止执行高危操作："+BAN_CMD.join("、"));
        return;
    }
    $.post("./api/docker.php",{act:"exec",container_id:currentFullId,cmd:cmd},function(res){
        $("#modalBody").text(res.data);
    }).fail(()=>alert("<?php echo $t['request_fail']; ?>"));
}

function closeModal(){
    closeTerminalSession();
    $("#modal").hide();
    $("#modalBody").empty();
    $("#modalTitle").text("");
    $("#cmdInput").val("");
}

function openCreateModal(){
    $("#createName").val("");
    $("#createImage").val("");
    $("#createCmd").val("");
    $("#createPort").val("");
    $("#createCpu").val("1");
    $("#createMem").val("512m");
    $("#createModal").css("display","flex");
}
function closeCreateModal(){
    $("#createModal").hide();
}
function submitCreate(){
    let name = $("#createName").val().trim();
    let image = $("#createImage").val().trim();
    let cmd = $("#createCmd").val().trim();
    let portStr = $("#createPort").val().trim();
    let cpu = $("#createCpu").val().trim() || "1";
    let memory = $("#createMem").val().trim() || "512m";
    if(!image){
        alert("镜像不能为空");
        return;
    }
    let ports = {};
    if(portStr){
        let arr = portStr.split(",");
        arr.forEach(item=>{
            let sp = item.split(":");
            if(sp.length===2) ports[sp[1]] = sp[0];
        });
    }
    let postBody = {
        name:name,
        image:image,
        cmd:cmd||null,
        ports:ports,
        cpu:parseInt(cpu),
        memory:memory
    };
    showLoading();
    $.ajax({
        url:"./api/docker.php?act=create",
        method:"POST",
        contentType:"application/json",
        data:JSON.stringify(postBody),
        xhrFields:{withCredentials:true},
        dataType:"json",
        success:function(res){
            hideLoading();
            alert(res.msg);
            if(res.code===0){
                closeCreateModal();
                loadDockerList();
            }
        },
        error:function(){
            hideLoading();
            alert("请求失败");
        }
    });
}

function openRepoModal(){
    $("#repoName").val("");
    $("#repoAddr").val("");
    $("#repoUser").val("");
    $("#repoPwd").val("");
    $("#repoModal").css("display","flex");
}
function closeRepoModal(){
    $("#repoModal").hide();
}
function submitBindRepo(){
    let repoName = $("#repoName").val().trim();
    let repoAddr = $("#repoAddr").val().trim();
    let repoUser = $("#repoUser").val().trim();
    let repoPwd = $("#repoPwd").val().trim();
    if(!repoAddr){
        alert("仓库地址不能为空");
        return;
    }
    let postBody = {
        repo_name:repoName,
        repo_addr:repoAddr,
        repo_user:repoUser,
        repo_pwd:repoPwd
    };
    showLoading();
    $.ajax({
        url:"./api/docker.php?act=bind_repo",
        method:"POST",
        contentType:"application/json",
        data:JSON.stringify(postBody),
        xhrFields:{withCredentials:true},
        dataType:"json",
        success:function(res){
            hideLoading();
            alert(res.msg);
            if(res.code===0){
                closeRepoModal();
            }
        },
        error:function(){
            hideLoading();
            alert("仓库绑定请求失败");
        }
    });
}

$("#logoutBtn").click(function(){
    location.href = "logout.php";
});

$(function(){
    initSocket();
    updateTime();
    setInterval(updateTime, 1000);
    refreshTimer = setInterval(function(){
        let activeTab = $(".tab-item.active").data("tab");
        if(activeTab === "container") loadDockerList();
        if(activeTab === "image") loadImageList();
    }, 30000);
    loadDockerList();
    loadImageList();
});
</script>
</body>
</html>
