<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Pic Watermark Demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="/static/style.css">
    <style>
      .tip-card {
        border: 1px solid #e9ecef;
        border-radius: 16px;
        background: #fff;
      }
      .tip-chip {
        display: inline-flex;
        align-items: center;
        padding: 0.3rem 0.65rem;
        border-radius: 999px;
        background: #f3f5f7;
        font-size: 0.85rem;
        color: #495057;
        margin-right: 0.4rem;
        margin-bottom: 0.4rem;
      }
      .mini-muted {
        font-size: 0.88rem;
        color: #6c757d;
      }
      .mono-box {
        font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
        font-size: 0.85rem;
        background: #f8f9fa;
        border: 1px solid #e9ecef;
        border-radius: 12px;
        padding: 0.75rem;
        word-break: break-all;
      }
      .mode-help {
        display: none;
      }
      .mode-help.active {
        display: block;
      }
    </style>
  </head>
  <body class="bg-light">
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-4">
      <div class="container-fluid">
        <a class="navbar-brand fs-1" href="#">Pic Watermark</a>
      </div>
    </nav>

    <div class="app-container">
      {% with messages = get_flashed_messages(with_categories=true) %}
        {% if messages %}
          {% for category, msg in messages %}
            <div class="alert alert-{{ category }}" role="alert">{{ msg }}</div>
          {% endfor %}
        {% endif %}
      {% endwith %}

      <div class="row">
        <div class="col-md-4">
          <div class="card mb-3 large-card">
            <div class="card-header">用户管理</div>
            <div class="card-body">
              <table class="table table-sm align-middle">
                <thead><tr><th>ID</th><th>Key</th><th></th></tr></thead>
                <tbody>
                  {% for u in users %}
                    <tr>
                      <td>{{ u.user_id }}</td>
                      <td>{{ u.user_key }}</td>
                      <td>
                        <form method="post" action="/users/delete" style="display:inline">
                          <input type="hidden" name="user_id" value="{{ u.user_id }}">
                          <button class="btn btn-sm btn-outline-danger" type="submit">删除</button>
                        </form>
                      </td>
                    </tr>
                  {% endfor %}
                </tbody>
              </table>

              <hr>
              <form method="post" action="/users/add" class="row g-2">
                <div class="col-6">
                  <input name="user_id" class="form-control form-control-sm" placeholder="user_x">
                </div>
                <div class="col-6">
                  <input name="user_key" class="form-control form-control-sm" placeholder="user_key">
                </div>
                <div class="col-12 text-end">
                  <button class="btn primary-action btn-primary">添加用户</button>
                </div>
              </form>
            </div>
          </div>

          <div class="card mb-3 large-card equal-height">
            <div class="card-header">操作</div>
            <div class="card-body d-flex">
              <div class="operation-buttons w-100">
                <a class="btn btn-primary btn-lg" href="/view/users?out_dir={{ current_out_dir }}">查看用户水印结果</a>
                <a class="btn btn-secondary btn-lg" href="/view/collusion?out_dir={{ current_out_dir }}">查看合谋攻击与评分</a>
                <a class="btn btn-info btn-lg text-white" href="/report?out_dir={{ current_out_dir }}">查看 report.json</a>
              </div>
            </div>
          </div>
        </div>

        <div class="col-md-8">
          <div class="card mb-3 large-card">
            <div class="card-header">运行配置</div>
            <div class="card-body">
              <form method="post" action="/run">
                <div class="mb-2">
                  <label class="form-label">图片路径（eg../image）</label>
                  <input name="image" class="form-control form-control-sm" placeholder="path/to/image.png">
                </div>
                <div class="mb-2">
                  <label class="form-label">输出目录（相对项目根）</label>
                  <input name="out_dir" class="form-control form-control-sm" value="{{ current_out_dir or 'results' }}">
                </div>

                <div class="row g-2 mb-2">
                  <div class="col-md-6">
                    <label class="form-label">处理模式</label>
                    <select name="processing_mode" id="processing_mode" class="form-select form-select-sm">
                      <option value="auto" selected>auto</option>
                      <option value="default">default</option>
                      <option value="large_raster">large_raster</option>
                    </select>
                  </div>
                  <div class="col-md-6">
                    <label class="form-label">tile_size</label>
                    <input name="tile_size" type="number" min="256" step="256" value="2048" class="form-control form-control-sm">
                  </div>
                </div>

                <div id="mode_help_auto" class="alert alert-light border mode-help active py-2 mb-2">
                  自动根据位深和文件大小切换
                </div>
                <div id="mode_help_default" class="alert alert-light border mode-help py-2 mb-2">
                  default链路适合普通小图
                </div>
                <div id="mode_help_large_raster" class="alert alert-warning mode-help py-2 mb-2">
                  large raster适合大图文件
                </div>

                <div class="row g-2 mb-2">
                  <div class="col-6">
                    <label class="form-label">用户数</label>
                    <input name="num_users" type="number" min="1" max="{{ users|length }}" value="{{ users|length if users|length < 9 else 8 }}" class="form-control form-control-sm">
                  </div>
                  <div class="col-6">
                    <label class="form-label">码长</label>
                    <input name="code_length" type="number" value="512" class="form-control form-control-sm">
                  </div>
                </div>

                <div class="mb-2">
                  <label class="form-label">合谋（逗号分隔）</label>
                  <input name="colluders" class="form-control form-control-sm" placeholder="user_2,user_5">
                </div>

                <div class="row g-2 mb-2">
                  <div class="col-4">
                    <label class="form-label">delta</label>
                    <input name="delta" type="number" step="0.1" value="8.0" class="form-control form-control-sm">
                  </div>
                  <div class="col-4">
                    <label class="form-label">repeats</label>
                    <input name="repeats" type="number" value="2" class="form-control form-control-sm">
                  </div>
                </div>

                <div class="mb-2">
                  <label class="form-label">delta_mode</label>
                  <select name="delta_mode" class="form-select form-select-sm">
                    <option value="normalized_8bit" selected>normalized_8bit（推荐）</option>
                    <option value="native">native</option>
                  </select>
                </div>

                <div class="mb-2">
                  <label class="form-label">master_key</label>
                  <input name="master_key" value="server-master-key-2026" class="form-control form-control-sm">
                </div>
                <div class="row g-2 mb-2">
                  <div class="col-6">
                    <label class="form-label">content_id</label>
                    <input name="content_id" value="asset-demo-001" class="form-control form-control-sm">
                  </div>
                  <div class="col-6">
                    <label class="form-label">seed</label>
                    <input name="seed" value="2026" class="form-control form-control-sm">
                  </div>
                </div>
                <div class="row g-2 mb-2">
                  <div class="col-6">
                    <label class="form-label">cover_size</label>
                    <input name="cover_size" type="number" value="512" class="form-control form-control-sm">
                  </div>
                  <div class="col-6">
                    <label class="form-label">psb_max_side</label>
                    <input name="psb_max_side" type="number" value="0" class="form-control form-control-sm">
                  </div>
                </div>

                <div class="form-check mb-3">
                  <input class="form-check-input" type="checkbox" name="emit_psb" id="emit_psb">
                  <label class="form-check-label" for="emit_psb">
                    输出扁平单层 PSB 文件
                  </label>
                </div>
                <div class="text-end">
                  <button class="btn primary-action btn-success">运行并生成</button>
                </div>
              </form>
            </div>
          </div>

          <div class="card mb-3 large-card">
            <div class="card-header">提取字符串</div>
            <div class="card-body">
              <form method="post" action="/extract_text" enctype="multipart/form-data">
                <input type="hidden" name="out_dir" value="{{ current_out_dir or 'results' }}">

                <div class="mb-2">
                  <label class="form-label">上传带水印图片</label>
                  <input type="file" name="extract_image_file" class="form-control form-control-sm">
                </div>

                <div class="mb-2">
                  <label class="form-label">或直接填写图片路径</label>
                  <input name="extract_image_path" class="form-control form-control-sm" placeholder="path/to/watermarked_image.png">
                </div>

                <div class="row g-2 mb-2">
                  <div class="col-md-6">
                    <label class="form-label">提取模式</label>
                    <select name="extract_route_mode" id="extract_route_mode" class="form-select form-select-sm">
                      <option value="auto" selected>auto</option>
                      <option value="default">default</option>
                      <option value="large_raster">large_raster</option>
                    </select>
                  </div>
                  <div class="col-md-6">
                    <label class="form-label">extract_tile_size</label>
                    <input name="extract_tile_size" type="number" min="256" step="256" value="2048" class="form-control form-control-sm">
                  </div>
                </div>

                <div class="row g-2 mb-2">
                  <div class="col-6">
                    <label class="form-label">master_key</label>
                    <input name="extract_master_key" value="server-master-key-2026" class="form-control form-control-sm">
                  </div>
                  <div class="col-6">
                    <label class="form-label">content_id</label>
                    <input name="extract_content_id" value="asset-demo-001" class="form-control form-control-sm">
                  </div>
                </div>

                <div class="row g-2 mb-2">
                  <div class="col-3">
                    <label class="form-label">delta</label>
                    <input name="extract_delta" type="number" step="0.1" value="8.0" class="form-control form-control-sm">
                  </div>
                  <div class="col-3">
                    <label class="form-label">repeats</label>
                    <input name="extract_repeats" type="number" value="2" class="form-control form-control-sm">
                  </div>
                  <div class="col-3">
                    <label class="form-label">code_length</label>
                    <input name="extract_code_length" type="number" value="512" class="form-control form-control-sm">
                  </div>
                  <div class="col-3">
                    <label class="form-label">psb_max_side</label>
                    <input name="extract_psb_max_side" type="number" value="0" class="form-control form-control-sm">
                  </div>
                </div>

                <div class="mb-3">
                  <label class="form-label">delta_mode</label>
                  <select name="extract_delta_mode" class="form-select form-select-sm">
                    <option value="normalized_8bit" selected>normalized_8bit（推荐）</option>
                    <option value="native">native</option>
                  </select>
                </div>

                <div class="text-end">
                  <button class="btn btn-warning text-dark">提取并显示字符串</button>
                </div>
              </form>

              {% if extract_result %}
                <hr>
                <div class="alert alert-light border mb-0">
                  <div><strong>图片：</strong>{{ extract_result.image_path }}</div>
                  <div><strong>提取字符串：</strong>{{ extract_result.extracted_text if extract_result.extracted_text else '解析失败' }}</div>
                  <div><strong>字符串校验：</strong>{{ '通过' if extract_result.text_ok else '失败' }}</div>
                  <div><strong>路由：</strong>{{ extract_result.route }}</div>
                  <div><strong>路由原因：</strong>{{ extract_result.route_reason }}</div>
                  <div><strong>输入是否 PSB：</strong>{{ extract_result.input_is_psb }}</div>
                  <div><strong>输入位深：</strong>{{ extract_result.input_depth }}</div>
                  <div><strong>提取位数：</strong>{{ extract_result.display_bits_len }}</div>
                </div>
              {% endif %}
            </div>
          </div>

          <div class="card mb-3 large-card equal-height">
            <div class="card-header">输出摘要</div>
            <div class="card-body">
              <p class="mb-1">输出目录: <strong>{{ current_out_dir }}</strong></p>
              <p class="mb-1">用户数量: <strong>{{ users|length }}</strong></p>
              <p class="mb-1">图片数量: <strong>{{ images|length }}</strong></p>
              {% if report %}
                <hr>
                <p class="mb-2">最近运行配置：</p>
                <ul class="list-unstyled small mb-0">
                  <li>模式: {{ report.mode if report.mode else '-' }}</li>
                  <li>应用路由: {{ report.app_route if report.app_route else '-' }}</li>
                  <li>路由原因: {{ report.route_reason if report.route_reason else '-' }}</li>
                  <li>码长: {{ report.config.code_length if report.config else (report.total_bits if report.total_bits else '-') }}</li>
                  <li>delta: {{ report.config.delta if report.config else report.delta }}</li>
                  <li>repeats: {{ report.config.repeats if report.config else report.repeats }}</li>
                  <li>tile_size: {{ report.tile_size if report.tile_size else '-' }}</li>
                  <li>单用户链路用户: {{ report.selected_user_id if report.selected_user_id else (report.user_id if report.user_id else '-') }}</li>
                  <li>输入是否 PSB: {{ report.config.input_is_psb if report.config else report.input_is_psb }}</li>
                  <li>输入位深: {{ report.config.input_depth if report.config else report.input_depth }}</li>
                  <li>是否尝试导出 PSB: {{ report.config.emit_psb if report.config else (report.output_psb is not none) }}</li>
                  <li>PSB 最大边: {{ report.config.psb_max_side if report.config else '-' }}</li>
                </ul>
              {% endif %}
            </div>
          </div>
        </div>
      </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
    <script>
      (function(){
        const equalize = () => {
          try {
            const leftBody = document.querySelector('.col-md-4 .large-card .card-body');
            const rightBody = document.querySelector('.col-md-8 .large-card .card-body');
            if (!leftBody || !rightBody) return;
            leftBody.style.minHeight = '';
            rightBody.style.minHeight = '';
            const lh = leftBody.getBoundingClientRect().height;
            const rh = rightBody.getBoundingClientRect().height;
            const h = Math.max(lh, rh);
            leftBody.style.minHeight = h + 'px';
            rightBody.style.minHeight = h + 'px';
          } catch (e) { }
        };

        const syncModeHelp = () => {
          const select = document.getElementById('processing_mode');
          if (!select) return;
          const value = select.value || 'auto';
          document.querySelectorAll('.mode-help').forEach(el => el.classList.remove('active'));
          const target = document.getElementById('mode_help_' + value);
          if (target) target.classList.add('active');
        };

        let t = null;
        window.addEventListener('load', () => {
          equalize();
          syncModeHelp();
        });
        window.addEventListener('resize', () => {
          clearTimeout(t);
          t = setTimeout(equalize, 120);
        });

        const select = document.getElementById('processing_mode');
        if (select) {
          select.addEventListener('change', syncModeHelp);
        }
      })();
    </script>
  </body>
</html>
