{% extends "base.html" %}
{% set active = "upload" %}

{% block title %}Status Transkripsi #{{ task_id }}{% endblock %}
{% block page_title %}Status Transkripsi{% endblock %}

{% block topbar_extra %}
<span style="color:var(--muted);font-size:.82rem">Task #{{ task_id }}</span>
{% endblock %}

{% block extra_head %}
<style>
  .status-layout {
    display: grid;
    grid-template-columns: 1fr 300px;
    gap: 20px;
    align-items: start;
  }
  @media (max-width: 900px) { .status-layout { grid-template-columns: 1fr; } }

  .status-header {
    display: flex; align-items: center; gap: 16px;
    margin-bottom: 20px;
    flex-wrap: wrap;
  }
  .status-circle {
    width: 56px; height: 56px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 24px;
    flex-shrink: 0;
  }
  .status-circle.pending    { background: rgba(227,179,65,.12); }
  .status-circle.processing { background: rgba(88,166,255,.12); animation: spin-glow 2s ease infinite; }
  .status-circle.completed  { background: rgba(63,185,80,.12); }
  .status-circle.failed     { background: rgba(248,81,73,.12); }
  .status-circle.cancelled  { background: rgba(139,148,158,.12); }
  @keyframes spin-glow { 0%,100%{box-shadow:0 0 0 rgba(88,166,255,0)} 50%{box-shadow:0 0 16px rgba(88,166,255,.3)} }

  .status-info h3 { font-family:'Sora',sans-serif; font-size:1rem; font-weight:700; margin-bottom:4px; }
  .status-info p  { font-size:.82rem; color:var(--muted); }

  .progress-section { margin-bottom: 24px; }
  .progress-label { display:flex; justify-content:space-between; font-size:.8rem; color:var(--muted); margin-bottom:8px; }
  .progress-bar { height:8px; background:var(--border); border-radius:4px; overflow:hidden; }
  .progress-fill {
    height: 100%;
    background: linear-gradient(90deg, var(--accent-dim), var(--accent));
    border-radius: 4px;
    transition: width .6s ease;
  }
  .progress-fill.done      { background: linear-gradient(90deg, #27a33a, var(--success)); }
  .progress-fill.error     { background: var(--danger); }
  .progress-fill.cancelled { background: var(--muted); }

  .result-toolbar { display:flex; gap:8px; margin-bottom:12px; flex-wrap:wrap; align-items:center; }
  .result-textarea {
    width: 100%; background: var(--bg); border: 1px solid var(--border); color: var(--text);
    padding: 16px; border-radius: var(--radius-sm); font-family:'DM Sans',sans-serif;
    font-size: .875rem; line-height: 1.8; resize: vertical; min-height: 280px; outline: none;
  }
  .result-textarea:focus { border-color: var(--accent); }
  .char-count { font-size:.75rem; color:var(--muted); margin-top:6px; }

  .segments-container {
    border:1px solid var(--border); border-radius:var(--radius-sm);
    background:var(--bg); max-height:400px; overflow-y:auto; padding:4px 0;
  }
  .segment-item {
    display:flex; gap:12px; padding:8px 14px;
    border-bottom:1px solid var(--border2); animation:seg-in .3s ease; align-items:flex-start;
  }
  .segment-item:last-child { border-bottom: none; }
  @keyframes seg-in { from{opacity:0;transform:translateY(6px)} to{opacity:1;transform:translateY(0)} }
  .seg-time {
    font-family:'DM Mono',monospace; font-size:.72rem; color:var(--accent);
    white-space:nowrap; padding-top:2px; min-width:80px;
  }
  .seg-text { font-size:.875rem; line-height:1.6; color:var(--text); flex:1; }
  .segments-empty { text-align:center; padding:32px; color:var(--muted); font-size:.85rem; }

  /* ── Action buttons ── */
  .btn-action {
    padding: 5px 12px;
    border-radius: var(--radius-sm);
    font-size: .78rem; font-weight: 600;
    cursor: pointer; font-family: 'DM Sans', sans-serif;
    transition: all .15s;
    display: inline-flex; align-items: center; gap: 6px;
    border: none;
  }
  .btn-action:disabled { opacity: .4; cursor: not-allowed; }

  .btn-cancel-task {
    background: rgba(248,81,73,.12); color: var(--danger); border: 1px solid rgba(248,81,73,.3);
  }
  .btn-cancel-task:hover:not(:disabled) { background: rgba(248,81,73,.22); }

  /* Tombol hapus — muncul untuk semua user di status terminal */
  .btn-delete-task {
    background: rgba(139,148,158,.1); color: var(--muted); border: 1px solid var(--border);
    display: none; /* tampil via JS */
  }
  .btn-delete-task:hover:not(:disabled) {
    background: rgba(248,81,73,.1); color: var(--danger); border-color: rgba(248,81,73,.3);
  }

  .meta-item {
    display:flex; justify-content:space-between; align-items:flex-start;
    padding:11px 0; border-bottom:1px solid var(--border2); font-size:.84rem; gap:12px;
  }
  .meta-item:last-child { border-bottom: none; }
  .meta-key { color:var(--muted); white-space:nowrap; }
  .meta-val { font-weight:500; text-align:right; word-break:break-all; }

  .waiting-anim { text-align:center; padding:60px 20px; }
  .spinner {
    width:48px; height:48px; border:3px solid var(--border); border-top-color:var(--accent);
    border-radius:50%; animation:spin .8s linear infinite; margin:0 auto 20px;
  }
  @keyframes spin { to { transform: rotate(360deg); } }
  .waiting-title { font-family:'Sora',sans-serif; font-size:1rem; font-weight:700; margin-bottom:6px; }
  .waiting-sub   { font-size:.85rem; color:var(--muted); }
  .pulse-dots span { display:inline-block; animation:dot-bounce .8s ease infinite; }
  .pulse-dots span:nth-child(2) { animation-delay:.15s; }
  .pulse-dots span:nth-child(3) { animation-delay:.3s; }
  @keyframes dot-bounce { 0%,80%,100%{transform:translateY(0)} 40%{transform:translateY(-4px)} }

  .badge-cancelled  { background:rgba(139,148,158,.15); color:var(--muted); }
  .badge-cancelling { background:rgba(248,81,73,.08); color:var(--danger); border:1px dashed rgba(248,81,73,.4); }

  /* Toast */
  #toast {
    position:fixed; bottom:24px; right:24px;
    padding:10px 18px; border-radius:var(--radius-sm);
    font-size:.85rem; font-weight:600;
    opacity:0; transform:translateY(8px);
    transition:all .25s; pointer-events:none;
    z-index:999;
  }
  #toast.show { opacity:1; transform:translateY(0); }
  #toast.success { background:rgba(63,185,80,.15); color:var(--success); border:1px solid rgba(63,185,80,.3); }
  #toast.error   { background:rgba(248,81,73,.12); color:var(--danger); border:1px solid rgba(248,81,73,.3); }
</style>
{% endblock %}

{% block content %}
<div class="status-layout">
  <!-- Left: main content -->
  <div>
    <div class="card" style="margin-bottom:16px" id="status-card">
      <div class="status-header">
        <div class="status-circle" id="status-icon">⏳</div>
        <div class="status-info">
          <h3 id="status-title">Memuat status...</h3>
          <p id="status-sub">Harap tunggu</p>
        </div>
        <div style="margin-left:auto;display:flex;align-items:center;gap:10px;flex-wrap:wrap">
          <span class="badge" id="status-badge">—</span>

          {# Tombol cancel — hanya admin #}
          {% if user.role == 'admin' %}
          <button class="btn-action btn-cancel-task" id="btn-cancel" style="display:none" onclick="requestCancel()">
            <svg width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24">
              <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
            </svg>
            Hentikan
          </button>
          {% endif %}

          {# Tombol hapus — semua user (tampil via JS saat status terminal) #}
          <button class="btn-action btn-delete-task" id="btn-delete" onclick="requestDelete()">
            <svg width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
              <polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6"/>
              <path d="M10 11v6M14 11v6M9 6V4h6v2"/>
            </svg>
            Hapus Riwayat
          </button>
        </div>
      </div>

      <div class="progress-section">
        <div class="progress-label">
          <span>Progress</span>
          <span id="progress-pct">0%</span>
        </div>
        <div class="progress-bar">
          <div class="progress-fill" id="progress-fill" style="width:0%"></div>
        </div>
      </div>
    </div>

    <!-- Result / Streaming area -->
    <div class="card" id="result-card">

      <!-- Waiting -->
      <div class="waiting-anim" id="waiting-state">
        <div class="spinner"></div>
        <div class="waiting-title">Menunggu proses dimulai</div>
        <div class="waiting-sub">Halaman ini otomatis diperbarui <span class="pulse-dots"><span>.</span><span>.</span><span>.</span></span></div>
      </div>

      <!-- Streaming segmen -->
      <div id="streaming-state" style="display:none">
        <div class="card-header">
          <span class="card-title">Transkripsi Berjalan — Hasil Sementara</span>
          <span class="badge badge-processing badge-dot" style="font-size:.7rem">Live</span>
        </div>
        <div class="segments-container" id="segments-container">
          <div class="segments-empty" id="segments-empty">Segmen pertama sedang diproses...</div>
        </div>
        <div style="margin-top:10px;font-size:.78rem;color:var(--muted)">
          Hasil akan diperbarui otomatis setiap beberapa detik.
        </div>
      </div>

      <!-- Hasil final -->
      <div id="result-state" style="display:none">
        <div class="card-header">
          <span class="card-title">Hasil Transkripsi</span>
        </div>
        <div class="result-toolbar">
          <button class="btn btn-ghost btn-sm" onclick="copyResult()">
            <svg width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg>
            Salin
          </button>
          <button class="btn btn-ghost btn-sm" onclick="downloadResult()">
            <svg width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg>
            Unduh TXT
          </button>
          <button class="btn btn-ghost btn-sm" onclick="toggleView()" id="btn-toggle-view">
            Tampilan Segmen
          </button>
        </div>
        <div id="view-plain">
          <textarea class="result-textarea" id="result-text" readonly></textarea>
          <div class="char-count" id="char-count"></div>
        </div>
        <div id="view-segments" style="display:none">
          <div class="segments-container" id="final-segments-container"></div>
        </div>

        <!-- Berita Acara -->
        <div id="ba-section" style="margin-top:20px;padding-top:16px;border-top:1px solid var(--border2)">
          <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;flex-wrap:wrap;gap:8px">
            <div>
              <div style="font-family:'Sora',sans-serif;font-size:.88rem;font-weight:700;margin-bottom:3px">
                📋 Berita Acara Sidang
              </div>
              <div style="font-size:.78rem;color:var(--muted)">
                Buat dokumen tanya-jawab formal dari hasil transkripsi ini menggunakan GPT.
              </div>
            </div>
            <button class="btn btn-sm" id="btn-create-ba" onclick="createBeritaAcara()"
              style="background:rgba(212,160,23,.12);color:var(--gold);border:1px solid rgba(212,160,23,.3);white-space:nowrap;display:flex;align-items:center;gap:7px">
              <svg width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/>
                <path d="M14 2v6h6M16 13H8M16 17H8M10 9H8"/>
              </svg>
              Buat Berita Acara
            </button>
          </div>
          <div id="ba-list" style="display:none">
            <div style="font-size:.75rem;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.8px;margin-bottom:8px">
              Dokumen Sebelumnya
            </div>
            <div id="ba-items"></div>
          </div>
        </div>
      </div>

      <!-- Error -->
      <div id="error-state" style="display:none">
        <div class="alert alert-danger">
          <svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
          <div>
            <div style="font-weight:600;margin-bottom:4px">Transkripsi Gagal</div>
            <div id="error-msg" style="font-size:.82rem"></div>
          </div>
        </div>
        <div style="display:flex;gap:8px;margin-top:12px;flex-wrap:wrap">
          <a href="/transkripsi/file" class="btn btn-primary btn-sm">Coba Lagi dengan File Baru</a>
          <span style="font-size:.78rem;color:var(--muted);align-self:center">
            — atau gunakan tombol <strong>Hapus Riwayat</strong> di atas untuk membersihkan task ini.
          </span>
        </div>
      </div>

      <!-- Cancelled -->
      <div id="cancelled-state" style="display:none">
        <div class="alert alert-warning">
          <svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
          <div>
            <div style="font-weight:600;margin-bottom:4px">Transkripsi Dibatalkan</div>
            <div style="font-size:.82rem">Task ini dihentikan sebelum selesai.</div>
          </div>
        </div>
        <a href="/transkripsi/file" class="btn btn-primary btn-sm" style="margin-top:12px">Upload File Baru</a>
      </div>

    </div>
  </div>

  <!-- Right: meta info -->
  <div class="card">
    <div class="card-header">
      <span class="card-title">Detail Task</span>
    </div>
    <div id="meta-list">
      <div class="meta-item"><span class="meta-key">Task ID</span><span class="meta-val">#{{ task_id }}</span></div>
      <div class="meta-item"><span class="meta-key">Status</span><span class="meta-val" id="meta-status">—</span></div>
      <div class="meta-item"><span class="meta-key">Engine</span><span class="meta-val" id="meta-engine">—</span></div>
      <div class="meta-item"><span class="meta-key">Model</span><span class="meta-val" id="meta-model">—</span></div>
      <div class="meta-item"><span class="meta-key">Mode Sidang</span><span class="meta-val" id="meta-court">—</span></div>
      <div class="meta-item"><span class="meta-key">Durasi Audio</span><span class="meta-val" id="meta-duration">—</span></div>
      <div class="meta-item"><span class="meta-key">Waktu Proses</span><span class="meta-val" id="meta-proctime">—</span></div>
      <div class="meta-item"><span class="meta-key">Dibuat</span><span class="meta-val" id="meta-created">—</span></div>
    </div>
  </div>
</div>

<!-- Toast notifikasi -->
<div id="toast"></div>
{% endblock %}

{% block scripts %}
<script>
  const TASK_ID    = {{ task_id }};
  const IS_ADMIN   = {{ 'true' if user.role == 'admin' else 'false' }};
  let pollInterval = null;
  let lastStatus   = null;
  let lastProgress = -1;
  let viewMode     = 'plain';
  let finalSegments = [];
  let cancelRequested = false;

  const STATUS_ICON  = { pending:'⏳', processing:'⚙️', completed:'✅', failed:'❌', cancelled:'🚫' };
  const STATUS_TITLE = {
    pending:    'Menunggu dalam antrian...',
    processing: 'Transkripsi sedang berjalan...',
    completed:  'Transkripsi berhasil!',
    failed:     'Transkripsi gagal',
    cancelled:  'Transkripsi dibatalkan',
  };
  const STATUS_SUB = {
    pending:    'Task akan segera diproses oleh worker.',
    processing: 'Hasil sementara ditampilkan di bawah saat segmen selesai.',
    completed:  'Hasil transkripsi siap.',
    failed:     'Terjadi kesalahan saat memproses audio.',
    cancelled:  'Task dihentikan sebelum selesai.',
  };
  const BADGE_LABEL = {
    pending:'Menunggu', processing:'Diproses',
    completed:'Selesai', failed:'Gagal', cancelled:'Dibatalkan',
  };

  // Status yang sudah final — tidak berubah lagi
  const TERMINAL_STATUSES = new Set(['completed', 'failed', 'cancelled']);

  function formatSec(s) {
    if (s == null) return '—';
    if (s < 60) return s.toFixed(1) + ' detik';
    const m = Math.floor(s/60), sec = (s%60).toFixed(0);
    return `${m}m ${sec}s`;
  }

  function formatTimestamp(sec) {
    const m  = Math.floor(sec / 60);
    const s  = Math.floor(sec % 60);
    const ms = Math.round((sec % 1) * 10);
    return `${String(m).padStart(2,'0')}:${String(s).padStart(2,'0')}.${ms}`;
  }

  function showToast(msg, type = 'success') {
    const t = document.getElementById('toast');
    t.textContent = msg;
    t.className = `show ${type}`;
    setTimeout(() => { t.className = ''; }, 3000);
  }

  function renderSegments(segs, containerId) {
    const container = document.getElementById(containerId);
    const empty     = container.querySelector('.segments-empty');
    if (empty) empty.remove();
    const existing = container.querySelectorAll('.segment-item').length;
    const newSegs  = segs.slice(existing);
    newSegs.forEach(seg => {
      const div = document.createElement('div');
      div.className = 'segment-item';
      div.innerHTML = `
        <span class="seg-time">${formatTimestamp(seg.start)} → ${formatTimestamp(seg.end)}</span>
        <span class="seg-text">${seg.text || ''}</span>`;
      container.appendChild(div);
    });
    container.scrollTop = container.scrollHeight;
  }

  function showState(name) {
    ['waiting-state','streaming-state','result-state','error-state','cancelled-state'].forEach(id => {
      document.getElementById(id).style.display = id === name ? 'block' : 'none';
    });
  }

  // ── Berita Acara ────────────────────────────────────────────────
  async function loadBAList() {
    try {
      const r = await fetch(`/api/berita-acara/by-task/${TASK_ID}`);
      if (!r.ok) return;
      const d = await r.json();
      const items  = d.items || [];
      const listEl = document.getElementById('ba-list');
      const itemsEl = document.getElementById('ba-items');
      if (items.length === 0) { listEl.style.display = 'none'; return; }
      listEl.style.display = 'block';
      const statusLabel = { pending:'Menunggu', processing:'Diproses', completed:'Selesai', failed:'Gagal' };
      const statusColor = { pending:'var(--muted)', processing:'var(--accent)', completed:'var(--success)', failed:'var(--danger)' };
      itemsEl.innerHTML = items.map(ba => `
        <div style="display:flex;align-items:center;justify-content:space-between;padding:8px 10px;
                    background:var(--surface2);border-radius:var(--radius-sm);margin-bottom:6px">
          <div style="display:flex;align-items:center;gap:10px">
            <span style="font-size:.72rem;font-weight:600;color:${statusColor[ba.status]||'var(--muted)'};
                         background:rgba(0,0,0,.2);padding:2px 8px;border-radius:20px">
              ${statusLabel[ba.status]||ba.status}
            </span>
            <span style="font-size:.82rem;color:var(--muted)">
              BA #${ba.id} · ${new Date(ba.created_at).toLocaleString('id-ID')}
            </span>
          </div>
          ${ba.status === 'completed' ? `<a href="/berita-acara/${ba.id}?task_id=${TASK_ID}"
            style="font-size:.8rem;color:var(--accent);text-decoration:none;font-weight:600">Buka →</a>` : ''}
        </div>`).join('');
    } catch(e) { console.warn('BA list error:', e); }
  }

  async function createBeritaAcara() {
    const btn = document.getElementById('btn-create-ba');
    btn.disabled = true;
    btn.innerHTML = '⏳ Memproses...';
    try {
      const r = await fetch('/api/berita-acara', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ task_id: TASK_ID }),
      });
      const d = await r.json();
      if (!r.ok) throw new Error(d.detail || 'Gagal membuat Berita Acara.');
      window.location.href = `/berita-acara/${d.ba_id}?task_id=${TASK_ID}`;
    } catch(e) {
      alert('Error: ' + e.message);
      btn.disabled = false;
      btn.innerHTML = `
        <svg width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
          <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/>
          <path d="M14 2v6h6M16 13H8M16 17H8M10 9H8"/>
        </svg>
        Buat Berita Acara`;
    }
  }

  // ── Cancel (admin) ───────────────────────────────────────────────
  async function requestCancel() {
    const btn = document.getElementById('btn-cancel');
    if (!btn || cancelRequested) return;
    if (!confirm(`Yakin ingin menghentikan task #${TASK_ID}? Hasil sementara tidak akan disimpan.`)) return;
    cancelRequested = true;
    btn.disabled = true;
    btn.innerHTML = '⏳ Membatalkan...';
    try {
      const r = await fetch(`/api/admin/tasks/${TASK_ID}/cancel`, { method: 'POST' });
      const d = await r.json();
      if (!r.ok) {
        alert(d.detail || 'Gagal membatalkan task.');
        cancelRequested = false;
        btn.disabled = false;
        btn.innerHTML = '✕ Hentikan';
        return;
      }
      document.getElementById('status-sub').textContent =
        'Permintaan cancel dikirim. Worker akan berhenti setelah segmen saat ini selesai...';
    } catch(e) {
      alert('Gagal menghubungi server.');
      cancelRequested = false;
      btn.disabled = false;
      btn.innerHTML = '✕ Hentikan';
    }
  }

  // ── Hapus task (semua user) ──────────────────────────────────────
  async function requestDelete() {
    const btn = document.getElementById('btn-delete');
    if (!btn) return;

    if (!confirm(
      `Hapus riwayat transkripsi #${TASK_ID}?\n\n` +
      `File audio dan hasil transkripsi akan dihapus permanen dan tidak bisa dipulihkan.`
    )) return;

    btn.disabled = true;
    btn.innerHTML = '⏳ Menghapus...';

    try {
      // Admin pakai endpoint admin, user biasa pakai endpoint user
      const url = IS_ADMIN
        ? `/api/admin/tasks/${TASK_ID}`
        : `/api/transkripsi/${TASK_ID}`;

      const r = await fetch(url, { method: 'DELETE' });
      const d = await r.json();

      if (!r.ok) throw new Error(d.detail || 'Gagal menghapus task.');

      showToast('✅ Task berhasil dihapus. Mengarahkan ke beranda...', 'success');
      clearInterval(pollInterval);
      setTimeout(() => { window.location.href = '/home'; }, 1800);

    } catch(e) {
      showToast('❌ ' + e.message, 'error');
      btn.disabled = false;
      btn.innerHTML = `
        <svg width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
          <polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6"/>
          <path d="M10 11v6M14 11v6M9 6V4h6v2"/>
        </svg>
        Hapus Riwayat`;
    }
  }

  // ── Polling ──────────────────────────────────────────────────────
  async function poll() {
    try {
      const r = await fetch(`/api/status/${TASK_ID}`);
      if (!r.ok) return;
      const d = await r.json();

      const statusChanged   = d.status !== lastStatus;
      const progressChanged = d.progress !== lastProgress;
      if (!statusChanged && !progressChanged && d.status === 'processing' && !d.segments?.length) return;

      lastStatus   = d.status;
      lastProgress = d.progress;

      // Status header
      document.getElementById('status-icon').className  = `status-circle ${d.status}`;
      document.getElementById('status-icon').textContent = STATUS_ICON[d.status] || '❓';
      document.getElementById('status-title').textContent = STATUS_TITLE[d.status] || d.status;
      document.getElementById('status-sub').textContent   = STATUS_SUB[d.status]  || '';

      const badge = document.getElementById('status-badge');
      badge.className  = `badge badge-dot badge-${d.status}`;
      badge.textContent = BADGE_LABEL[d.status] || d.status;

      // Tombol cancel (admin)
      const btnCancel = document.getElementById('btn-cancel');
      if (btnCancel) {
        const canCancel = (d.status === 'processing' || d.status === 'pending') && !cancelRequested;
        btnCancel.style.display = canCancel ? 'inline-flex' : 'none';
      }

      // Tombol hapus: tampil saat status sudah terminal (completed/failed/cancelled)
      const btnDelete = document.getElementById('btn-delete');
      if (btnDelete) {
        btnDelete.style.display = TERMINAL_STATUSES.has(d.status) ? 'inline-flex' : 'none';
      }

      // Progress bar
      const pct  = d.progress || 0;
      document.getElementById('progress-pct').textContent = pct + '%';
      const fill = document.getElementById('progress-fill');
      fill.style.width = pct + '%';
      fill.className = 'progress-fill'
        + (d.status === 'completed' ? ' done'
           : d.status === 'failed'  ? ' error'
           : d.status === 'cancelled' ? ' cancelled' : '');

      // Meta
      document.getElementById('meta-status').innerHTML    = `<span class="badge badge-${d.status}">${d.status}</span>`;
      document.getElementById('meta-engine').textContent  = d.engine || '—';
      document.getElementById('meta-model').textContent   = d.model_type || '—';
      document.getElementById('meta-court').textContent   = d.is_court_mode ? '✅ Aktif' : '—';
      document.getElementById('meta-duration').textContent = formatSec(d.audio_duration);
      document.getElementById('meta-proctime').textContent = formatSec(d.processing_time);
      document.getElementById('meta-created').textContent  = d.created_at ? new Date(d.created_at).toLocaleString('id-ID') : '—';

      // Konten utama
      if (d.status === 'processing') {
        const hasSegs = d.segments && d.segments.length > 0;
        if (hasSegs) {
          showState('streaming-state');
          renderSegments(d.segments, 'segments-container');
        } else {
          showState('waiting-state');
        }

      } else if (d.status === 'completed') {
        showState('result-state');
        const txt = d.result || '';
        document.getElementById('result-text').value = txt;
        document.getElementById('char-count').textContent =
          `${txt.length.toLocaleString()} karakter · ${txt.trim().split(/\s+/).filter(Boolean).length.toLocaleString()} kata`;
        clearInterval(pollInterval);
        loadBAList();

      } else if (d.status === 'failed') {
        showState('error-state');
        document.getElementById('error-msg').textContent = d.error_message || 'Kesalahan tidak diketahui.';
        clearInterval(pollInterval);

      } else if (d.status === 'cancelled') {
        showState('cancelled-state');
        clearInterval(pollInterval);

      } else {
        showState('waiting-state');
        document.querySelector('.waiting-title').textContent = 'Menunggu dalam antrian...';
      }

    } catch(e) { console.warn('Poll error:', e); }
  }

  function copyResult() {
    const txt = document.getElementById('result-text').value;
    navigator.clipboard.writeText(txt).then(() => {
      const btn = event.target.closest('button');
      const orig = btn.innerHTML;
      btn.innerHTML = '✅ Tersalin!';
      setTimeout(() => btn.innerHTML = orig, 2000);
    });
  }

  function downloadResult() {
    const txt  = document.getElementById('result-text').value;
    const blob = new Blob([txt], { type: 'text/plain' });
    const url  = URL.createObjectURL(blob);
    const a    = document.createElement('a');
    a.href     = url;
    a.download = `transkripsi-task-${TASK_ID}.txt`;
    a.click();
    URL.revokeObjectURL(url);
  }

  function toggleView() {
    const btn = document.getElementById('btn-toggle-view');
    if (viewMode === 'plain') {
      viewMode = 'segments';
      document.getElementById('view-plain').style.display    = 'none';
      document.getElementById('view-segments').style.display = 'block';
      btn.textContent = 'Tampilan Teks';
      const fc = document.getElementById('final-segments-container');
      if (fc.children.length === 0 && finalSegments.length > 0) {
        renderSegments(finalSegments, 'final-segments-container');
      }
    } else {
      viewMode = 'plain';
      document.getElementById('view-plain').style.display    = 'block';
      document.getElementById('view-segments').style.display = 'none';
      btn.textContent = 'Tampilan Segmen';
    }
  }

  poll();
  pollInterval = setInterval(poll, 2500);
</script>
{% endblock %}