{% extends "base.html" %}
{% block title %}聊天查看器 — WeChat EXP{% endblock %}
{% block head %}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{{ url_for('static', filename='css/app.css') }}">
<script type="importmap">
{
  "imports": {
    "@xenova/transformers": "https://cdn.jsdelivr.net/npm/@xenova/transformers@2.17.2/dist/transformers.min.js"
  }
}
</script>
<script type="module">
import { pipeline, env } from '@xenova/transformers';

// Load model from local Flask static files (bundled in exe)
// Falls back to Hugging Face CDN if local model not found
env.remoteHost = window.location.origin;
env.remotePathTemplate = '/static/models/{model}';

let _transcriber = null;
let _loading = false;
let _loadResolvers = [];

async function _getTranscriber(onProgress) {
  if (_transcriber) return _transcriber;
  if (_loading) {
    return new Promise((resolve) => { _loadResolvers.push(resolve); });
  }
  _loading = true;
  try {
    onProgress && onProgress('正在加载语音识别模型...');
    _transcriber = await pipeline('automatic-speech-recognition', 'Xenova/whisper-tiny', {
      quantized: true,
      progress_callback: (p) => {
        if (p.status === 'progress' && p.file) {
          const pct = p.progress ? Math.round(p.progress) : 0;
          onProgress && onProgress(`加载模型: ${p.file} ${pct}%`);
        }
      }
    });
    for (const r of _loadResolvers) r(_transcriber);
    _loadResolvers = [];
    return _transcriber;
  } catch (e) {
    _loading = false;
    for (const r of _loadResolvers) r(null);
    _loadResolvers = [];
    throw e;
  }
}

window.WhisperTranscriber = {
  get loaded() { return !!_transcriber; },
  async transcribe(audioUrl, onProgress) {
    const t = await _getTranscriber(onProgress);
    if (!t) throw new Error('模型加载失败');
    const result = await t(audioUrl);
    return result.text || '';
  }
};
</script>
<style>
.group-info-backdrop { position:fixed; top:0; left:0; right:0; bottom:0; background:rgba(0,0,0,0.5); z-index:998; }
.group-info-panel { position:fixed; top:0; right:0; width:300px; height:100vh; background:#161b22; border-left:1px solid #30363d; z-index:999; overflow-y:auto; padding:0; transform:translateX(0); transition:transform 0.2s; }
.gi-header { display:flex; align-items:center; padding:12px 16px; border-bottom:1px solid #21262d; }
.gi-close { font-size:22px; cursor:pointer; color:#8b949e; margin-right:8px; }
.gi-close:hover { color:#e94560; }
.gi-btn { background:none; border:1px solid #30363d; color:#58a6ff; padding:4px 12px; border-radius:6px; cursor:pointer; font-size:15px; margin-left:8px; }
.gi-btn:hover { background:#1a1a2e; }
#group-info-content { padding:12px 16px; }
</style>
{% endblock %}
{% block nav_right %}
<a href="/" class="nav-link">仪表盘</a>
{% endblock %}
{% block content %}
<div id="app">
  <aside id="sidebar">
    <div class="sidebar-header">
      <input type="text" id="contact-search" placeholder="搜索联系人/群聊..." autocomplete="off">
    </div>
    <div id="contact-list" class="contact-list"></div>
  </aside>

  <main id="main">
    <div id="welcome" class="welcome">
      <div class="welcome-icon">💬</div>
      <h2>选择左侧联系人开始浏览</h2>
      <p>支持文本、图片、语音、视频、位置、链接、名片等多种消息类型</p>
    </div>

    <div id="chat-header" class="chat-header" style="display:none">
      <img id="header-avatar" class="header-avatar" src="" style="display:none"
           onerror="this.style.display='none'" alt="" />
      <div class="header-info">
        <span id="chat-name" class="chat-name"></span>
        <span id="chat-stats" class="chat-stats"></span>
      </div>
      <button id="btn-group-info" class="gi-btn" style="display:none" onclick="openGroupInfo()" title="群信息">ⓘ</button>
    </div>

    <div id="filter-bar" class="filter-bar" style="display:none">
      <input type="text" id="filter-keyword" placeholder="搜索消息内容..." autocomplete="off">
      <input type="date" id="filter-date-start" title="开始日期">
      <span class="date-sep">—</span>
      <input type="date" id="filter-date-end" title="结束日期">
      <select id="filter-type">
        <option value="">全部类型</option>
        <option value="1">文本</option>
        <option value="3">图片</option>
        <option value="34">语音</option>
        <option value="43">视频</option>
        <option value="48">位置</option>
        <option value="49">链接/转发</option>
        <option value="42">名片</option>
        <option value="47">表情</option>
        <option value="6">文件</option>
        <option value="50">网络电话</option>
        <option value="10000,10002">系统消息</option>
      </select>
      <select id="filter-sender"><option value="">全部发送者</option></select>
      <span id="filter-result-count" class="filter-result-count"></span>
    </div>

    <div id="message-list" class="message-list" style="display:none"></div>

    <div id="pagination-bar" class="pagination-bar" style="display:none">
      <div class="pagination-controls">
        <button id="btn-first" class="pg-btn" title="首页">&#171;</button>
        <button id="btn-prev" class="pg-btn" title="上页">&#8249;</button>
        <span id="page-numbers" class="page-numbers"></span>
        <button id="btn-next" class="pg-btn" title="下页">&#8250;</button>
        <button id="btn-last" class="pg-btn" title="末页">&#187;</button>
      </div>
      <div class="pagination-jump">
        <span>&#x1f4c5;</span>
        <input type="date" id="jump-date" title="跳转到日期">
        <button id="btn-jump-date" class="pg-btn">跳转</button>
      </div>
      <div class="pagination-info" id="pagination-info"></div>
    </div>
  </main>
</div>

<!-- Group Info Panel (slide-in from right) -->
<div id="group-info-backdrop" class="group-info-backdrop" style="display:none" onclick="closeGroupInfo()"></div>
<div id="group-info-panel" class="group-info-panel" style="display:none">
  <div class="gi-header">
    <span class="gi-close" onclick="closeGroupInfo()">&times;</span>
    <span style="color:#8b949e;font-size:12px">群详情</span>
  </div>
  <div id="group-info-content"></div>
</div>

<div id="lightbox" class="lightbox" style="display:none" onclick="this.style.display='none'">
  <span class="lightbox-close">&times;</span>
  <img id="lightbox-img" src="" alt="">
</div>

<audio id="audio-player" style="display:none" controls></audio>
<a id="voice-download" style="display:none;margin-left:12px;color:#58a6ff;font-size:12px;text-decoration:none" download>下载语音文件</a>
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='js/api.js') }}"></script>
<script src="{{ url_for('static', filename='js/utils.js') }}"></script>
<script src="{{ url_for('static', filename='js/store.js') }}"></script>
<script src="{{ url_for('static', filename='js/components/component.js') }}"></script>
<script src="{{ url_for('static', filename='js/components/contact-list.js') }}"></script>
<script src="{{ url_for('static', filename='js/components/message-bubble.js') }}"></script>
<script src="{{ url_for('static', filename='js/components/voice-player.js') }}"></script>
<script src="{{ url_for('static', filename='js/components/pagination.js') }}"></script>
<script src="{{ url_for('static', filename='js/components/group-info.js') }}"></script>
<script src="{{ url_for('static', filename='js/components/chat-header.js') }}"></script>
<script src="{{ url_for('static', filename='js/components/filter-bar.js') }}"></script>
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
{% endblock %}
