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

{% block title %}Riwayat Transkripsi{% endblock %}
{% block page_title %}Riwayat Transkripsi{% endblock %}

{% block extra_head %}
<style>
  /* ── Filter toolbar ── */
  .riwayat-toolbar {
    display: flex; align-items: center; gap: 10px;
    margin-bottom: 16px; flex-wrap: wrap;
  }
  .riwayat-toolbar-right { margin-left: auto; display: flex; gap: 8px; }

  /* ── Storage summary card ── */
  .storage-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 12px;
    margin-bottom: 20px;
  }
  .storage-sum-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px;
  }
  .sum-label {
    font-size: .7rem; color: var(--muted);
    text-transform: uppercase; font-weight: 600;
    letter-spacing: .4px; margin-bottom: 5px;
  }
  .sum-val {
    font-family: 'Sora', sans-serif;
    font-size: 1.35rem; font-weight: 800;
  }
  .sum-sub { font-size: .72rem; color: var(--muted); margin-top: 2px; }

  /* ── Table ── */
  .table-wrap { overflow-x: auto; }
  table { width: 100%; border-collapse: collapse; font-size: .84rem; }
  thead tr { border-bottom: 1px solid var(--border); }
  th {
    text-align: left; padding: 10px 14px;
    font-size: .72rem; font-weight: 600;
    color: var(--muted); text-transform: uppercase; letter-spacing: .5px;
  }
  td { padding: 11px 14px; border-bottom: 1px solid var(--border2); vertical-align: middle; }
  tbody tr:hover { background: var(--surface2); }
  tbody tr:last-child td { border-bottom: none; }

  /* ── File size badge ── */
  .fsz-badge {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 2px 8px; border-radius: 20px;
    font-size: .71rem; font-weight: 600;
    font-family: 'DM Mono', monospace; white-space: nowrap;
  }
  .fsz-badge.exists {
    background: rgba(63,185,80,.1); border: 1px solid rgba(63,185,80,.2); color: var(--success);
  }
  .fsz-badge.missing {
    background: rgba(248,81,73,.08); border: 1px solid rgba(248,81,73,.2); color: var(--danger);
  }
  .fsz-badge.cleared {
    background: rgba(139,148,158,.08); border: 1px solid var(--border); color: var(--muted);
  }

  /* ── View button ── */
  .btn-row-action {
    padding: 4px 10px; border-radius: var(--radius-sm);
    font-size: .74rem; font-weight: 600;
    cursor: pointer; font-family: 'DM Sans', sans-serif;
    transition: all .15s;
    display: inline-flex; align-items: center; gap: 4px;
    border: none;
    white-space: nowrap;
  }
  .btn-row-action:disabled { opacity: .4; cursor: not-allowed; }
  .btn-view {
    background: rgba(88,166,255,.1);
    border: 1px solid rgba(88,166,255,.2);
    color: var(--accent);
    text-decoration: none;
  }
  .btn-view:hover:not(:disabled) { background: rgba(88,166,255,.2); }

  /* ── Delete dropdown ── */
  .delete-dropdown {
    position: relative;
    display: inline-block;
  }
  .btn-del-trigger {
    padding: 4px 10px; border-radius: var(--radius-sm);
    font-size: .74rem; font-weight: 600;
    cursor: pointer; font-family: 'DM Sans', sans-serif;
    transition: all .15s;
    display: inline-flex; align-items: center; gap: 5px;
    background: rgba(139,148,158,.1);
    border: 1px solid var(--border);
    color: var(--muted);
    white-space: nowrap;
  }
  .btn-del-trigger:hover { background: rgba(248,81,73,.08); color: var(--danger); border-color: rgba(248,81,73,.25); }
  .btn-del-trigger:disabled { opacity: .4; cursor: not-allowed; }
  .btn-del-trigger .chevron {
    font-size: .6rem;
    transition: transform .15s;
  }
  .delete-dropdown.open .btn-del-trigger .chevron {
    transform: rotate(180deg);
  }

  .del-menu {
    display: none;
    position: absolute;
    right: 0; top: calc(100% + 4px);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-lg);
    z-index: 200;
    min-width: 220px;
    overflow: hidden;
  }
  .delete-dropdown.open .del-menu { display: block; }

  .del-menu-item {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 10px 14px;
    cursor: pointer;
    transition: background .12s;
    border: none;
    background: none;
    width: 100%;
    text-align: left;
    font-family: 'DM Sans', sans-serif;
  }
  .del-menu-item:hover { background: var(--surface2); }
  .del-menu-item:disabled { opacity: .4; cursor: not-allowed; }
  .del-menu-item + .del-menu-item {
    border-top: 1px solid var(--border2);
  }
  .del-menu-icon { font-size: 1rem; flex-shrink: 0; margin-top: 1px; }
  .del-menu-text { display: flex; flex-direction: column; gap: 1px; }
  .del-menu-label {
    font-size: .79rem; font-weight: 600; color: var(--text);
    line-height: 1.2;
  }
  .del-menu-desc {
    font-size: .69rem; color: var(--muted); line-height: 1.3;
  }
  /* Disabled item */
  .del-menu-item.disabled,
  .del-menu-item:disabled {
    opacity: .4;
    cursor: not-allowed;
    pointer-events: none;
  }
  .del-menu-item.disabled .del-menu-label { color: var(--muted) !important; }

  /* Danger item */
  .del-menu-item.danger .del-menu-label { color: var(--danger); }
  .del-menu-item.danger:hover { background: rgba(248,81,73,.06); }
  /* Divider label */
  .del-menu-divider {
    font-size: .65rem; font-weight: 700;
    color: var(--muted2); text-transform: uppercase;
    letter-spacing: .6px; padding: 8px 14px 4px;
    border-top: 1px solid var(--border2);
  }

  /* ── Empty state ── */
  .empty-state {
    text-align: center; padding: 60px 20px; color: var(--muted);
  }
  .empty-state-icon { font-size: 2.5rem; margin-bottom: 12px; }
  .empty-state-title {
    font-family: 'Sora', sans-serif;
    font-size: 1rem; font-weight: 700; margin-bottom: 6px; color: var(--text);
  }
  .empty-state-sub { font-size: .85rem; }

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

  /* ── Pagination ── */
  .pagination {
    display: flex; align-items: center; justify-content: center; gap: 6px;
    margin-top: 16px; flex-wrap: wrap;
  }
  .page-btn {
    padding: 5px 11px; border-radius: var(--radius-sm);
    border: 1px solid var(--border); background: var(--surface);
    color: var(--text); font-size: .8rem; cursor: pointer;
    font-family: 'DM Sans', sans-serif; transition: all .15s;
  }
  .page-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
  .page-btn:disabled { opacity: .4; cursor: not-allowed; }
  .page-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
  .page-info { font-size: .78rem; color: var(--muted); padding: 0 6px; }

  /* ── Result badge ── */
  .result-badge {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 2px 8px; border-radius: 20px;
    font-size: .71rem; font-weight: 600;
    white-space: nowrap;
  }
  .result-badge.has-result {
    background: rgba(63,185,80,.1); border: 1px solid rgba(63,185,80,.2); color: var(--success);
  }
  .result-badge.no-result {
    background: rgba(139,148,158,.08); border: 1px solid var(--border); color: var(--muted);
  }
</style>
{% endblock %}

{% block content %}
<!-- Storage summary -->
<div class="storage-summary" id="storage-summary">
  <div class="storage-sum-card">
    <div class="sum-label">Total Task</div>
    <div class="sum-val" id="sum-total">—</div>
    <div class="sum-sub">semua transkripsi</div>
  </div>
  <div class="storage-sum-card">
    <div class="sum-label">Selesai</div>
    <div class="sum-val" id="sum-done" style="color:var(--success)">—</div>
    <div class="sum-sub">transkripsi berhasil</div>
  </div>
  <div class="storage-sum-card">
    <div class="sum-label">File Tersimpan</div>
    <div class="sum-val" id="sum-files">—</div>
    <div class="sum-sub" id="sum-size">di server</div>
  </div>
  <div class="storage-sum-card">
    <div class="sum-label">Durasi Total</div>
    <div class="sum-val" id="sum-duration">—</div>
    <div class="sum-sub">audio ditranskripsi</div>
  </div>
</div>

<!-- Toolbar -->
<div class="riwayat-toolbar">
  <select class="form-select" id="filter-status" style="max-width:160px" onchange="loadTasks()">
    <option value="">Semua Status</option>
    <option value="completed">✅ Selesai</option>
    <option value="processing">⚙️ Diproses</option>
    <option value="pending">⏳ Menunggu</option>
    <option value="failed">❌ Gagal</option>
    <option value="cancelled">🚫 Dibatalkan</option>
  </select>
  <button class="btn btn-ghost btn-sm" onclick="loadTasks(); loadSummary()">🔄 Refresh</button>
  <div class="riwayat-toolbar-right">
    <button class="btn btn-danger btn-sm" onclick="bulkDeleteMyCompletedFiles()">
      🗑 Hapus Semua File Audio (Selesai)
    </button>
  </div>
</div>

<!-- Table -->
<div class="card" style="margin-bottom:0">
  <div class="table-wrap">
    <table>
      <thead>
        <tr>
          <th>Task</th>
          <th>Status</th>
          <th>Engine / Model</th>
          <th>File Audio</th>
          <th>Hasil</th>
          <th>Durasi</th>
          <th>Dibuat</th>
          <th>Aksi</th>
        </tr>
      </thead>
      <tbody id="riwayat-tbody">
        <tr><td colspan="8" style="text-align:center;padding:40px;color:var(--muted)">Memuat...</td></tr>
      </tbody>
    </table>
  </div>
  <div style="padding:10px 14px;border-top:1px solid var(--border2);font-size:.76rem;color:var(--muted)"
       id="riwayat-info"></div>
</div>

<!-- Pagination -->
<div class="pagination" id="riwayat-pagination"></div>

<!-- Alert info -->
<div class="alert alert-info" style="margin-top:16px">
  <svg width="15" height="15" 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>
  <span>
    Tombol <strong>Hapus ▾</strong> memberi tiga pilihan:
    <strong>🎵 Audio saja</strong> — file audio dihapus, teks transkripsi tetap ada ·
    <strong>📄 Transkripsi saja</strong> — teks dihapus, file audio tetap ada di server ·
    <strong>🗑 Semua</strong> — task beserta semua datanya dihapus permanen.
  </span>
</div>

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

{% block scripts %}
<script>
  const LIMIT   = 15;
  let   currentOffset = 0;
  let   totalTasks    = 0;
  let   taskSummaryCache = [];

  // ── Toast ────────────────────────────────────────────────────────
  function showToast(msg, type = 'success') {
    const el = document.getElementById('riwayat-toast');
    el.textContent = msg;
    el.className   = `show ${type}`;
    clearTimeout(el._t);
    el._t = setTimeout(() => el.classList.remove('show'), 3500);
  }

  // ── Format helpers ───────────────────────────────────────────────
  function fmtDur(sec) {
    if (!sec) return '—';
    const m = Math.floor(sec / 60);
    const s = Math.round(sec % 60);
    return m > 0 ? `${m}m ${s}s` : `${s}s`;
  }
  function fmtDate(iso) {
    if (!iso) return '—';
    return new Date(iso).toLocaleDateString('id-ID', {
      day: '2-digit', month: 'short', year: 'numeric',
      hour: '2-digit', minute: '2-digit'
    });
  }
  function fmtMB(bytes) {
    if (!bytes) return '0 MB';
    return (bytes / (1024 * 1024)).toFixed(2) + ' MB';
  }

  // ── Summary ──────────────────────────────────────────────────────
  async function loadSummary() {
    try {
      const r = await fetch('/api/tasks?limit=500&offset=0');
      if (!r.ok) return;
      const d = await r.json();
      taskSummaryCache = d.tasks || [];

      const total    = d.total;
      const done     = taskSummaryCache.filter(t => t.status === 'completed').length;
      const withFile = taskSummaryCache.filter(t => t.file_exists).length;
      const totalDur = taskSummaryCache.reduce((acc, t) => acc + (t.audio_duration || 0), 0);

      document.getElementById('sum-total').textContent    = total.toLocaleString('id-ID');
      document.getElementById('sum-done').textContent     = done.toLocaleString('id-ID');
      document.getElementById('sum-files').textContent    = withFile.toLocaleString('id-ID');
      document.getElementById('sum-duration').textContent = fmtDur(totalDur);

      const totalBytes = taskSummaryCache.reduce((acc, t) => acc + (t.file_size_bytes || 0), 0);
      if (totalBytes > 0) {
        document.getElementById('sum-size').textContent = fmtMB(totalBytes) + ' di server';
      }
    } catch(e) { console.warn('[summary]', e); }
  }

  // ── Load tasks ───────────────────────────────────────────────────
  async function loadTasks() {
    const status = document.getElementById('filter-status').value;
    let url = `/api/tasks?limit=${LIMIT}&offset=${currentOffset}`;
    if (status) url += `&status=${status}`;

    const tbody = document.getElementById('riwayat-tbody');
    const info  = document.getElementById('riwayat-info');
    tbody.innerHTML = `<tr><td colspan="8" style="text-align:center;padding:40px;color:var(--muted)">Memuat...</td></tr>`;

    try {
      const r = await fetch(url);
      if (!r.ok) throw new Error('Gagal memuat riwayat.');
      const d = await r.json();
      totalTasks = d.total;

      if (!d.tasks.length) {
        tbody.innerHTML = `
          <tr><td colspan="8">
            <div class="empty-state">
              <div class="empty-state-icon">📭</div>
              <div class="empty-state-title">Belum Ada Riwayat</div>
              <div class="empty-state-sub">Mulai dengan mengupload file audio atau merekam suara.</div>
            </div>
          </td></tr>`;
        info.textContent = '';
        renderPagination();
        return;
      }

      tbody.innerHTML = d.tasks.map(task => {
        const isActive = ['pending', 'processing'].includes(task.status);

        // file_exists bisa true/false/undefined — kita tampilkan badge sesuai kondisi
        // tapi tombol hapus audio SELALU muncul; backend yang handle jika file sudah tidak ada
        const fileExists = task.file_exists;  // bisa undefined jika API tidak kirim field ini

        // Badge file audio
        const fileBadge = fileExists === true
          ? `<span class="fsz-badge exists">✓ Ada${task.file_size_bytes ? ' · ' + fmtMB(task.file_size_bytes) : ''}</span>`
          : fileExists === false
            ? `<span class="fsz-badge missing">✗ Terhapus</span>`
            : `<span style="color:var(--muted);font-size:.76rem">—</span>`;

        // Badge hasil transkripsi
        // has_result: boolean dari task_to_response(). Fallback: completed = ada hasil
        const hasResult    = task.has_result !== undefined ? task.has_result : (task.status === 'completed');
        const isCompleted  = task.status === 'completed';
        const resultBadge  = isCompleted
          ? (hasResult
              ? `<span class="result-badge has-result">✓ Ada</span>`
              : `<span class="result-badge no-result">✗ Dihapus</span>`)
          : `<span style="color:var(--muted);font-size:.76rem">—</span>`;

        const engineLabel = `${task.engine || '—'} / ${task.model_type || '—'}`;
        const courtBadge  = task.is_court_mode
          ? `<span style="font-size:.68rem;color:var(--muted);display:block;margin-top:2px">⚖️ Mode Sidang</span>`
          : '';

        // ── Dropdown hapus ────────────────────────────────────────
        // Semua tiga pilihan SELALU ditampilkan (kecuali pending/processing).
        // Logika disabled:
        //   - "Hapus Audio"        → disabled jika file_exists sudah false
        //   - "Hapus Transkripsi"  → disabled jika status bukan completed atau has_result false
        //   - "Hapus Semua"        → selalu aktif
        const audioDisabled  = fileExists === false;
        const resultDisabled = !isCompleted || !hasResult;

        const deleteDropdown = !isActive ? `
          <div class="delete-dropdown" id="dd-${task.id}">
            <button class="btn-del-trigger" onclick="toggleDropdown(${task.id}, event)">
              🗑 Hapus <span class="chevron">▾</span>
            </button>
            <div class="del-menu">

              <button class="del-menu-item ${audioDisabled ? 'disabled' : ''}"
                      ${audioDisabled ? 'disabled title="File audio sudah tidak ada di server"' : ''}
                      onclick="${audioDisabled ? '' : 'deleteAudio(' + task.id + '); closeAllDropdowns()'}">
                <span class="del-menu-icon">🎵</span>
                <span class="del-menu-text">
                  <span class="del-menu-label">Hapus Audio Saja</span>
                  <span class="del-menu-desc">${audioDisabled
                    ? 'File audio sudah tidak ada di server.'
                    : 'File audio dihapus dari server. Hasil transkripsi tetap tersimpan.'}</span>
                </span>
              </button>

              <button class="del-menu-item ${resultDisabled ? 'disabled' : ''}"
                      ${resultDisabled ? 'disabled title="Tidak ada hasil transkripsi yang bisa dihapus"' : ''}
                      onclick="${resultDisabled ? '' : 'deleteResult(' + task.id + '); closeAllDropdowns()'}">
                <span class="del-menu-icon">📄</span>
                <span class="del-menu-text">
                  <span class="del-menu-label">Hapus Transkripsi Saja</span>
                  <span class="del-menu-desc">${resultDisabled
                    ? 'Tidak ada hasil transkripsi untuk task ini.'
                    : 'Teks transkripsi dihapus. File audio tetap ada di server.'}</span>
                </span>
              </button>

              <div class="del-menu-divider">Hapus Permanen</div>
              <button class="del-menu-item danger"
                      onclick="deleteTask(${task.id}); closeAllDropdowns()">
                <span class="del-menu-icon">🗑</span>
                <span class="del-menu-text">
                  <span class="del-menu-label">Hapus Semua</span>
                  <span class="del-menu-desc">Task, audio, dan transkripsi dihapus permanen. Tidak bisa dibatalkan.</span>
                </span>
              </button>

            </div>
          </div>
        ` : `<span style="font-size:.72rem;color:var(--muted)">${task.status}</span>`;

        return `
          <tr id="task-row-${task.id}">
            <td>
              <a href="/transkripsi/status/${task.id}"
                 style="color:var(--accent);font-weight:600">#${task.id}</a>
            </td>
            <td>
              <span class="badge badge-${task.status}" style="font-size:.74rem">${task.status}</span>
            </td>
            <td style="font-size:.8rem;color:var(--muted)">${engineLabel}${courtBadge}</td>
            <td id="file-cell-${task.id}">${fileBadge}</td>
            <td id="result-cell-${task.id}">${resultBadge}</td>
            <td style="font-size:.82rem;color:var(--muted)">${fmtDur(task.audio_duration)}</td>
            <td style="font-size:.78rem;color:var(--muted)">${fmtDate(task.created_at)}</td>
            <td>
              <div style="display:flex;gap:4px;align-items:center;flex-wrap:wrap" id="action-cell-${task.id}">
                <a href="/transkripsi/status/${task.id}" class="btn-row-action btn-view">
                  👁 Lihat
                </a>
                ${deleteDropdown}
              </div>
            </td>
          </tr>
        `;
      }).join('');

      const start = currentOffset + 1;
      const end   = Math.min(currentOffset + d.tasks.length, totalTasks);
      info.textContent = `Menampilkan ${start}–${end} dari ${totalTasks} riwayat.`;
      renderPagination();

    } catch(e) {
      tbody.innerHTML = `<tr><td colspan="8" style="text-align:center;padding:32px;color:var(--danger)">${e.message}</td></tr>`;
    }
  }

  // ── Dropdown open/close ──────────────────────────────────────────
  function toggleDropdown(taskId, event) {
    event.stopPropagation();
    const dd = document.getElementById(`dd-${taskId}`);
    const wasOpen = dd.classList.contains('open');
    closeAllDropdowns();
    if (!wasOpen) dd.classList.add('open');
  }

  function closeAllDropdowns() {
    document.querySelectorAll('.delete-dropdown.open').forEach(el => el.classList.remove('open'));
  }

  // Tutup dropdown jika klik di luar
  document.addEventListener('click', closeAllDropdowns);

  // ── Pagination ───────────────────────────────────────────────────
  function renderPagination() {
    const container = document.getElementById('riwayat-pagination');
    const pages     = Math.ceil(totalTasks / LIMIT);
    const current   = Math.floor(currentOffset / LIMIT);
    if (pages <= 1) { container.innerHTML = ''; return; }

    let html = `
      <button class="page-btn" onclick="goPage(0)" ${current === 0 ? 'disabled' : ''}>«</button>
      <button class="page-btn" onclick="goPage(${current - 1})" ${current === 0 ? 'disabled' : ''}>‹</button>
    `;
    const start = Math.max(0, current - 2);
    const end   = Math.min(pages, start + 5);
    for (let i = start; i < end; i++) {
      html += `<button class="page-btn ${i === current ? 'active' : ''}" onclick="goPage(${i})">${i + 1}</button>`;
    }
    html += `
      <button class="page-btn" onclick="goPage(${current + 1})" ${current >= pages - 1 ? 'disabled' : ''}>›</button>
      <button class="page-btn" onclick="goPage(${pages - 1})" ${current >= pages - 1 ? 'disabled' : ''}>»</button>
      <span class="page-info">Hal. ${current + 1} / ${pages}</span>
    `;
    container.innerHTML = html;
  }

  function goPage(page) {
    currentOffset = page * LIMIT;
    loadTasks();
    window.scrollTo({ top: 0, behavior: 'smooth' });
  }

  // ── 1. Hapus audio saja ──────────────────────────────────────────
  // DELETE /api/transkripsi/{task_id}/audio
  // File audio dihapus dari server. Record task & hasil transkripsi TETAP.
  async function deleteAudio(taskId) {
    if (!confirm(
      `Hapus file audio Task #${taskId}?\n\n` +
      `✅ Hasil transkripsi TETAP tersimpan.\n` +
      `❌ File audio di server akan dihapus.\n\n` +
      `Tindakan ini tidak bisa dibatalkan.`
    )) return;

    const btn = document.querySelector(`#dd-${taskId} .btn-del-trigger`);
    if (btn) { btn.disabled = true; btn.textContent = '⏳'; }

    try {
      const r = await fetch(`/api/transkripsi/${taskId}/audio`, { method: 'DELETE' });
      const d = await r.json();
      if (!r.ok) throw new Error(d.detail || 'Gagal menghapus file audio.');

      showToast('✅ File audio dihapus. Hasil transkripsi tetap tersimpan.', 'success');

      // Update badge file → "Terhapus"
      const fileCell = document.getElementById(`file-cell-${taskId}`);
      if (fileCell) fileCell.innerHTML = `<span class="fsz-badge missing">✗ Terhapus</span>`;

      // Rebuild dropdown: "Hapus Audio" tidak relevan lagi
      _rebuildDropdown(taskId, { hasFile: false, hasResult: true });

      loadSummary();
    } catch(e) {
      showToast('❌ ' + e.message, 'error');
      if (btn) { btn.disabled = false; btn.innerHTML = '🗑 Hapus <span class="chevron">▾</span>'; }
    }
  }

  // ── 2. Hapus transkripsi saja ────────────────────────────────────
  // DELETE /api/transkripsi/{task_id}/result
  // Teks hasil transkripsi dihapus. File audio & record task TETAP.
  async function deleteResult(taskId) {
    if (!confirm(
      `Hapus hasil transkripsi Task #${taskId}?\n\n` +
      `✅ File audio TETAP tersimpan di server.\n` +
      `❌ Teks hasil transkripsi akan dihapus permanen.\n\n` +
      `Tindakan ini tidak bisa dibatalkan.`
    )) return;

    const btn = document.querySelector(`#dd-${taskId} .btn-del-trigger`);
    if (btn) { btn.disabled = true; btn.textContent = '⏳'; }

    try {
      const r = await fetch(`/api/transkripsi/${taskId}/result`, { method: 'DELETE' });
      const d = await r.json();
      if (!r.ok) throw new Error(d.detail || 'Gagal menghapus hasil transkripsi.');

      showToast('✅ Hasil transkripsi dihapus. File audio tetap tersimpan.', 'success');

      // Update badge hasil → "Dihapus"
      const resultCell = document.getElementById(`result-cell-${taskId}`);
      if (resultCell) resultCell.innerHTML = `<span class="result-badge no-result">✗ Dihapus</span>`;

      // Rebuild dropdown: "Hapus Transkripsi" tidak relevan lagi
      const currentFileExists = !!document.querySelector(`#file-cell-${taskId} .fsz-badge.exists`);
      _rebuildDropdown(taskId, { hasFile: currentFileExists, hasResult: false });

      loadSummary();
    } catch(e) {
      showToast('❌ ' + e.message, 'error');
      if (btn) { btn.disabled = false; btn.innerHTML = '🗑 Hapus <span class="chevron">▾</span>'; }
    }
  }

  // ── 3. Hapus semua (task + audio + hasil) ───────────────────────
  // DELETE /api/transkripsi/{task_id}
  async function deleteTask(taskId) {
    if (!confirm(
      `Hapus Task #${taskId} secara permanen?\n\n` +
      `❌ File audio DAN hasil transkripsi KEDUANYA akan dihapus.\n` +
      `Tindakan ini tidak bisa dibatalkan.`
    )) return;

    const btn = document.querySelector(`#dd-${taskId} .btn-del-trigger`);
    if (btn) { btn.disabled = true; btn.textContent = '⏳'; }

    try {
      const r = await fetch(`/api/transkripsi/${taskId}`, { method: 'DELETE' });
      const d = await r.json();
      if (!r.ok) throw new Error(d.detail || 'Gagal menghapus task.');

      showToast('✅ Task berhasil dihapus.', 'success');

      const row = document.getElementById(`task-row-${taskId}`);
      if (row) {
        row.style.transition = 'opacity .3s';
        row.style.opacity    = '0';
        setTimeout(() => {
          row.remove();
          const tbody = document.getElementById('riwayat-tbody');
          if (!tbody.querySelector('tr[id^="task-row-"]')) loadTasks();
        }, 300);
      }

      loadSummary();
    } catch(e) {
      showToast('❌ ' + e.message, 'error');
      if (btn) { btn.disabled = false; btn.innerHTML = '🗑 Hapus <span class="chevron">▾</span>'; }
    }
  }

  // ── Helper: rebuild isi dropdown setelah aksi parsial ───────────
  // Supaya item yang sudah tidak relevan menghilang tanpa full reload.
  function _rebuildDropdown(taskId, { hasFile, hasResult }) {
    const menu = document.querySelector(`#dd-${taskId} .del-menu`);
    if (!menu) return;

    // Aktifkan kembali trigger
    const btn = document.querySelector(`#dd-${taskId} .btn-del-trigger`);
    if (btn) { btn.disabled = false; btn.innerHTML = '🗑 Hapus <span class="chevron">▾</span>'; }

    // Jika tidak ada lagi yang bisa dihapus parsial, ganti isi menu
    const audioItem = hasFile ? `
      <button class="del-menu-item"
              onclick="deleteAudio(${taskId}); closeAllDropdowns()">
        <span class="del-menu-icon">🎵</span>
        <span class="del-menu-text">
          <span class="del-menu-label">Hapus Audio Saja</span>
          <span class="del-menu-desc">File audio dihapus, transkripsi tetap.</span>
        </span>
      </button>` : '';

    const resultItem = hasResult ? `
      <button class="del-menu-item"
              onclick="deleteResult(${taskId}); closeAllDropdowns()">
        <span class="del-menu-icon">📄</span>
        <span class="del-menu-text">
          <span class="del-menu-label">Hapus Transkripsi Saja</span>
          <span class="del-menu-desc">Teks dihapus, file audio tetap ada.</span>
        </span>
      </button>` : '';

    menu.innerHTML = `
      ${audioItem}
      ${resultItem}
      <div class="del-menu-divider">Hapus Permanen</div>
      <button class="del-menu-item danger"
              onclick="deleteTask(${taskId}); closeAllDropdowns()">
        <span class="del-menu-icon">🗑</span>
        <span class="del-menu-text">
          <span class="del-menu-label">Hapus Semua</span>
          <span class="del-menu-desc">Task, audio, dan transkripsi dihapus permanen.</span>
        </span>
      </button>
    `;
  }

  // ── Bulk: hapus semua file audio task selesai ────────────────────
  async function bulkDeleteMyCompletedFiles() {
    if (!confirm(
      'Hapus semua file audio dari task yang sudah selesai?\n\n' +
      '✅ Hasil transkripsi TETAP tersimpan.\n' +
      '❌ File audio di server akan dihapus.\n\n' +
      'Tindakan ini tidak bisa dibatalkan!'
    )) return;

    try {
      const r = await fetch('/api/tasks?limit=200&status=completed');
      if (!r.ok) throw new Error('Gagal mengambil daftar task.');
      const d = await r.json();
      const tasksWithFile = (d.tasks || []).filter(t => t.file_exists);

      if (!tasksWithFile.length) {
        showToast('Tidak ada file audio yang perlu dihapus.', 'success');
        return;
      }

      let deleted = 0;
      let failed  = 0;

      for (const task of tasksWithFile) {
        try {
          const rd = await fetch(`/api/transkripsi/${task.id}/audio`, { method: 'DELETE' });
          if (rd.ok) deleted++;
          else       failed++;
        } catch { failed++; }
      }

      if (deleted > 0) {
        showToast(
          `✅ ${deleted} file audio berhasil dihapus${failed > 0 ? ' (' + failed + ' gagal)' : ''}. Hasil transkripsi tetap tersimpan.`,
          'success'
        );
      } else {
        showToast('❌ Semua penghapusan gagal.', 'error');
      }

      loadTasks();
      loadSummary();

    } catch(e) { showToast('❌ ' + e.message, 'error'); }
  }

  // ── Init ─────────────────────────────────────────────────────────
  loadSummary();
  loadTasks();
</script>
{% endblock %}