{% extends "ewoooc_base.html" %}

{% block title %}PPT 視覺 QA 產線{% endblock %}

{% block extra_css %}
  <link rel="stylesheet" href="{{ url_for('static', filename='css/page-ppt-audit-history.css') }}">
{% endblock %}

{% block ewooo_content %}
{% import "admin/_observability_labels.html" as obs_label %}

<div class="container-fluid mt-3">
  <section class="ppt-hero">
    <div class="ppt-hero-grid">
      <div class="ppt-hero-copy">
        <div class="ppt-kicker"><i class="fas fa-search me-1"></i> PPT 視覺 QA 產線 · {{ report_month }} · {{ selected_report_type.label }}</div>
        <h1 class="ppt-title">{{ operator_summary.headline }}</h1>
        <p class="ppt-subtitle">{{ operator_summary.message }}</p>
        {% if operator_summary.blocker_text %}
        <p class="ppt-hero-note"><i class="fas fa-circle-info me-1" aria-hidden="true"></i>{{ operator_summary.blocker_text }}</p>
        {% endif %}
        <div class="ppt-hero-actions">
          <a class="btn btn-primary btn-sm" href="{{ operator_summary.primary_anchor }}">{{ operator_summary.primary_action }}</a>
          <a class="btn btn-outline-primary btn-sm" href="#ppt-production-center">定期產出矩陣</a>
          {% if operator_summary.latest_deck.name %}
          <a class="btn btn-outline-secondary btn-sm"
             href="{{ url_for('admin_observability.ppt_audit_file', filename=operator_summary.latest_deck.name) }}"
             target="_blank"
             rel="noopener"
             data-ppt-open-preview
             data-ppt-filename="{{ operator_summary.latest_deck.name }}"
             data-ppt-preview-title="最新簡報 · {{ operator_summary.latest_deck.name }}"
             data-ppt-preview-pdf="{{ url_for('admin_observability.ppt_audit_file', filename=operator_summary.latest_deck.name, action='pdf') }}"
             data-ppt-preview-page="{{ url_for('admin_observability.ppt_audit_file', filename=operator_summary.latest_deck.name) }}"
             data-ppt-download-url="{{ url_for('admin_observability.ppt_audit_file', filename=operator_summary.latest_deck.name, action='download') }}">
            <i class="fas fa-eye me-1"></i>預覽最新
          </a>
          {% endif %}
        </div>
      </div>
      <aside class="ppt-hero-deck is-{{ operator_summary.status }}" aria-label="最新簡報狀態">
        <div class="ppt-label">Latest Deck</div>
        <strong>{{ operator_summary.latest_deck_label }}</strong>
        <small>{{ operator_summary.latest_deck_meta }}</small>
        <div class="ppt-hero-deck-run">
          <span>{{ operator_summary.latest_run_label }}</span>
          <small>{{ operator_summary.latest_run_meta }}</small>
        </div>
      </aside>
    </div>
  </section>
  <section class="ppt-command ppt-command--compact" aria-label="PPT 產線關鍵狀態">
    {% for signal in operator_summary.signals %}
    <div class="ppt-signal is-{{ signal.status }}">
      <div class="ppt-label">{{ signal.label }}</div>
      <span class="ppt-value">{{ signal.value }}</span>
      <small class="text-muted">{{ signal.meta }}</small>
    </div>
    {% endfor %}
  </section>
  {% if not vision_status.ready %}
  <section class="ppt-diagnostic-strip" id="ppt-runtime-diagnostic">
    <div>
      <div class="ppt-label">視覺 QA 尚未就緒</div>
      <strong>目前不是模型能力問題，而是執行環境尚未完整開啟。</strong>
      <small class="text-muted">{{ vision_status.summary }}</small>
    </div>
    <div class="ppt-diagnostic-checks" aria-label="視覺 QA runtime checklist">
      {% for check in vision_status.readiness_checks %}
      <div class="ppt-diagnostic-check is-{{ check.status }}">
        <span>{{ check.label }}</span>
        <strong>{{ check.value }}</strong>
        <small>{{ check.detail }}</small>
      </div>
      {% endfor %}
    </div>
    <div class="ppt-diagnostic-actions">
      <span class="ppt-run-status is-planned">{{ vision_status.ready_count }}/{{ vision_status.check_count }} 通過</span>
      {% for action in vision_status.next_actions %}
      <small>{{ action }}</small>
      {% endfor %}
      {% if vision_status.blockers %}
      <small class="text-muted">阻擋：{{ vision_status.blockers|join('；') }}</small>
      {% endif %}
    </div>
  </section>
  {% endif %}
  {% if error %}<div class="alert alert-warning mt-3"><strong><i class="fas fa-triangle-exclamation me-1"></i></strong>{{ error }}</div>{% endif %}

  <section class="ppt-aider-status{% if not aider_heal_active_count %} is-empty{% endif %}" data-ppt-aider-status aria-live="polite">
    <div class="ppt-aider-status-main">
      <span class="ppt-run-status is-planned"><i class="fas fa-wrench me-1" aria-hidden="true"></i>AiderHeal</span>
      <div>
        <strong data-ppt-aider-status-title>{% if aider_heal_active_count %}AiderHeal 執行中 · {{ aider_heal_active_count }}{% else %}AiderHeal 待命{% endif %}</strong>
        <small data-ppt-aider-status-meta>{% if aider_heal_active_count %}修復完成後會由 Telegram/Gitea/CD 回報。{% else %}有問題的審核紀錄可直接一鍵派工。{% endif %}</small>
      </div>
    </div>
    <div class="ppt-aider-job-list" data-ppt-aider-job-list>
      {% for job in aider_heal_active_jobs[:3] %}
      <div class="ppt-aider-job">
        <code>{{ job.pptx_filename or 'manual' }}</code>
        <span>{{ job.queued_at }}</span>
        <small>{{ job.diagnosis }}</small>
      </div>
      {% endfor %}
    </div>
  </section>

  <section class="ppt-vision-status is-{{ vision_audit_status.status }}" data-ppt-vision-status aria-live="polite">
    <div class="ppt-vision-status-main">
      <span class="ppt-run-status is-{{ 'ready' if vision_audit_status.status == 'completed' else 'planned' if vision_audit_status.status in ['idle', 'queued', 'running'] else 'error' }}">
        <i class="fas fa-eye me-1" aria-hidden="true"></i>Vision QA
      </span>
      <div>
        <strong data-ppt-vision-status-title>{{ vision_audit_status.status_label }}</strong>
        <small data-ppt-vision-status-meta>{{ vision_audit_status.message }}</small>
      </div>
    </div>
    <div class="ppt-vision-status-list" data-ppt-vision-status-list>
      <div class="ppt-vision-job is-runtime">
        <span>Runtime</span>
        <strong>{{ vision_status.status_label }}</strong>
        <small>{{ vision_status.model }} · {{ vision_status.converter or '無轉檔器' }}</small>
      </div>
      {% if vision_audit_status.last_run %}
      <div class="ppt-vision-job">
        <span>{{ vision_audit_status.last_run.finished_at or vision_audit_status.last_run.started_at or vision_audit_status.last_run.queued_at }}</span>
        <strong>{{ vision_audit_status.last_run.summary.audited_count }} 份 / {{ vision_audit_status.last_run.summary.total_issues }} 問題</strong>
        <small>{% if vision_audit_status.last_run.summary.error_count %}執行錯誤 {{ vision_audit_status.last_run.summary.error_count }}{% else %}無執行錯誤{% endif %}</small>
      </div>
      {% else %}
      <div class="ppt-vision-job">
        <span>尚無紀錄</span>
        <strong>待命</strong>
        <small>按下「立即視覺 QA」後會在這裡顯示背景任務狀態。</small>
      </div>
      {% endif %}
    </div>
  </section>

  <section class="ppt-toolbar">
    <div class="d-flex align-items-center gap-2">
      <a class="btn btn-sm btn-outline-secondary" href="{{ url_for('admin_observability.ppt_audit_history', month=prev_month_label, report_type=report_type) }}">
        <i class="fas fa-angle-left me-1"></i>上個月
      </a>
      <span class="badge bg-light text-dark border py-2 px-3">{{ report_month }}</span>
      {% if show_next_month %}
        <a class="btn btn-sm btn-outline-secondary" href="{{ url_for('admin_observability.ppt_audit_history', month=next_month_label, report_type=report_type) }}">
          下個月<i class="fas fa-angle-right ms-1"></i>
        </a>
      {% else %}
        <button class="btn btn-sm btn-outline-secondary" type="button" disabled>下個月<i class="fas fa-angle-right ms-1"></i></button>
      {% endif %}
    </div>
    <div class="ppt-type-tabs">
      {% for opt in report_type_options %}
        <a class="btn btn-sm {% if report_type == opt.key %}btn-primary{% else %}btn-outline-primary{% endif %} ppt-type-chip" href="{{ url_for('admin_observability.ppt_audit_history', month=report_month, report_type=opt.key) }}">
          {{ opt.label }}
        </a>
      {% endfor %}
    </div>
  </section>
  <section class="ppt-deck-workbench" id="ppt-deck-workbench" aria-label="最近可預覽簡報">
    <div class="ppt-workbench-head">
      <div>
        <div class="ppt-label">Preview Workbench</div>
        <h2 class="ppt-panel-title">最近可預覽簡報</h2>
      </div>
      <div class="ppt-workbench-actions">
        <small class="text-muted">最新 {{ files[:4]|length }} 份，直接線上預覽或下載原始 PPTX</small>
        <button class="btn btn-outline-primary btn-sm" type="button" data-ppt-run-vision {% if not vision_status.ready or not vision_audit_filenames %}disabled{% endif %}>
          <i class="fas fa-eye me-1"></i>立即視覺 QA
        </button>
        {% if pipeline_view.uncached_preview_count > 0 %}
        <button class="btn btn-outline-primary btn-sm" type="button" data-ppt-prewarm-all>
          <i class="fas fa-fire me-1"></i>預熱本頁 PDF
          <span class="badge bg-light text-dark border ms-1" data-ppt-prewarm-count>{{ pipeline_view.uncached_preview_count }}</span>
        </button>
        {% endif %}
      </div>
    </div>
    {% if files %}
    <div class="ppt-deck-rail">
      {% for f in files[:4] %}
      <article class="ppt-deck-card {% if not f.file_exists or not f.is_valid_ppt %}is-disabled{% endif %}">
        <div class="ppt-deck-meta">
          <span class="ppt-label">{{ selected_report_type.label }}</span>
          <span>{{ f.mtime }}</span>
        </div>
        <h3>{{ f.name }}</h3>
        <div class="ppt-deck-facts">
          <span>{{ f.size_kb if f.size_kb is not none else '—' }} KB</span>
          <span>{{ f.source }}</span>
          {% if f.file_exists and f.is_valid_ppt %}<span class="status-good">可預覽</span>{% else %}<span class="status-bad">需回補</span>{% endif %}
          {% if f.file_exists and f.is_valid_ppt %}
            {% if f.preview_cache_ready %}<span class="status-blue" data-ppt-preview-state="{{ f.name }}">PDF 快取</span>{% else %}<span class="status-warn" data-ppt-preview-state="{{ f.name }}">首次轉檔</span>{% endif %}
          {% endif %}
        </div>
        <div class="ppt-file-actions">
          {% if f.file_exists and f.is_valid_ppt %}
          <a class="btn btn-outline-primary btn-sm"
             href="{{ url_for('admin_observability.ppt_audit_file', filename=f.name) }}"
             target="_blank"
             rel="noopener"
             data-ppt-open-preview
             data-ppt-filename="{{ f.name }}"
             data-ppt-preview-title="{{ selected_report_type.label }} · {{ f.name }}"
             data-ppt-preview-pdf="{{ url_for('admin_observability.ppt_audit_file', filename=f.name, action='pdf') }}"
             data-ppt-preview-page="{{ url_for('admin_observability.ppt_audit_file', filename=f.name) }}"
             data-ppt-download-url="{{ url_for('admin_observability.ppt_audit_file', filename=f.name, action='download') }}">
            <i class="fas fa-eye me-1"></i>線上預覽
          </a>
          {% if not f.preview_cache_ready %}
          <button class="btn btn-outline-primary btn-sm" type="button" data-ppt-prewarm-preview data-ppt-filename="{{ f.name }}">
            <i class="fas fa-fire me-1"></i>預熱 PDF
          </button>
          {% endif %}
          {% endif %}
          {% if f.file_exists %}
          <a class="btn btn-outline-secondary btn-sm" href="{{ url_for('admin_observability.ppt_audit_file', filename=f.name, action='download') }}">
            <i class="fas fa-download me-1"></i>下載
          </a>
          {% endif %}
        </div>
      </article>
      {% endfor %}
    </div>
    {% else %}
    <div class="ppt-empty ppt-deck-empty">
      目前沒有符合 {{ report_month }} / {{ selected_report_type.label }} 的簡報檔案；可先切換報表類型，或在下方補齊定義簡報。
    </div>
    {% endif %}
  </section>
  <section class="ppt-health-board" aria-label="PPT 產線健康總覽">
    <div class="ppt-health-main is-{{ pipeline_view.status }}">
      <div class="ppt-label">Pipeline Health</div>
      <h2>{{ pipeline_view.title }}</h2>
      <p>{{ pipeline_view.message }}</p>
      <div class="ppt-health-facts">
        <span><strong>{{ pipeline_view.ready_count }}/{{ pipeline_view.total_count }}</strong> 定義覆蓋</span>
        <span><strong>{{ pipeline_view.valid_preview_count }}</strong> 份可預覽</span>
        <span><strong>{{ pipeline_view.cached_preview_count }}</strong> 份 PDF 快取</span>
        <span><strong>{{ pipeline_view.audit_total }}</strong> 筆視覺 QA</span>
      </div>
    </div>
    <div class="ppt-stage-grid">
      {% for stage in pipeline_view.stages %}
      <article class="ppt-stage-card is-{{ stage.status }}">
        <div class="ppt-stage-icon"><i class="fas fa-{{ stage.icon }}" aria-hidden="true"></i></div>
        <div>
          <div class="ppt-label">{{ stage.label }}</div>
          <strong>{{ stage.value }}</strong>
          <small>{{ stage.meta }}</small>
          <p>{{ stage.detail }}</p>
        </div>
      </article>
      {% endfor %}
    </div>
  </section>
  <section class="ppt-action-queue" id="ppt-action-queue" data-ppt-action-queue aria-label="PPT 工作隊列">
    <div class="ppt-workbench-head">
      <div>
        <div class="ppt-label">Action Queue</div>
        <h2 class="ppt-panel-title">接下來要處理的事</h2>
      </div>
      <small class="text-muted">把缺漏、預覽、視覺 QA、DB 寫入集中成工作隊列</small>
    </div>
    <div class="ppt-action-grid">
      {% for lane in pipeline_view.action_lanes %}
      <article class="ppt-action-lane is-{{ lane.status }}">
        <div class="ppt-action-lane-head">
          <span class="ppt-label">{{ lane.label }}</span>
          <strong>{{ lane.count }}</strong>
        </div>
        <div class="ppt-action-list">
          {% for item in lane.entries %}
          <div class="ppt-action-item">
            <div>
              <strong>{{ item.title }}</strong>
              <small>{{ item.meta }}</small>
              <p>{{ item.detail }}</p>
            </div>
            <div class="ppt-action-foot">
              <span class="ppt-run-status is-{{ lane.status }}">{{ item.status_label }}</span>
              {% if item.filename and lane.key in ['preview', 'database', 'triage', 'audit'] %}
              <a class="btn btn-outline-primary btn-sm"
                 href="{{ url_for('admin_observability.ppt_audit_file', filename=item.filename) }}"
                 target="_blank"
                 rel="noopener"
                 data-ppt-open-preview
                 data-ppt-filename="{{ item.filename }}"
                 data-ppt-preview-title="{{ item.title }} · {{ item.filename }}"
                 data-ppt-preview-pdf="{{ url_for('admin_observability.ppt_audit_file', filename=item.filename, action='pdf') }}"
                 data-ppt-preview-page="{{ url_for('admin_observability.ppt_audit_file', filename=item.filename) }}"
                 data-ppt-download-url="{{ url_for('admin_observability.ppt_audit_file', filename=item.filename, action='download') }}">
                <i class="fas fa-eye me-1"></i>預覽
              </a>
              {% endif %}
              {% if item.can_regenerate %}
              <button class="btn btn-outline-warning btn-sm" type="button" data-ppt-generate-one data-report-type="{{ item.report_type }}" data-report-label="{{ item.title }}">
                <i class="fas fa-rotate me-1"></i>重跑
              </button>
              {% endif %}
            </div>
          </div>
          {% else %}
          <div class="ppt-action-empty">{{ lane.empty_text }}</div>
          {% endfor %}
        </div>
      </article>
      {% endfor %}
    </div>
  </section>
  {% if issue_items %}
  <section class="ppt-issue-board" id="ppt-issue-board" aria-label="視覺問題追蹤">
    <div class="ppt-workbench-head">
      <div>
        <div class="ppt-label">Vision Findings</div>
        <h2 class="ppt-panel-title">視覺問題追蹤</h2>
      </div>
      <div class="ppt-issue-metrics">
        <span><strong>{{ issue_digest.total }}</strong> 問題</span>
        <span><strong>{{ issue_digest.files }}</strong> 檔案</span>
        <span><strong>{{ issue_digest.error_count }}</strong> 高優先</span>
        <span><strong>{{ issue_digest.latest_audit or '—' }}</strong> 最近審核</span>
      </div>
    </div>
    <div class="ppt-issue-grid">
      {% for issue in issue_items[:8] %}
      <article class="ppt-issue-card is-{{ issue.status }}">
        <div class="ppt-issue-top">
          <span class="ppt-run-status is-{{ 'error' if issue.status == 'error' else 'planned' }}">{{ issue.slide_label }}</span>
          <span class="ppt-label">{{ issue.category }}</span>
        </div>
        <strong><code>{{ issue.pptx_filename }}</code></strong>
        <p>{{ issue.text }}</p>
        <div class="ppt-action-foot">
          <small class="text-muted">{{ issue.audited_at }}</small>
          <a class="btn btn-outline-primary btn-sm"
             href="{{ url_for('admin_observability.ppt_audit_file', filename=issue.pptx_filename) }}"
             target="_blank"
             rel="noopener"
             data-ppt-open-preview
             data-ppt-filename="{{ issue.pptx_filename }}"
             data-ppt-preview-title="問題回放 · {{ issue.pptx_filename }}"
             data-ppt-preview-pdf="{{ url_for('admin_observability.ppt_audit_file', filename=issue.pptx_filename, action='pdf') }}"
             data-ppt-preview-page="{{ url_for('admin_observability.ppt_audit_file', filename=issue.pptx_filename) }}"
             data-ppt-download-url="{{ url_for('admin_observability.ppt_audit_file', filename=issue.pptx_filename, action='download') }}">
            <i class="fas fa-eye me-1"></i>回放
          </a>
        </div>
        {% if issue.report_type %}
        <div class="ppt-action-foot">
          <button class="btn btn-outline-warning btn-sm" type="button" data-ppt-generate-one data-report-type="{{ issue.report_type }}" data-report-label="{{ issue.pptx_filename }}">
            <i class="fas fa-rotate me-1"></i>重跑同類簡報
          </button>
        </div>
        {% endif %}
      </article>
      {% endfor %}
    </div>
  </section>
  {% endif %}
  <section class="ppt-panel mt-3"
           id="ppt-production-center"
           data-ppt-auto-generation
           data-auto-start="{{ 'true' if auto_generation.can_auto_start else 'false' }}"
           data-report-types="{{ auto_generation_missing_report_types | join(',') }}">
    <div class="ppt-panel-head">
      <div>
        <div class="ppt-label">Production Command Center</div>
        <h2 class="ppt-panel-title">簡報產線控制台</h2>
      </div>
      <div class="ppt-panel-actions">
        <button class="btn btn-sm btn-outline-primary" type="button" data-ppt-run-vision {% if not vision_status.ready or not vision_audit_filenames %}disabled{% endif %}>
          <i class="fas fa-eye me-1" aria-hidden="true"></i>立即視覺 QA
        </button>
        <button class="btn btn-sm btn-outline-primary" type="button" data-ppt-generate-missing {% if not auto_generation.enabled or auto_generation.missing_count == 0 %}disabled{% endif %}>
          <i class="fas fa-wand-magic-sparkles me-1" aria-hidden="true"></i>補齊缺漏簡報
        </button>
      </div>
    </div>
    <div class="ppt-panel-body">
      <div class="ppt-pipeline-layout">
        <div class="ppt-cadence-rail" aria-label="PPT 定期產出節奏">
          {% for cadence in auto_generation.cadences %}
          <article class="ppt-cadence-tile is-{{ cadence.status }}">
            <div class="ppt-cadence-top">
              <span class="ppt-label">{{ cadence.label }}</span>
              <strong>{{ cadence.schedule_text }}</strong>
            </div>
            <div class="ppt-cadence-meter" aria-hidden="true">
              <span style="width: {{ cadence.progress_pct }}%"></span>
            </div>
            <div class="ppt-cadence-meta">
              <span>{{ cadence.status_label }}</span>
              <span>{{ cadence.coverage_text }}</span>
            </div>
            <p class="ppt-cadence-gate">{{ cadence.description }}</p>
            {% if cadence.missing_count > 0 %}
            <small class="text-muted">待補：{{ cadence.missing_report_labels[:3]|join('、') }}{% if cadence.missing_report_labels|length > 3 %} 等 {{ cadence.missing_report_labels|length }} 類{% endif %}</small>
            {% else %}
            <small class="status-good">{{ cadence.status_hint }}</small>
            {% endif %}
          </article>
          {% endfor %}
        </div>
        <div class="ppt-coverage-board">
          <div class="ppt-coverage-score">
            <div>
              <span class="ppt-label">定義簡報</span>
              <strong>{{ auto_generation.ready_count }}/{{ auto_generation.total }}</strong>
              <small class="text-muted">目前缺漏 {{ auto_generation.missing_count }} 類</small>
            </div>
            <div>
              <span class="ppt-label">DB 紀錄</span>
              <strong>{{ generation_runs|length }}</strong>
              <small class="text-muted">本月最近寫入</small>
            </div>
            <div>
              <span class="ppt-label">線上預覽</span>
              <strong>PDF</strong>
              <small class="text-muted">PPTX 轉檔快取</small>
            </div>
          </div>
          <div class="ppt-coverage-list" aria-label="定義簡報覆蓋明細">
            <div class="ppt-coverage-list-head">
              <span class="ppt-label">報表覆蓋矩陣</span>
              <small>DB / 預覽 / 視覺 QA / 交付</small>
            </div>
            {% for item in auto_generation_items %}
            <div class="ppt-coverage-row is-{{ item.delivery_status }}">
              <div class="ppt-coverage-main">
                <strong>{{ item.label }}</strong>
                <small>{{ item.target_label or '最新資料' }}{% if item.latest_file_mtime %} · {{ item.latest_file_mtime }}{% endif %}</small>
                {% if item.latest_file_name %}
                <small><code>{{ item.latest_file_name }}</code></small>
                {% else %}
                <small>{{ item.status_hint }}</small>
                {% endif %}
                {% if item.audit_summary %}
                <small>{{ item.audit_summary[:90] }}</small>
                {% endif %}
              </div>
              <div class="ppt-coverage-signals">
                <span class="ppt-run-status is-{{ item.db_status }}">{{ item.db_label }}</span>
                <span class="ppt-run-status is-{{ item.preview_status }}">{{ item.preview_label }}</span>
                <span class="ppt-run-status is-{{ item.qa_status }}">{{ item.qa_label }}</span>
                <span class="ppt-run-status is-{{ item.delivery_status }}">{{ item.delivery_label }}</span>
              </div>
              <div class="ppt-coverage-actions">
                {% if item.can_preview %}
                <a class="btn btn-outline-primary btn-sm"
                   href="{{ url_for('admin_observability.ppt_audit_file', filename=item.latest_file_name) }}"
                   target="_blank"
                   rel="noopener"
                   data-ppt-open-preview
                   data-ppt-filename="{{ item.latest_file_name }}"
                   data-ppt-preview-title="{{ item.label }} · {{ item.latest_file_name }}"
                   data-ppt-preview-pdf="{{ url_for('admin_observability.ppt_audit_file', filename=item.latest_file_name, action='pdf') }}"
                   data-ppt-preview-page="{{ url_for('admin_observability.ppt_audit_file', filename=item.latest_file_name) }}"
                   data-ppt-download-url="{{ url_for('admin_observability.ppt_audit_file', filename=item.latest_file_name, action='download') }}">
                  <i class="fas fa-eye me-1"></i>預覽
                </a>
                {% endif %}
                {% if item.can_prewarm %}
                <button class="btn btn-outline-primary btn-sm" type="button" data-ppt-prewarm-preview data-ppt-filename="{{ item.latest_file_name }}">
                  <i class="fas fa-fire me-1"></i>預熱
                </button>
                {% endif %}
                {% if item.can_regenerate and item.delivery_status in ['missing', 'error', 'partial'] %}
                <button class="btn btn-outline-warning btn-sm" type="button" data-ppt-generate-one data-report-type="{{ item.key }}" data-report-label="{{ item.label }}">
                  <i class="fas fa-rotate me-1"></i>重跑
                </button>
                {% endif %}
              </div>
            </div>
            {% endfor %}
          </div>
        </div>
      </div>
      <div class="ppt-auto-status small text-muted mt-3" data-ppt-auto-status>
        {% if auto_generation.enabled %}
          {{ auto_generation.cadence_summary }} 會定期產出並寫入 DB；目前缺漏 {{ auto_generation.missing_count }} 類。視覺 QA 可立即補跑，或等待每日 22:00 排程。
        {% else %}
          PPT_AUTO_GENERATION_ENABLED=false，已停用自動補齊。
        {% endif %}
      </div>
      <div class="ppt-run-log mt-3">
        <div class="ppt-run-log-head">
          <div>
            <div class="ppt-label">DB 產出紀錄</div>
            <h3>最近寫入 ppt_generation_runs</h3>
          </div>
          <small class="text-muted">產出檔案、參數、狀態會同步保留在資料庫</small>
        </div>
        {% if generation_runs %}
        <div class="ppt-run-list">
          {% for run in generation_runs %}
          <div class="ppt-run-row">
            <span class="ppt-run-kind">{{ run.schedule_label }}</span>
            <strong>{{ run.report_label }}</strong>
            <span class="ppt-run-target">{{ run.target_label or '最新資料' }}</span>
            <span class="ppt-run-status is-{{ run.status }}">{{ run.status_label }}</span>
            <small class="text-muted">{{ run.started_at }}{% if run.finished_at %} → {{ run.finished_at }}{% endif %}</small>
            {% if run.file_name %}
            <a class="btn btn-outline-primary btn-sm"
               href="{{ url_for('admin_observability.ppt_audit_file', filename=run.file_name) }}"
               target="_blank"
               rel="noopener"
               data-ppt-open-preview
               data-ppt-filename="{{ run.file_name }}"
               data-ppt-preview-title="{{ run.report_label }} · {{ run.file_name }}"
               data-ppt-preview-pdf="{{ url_for('admin_observability.ppt_audit_file', filename=run.file_name, action='pdf') }}"
               data-ppt-preview-page="{{ url_for('admin_observability.ppt_audit_file', filename=run.file_name) }}"
               data-ppt-download-url="{{ url_for('admin_observability.ppt_audit_file', filename=run.file_name, action='download') }}">
              <i class="fas fa-eye me-1"></i>預覽
            </a>
            {% endif %}
          </div>
          {% endfor %}
        </div>
        {% else %}
        <div class="ppt-empty ppt-run-empty">
          目前查無本月 DB 產出紀錄；下一次自動排程或手動補齊後，會寫入 ppt_generation_runs 並顯示在這裡。
        </div>
        {% endif %}
      </div>
    </div>
  </section>
  <section class="ppt-grid">
    <div class="ppt-stack">
    <article class="ppt-table-shell">
      <div class="ppt-table-title">
        <div>
          <div class="ppt-label">審核歷史</div>
          <h3>視覺審核歷史（{{ report_month }}）</h3>
        </div>
      </div>
      <div class="table-responsive">
        <table class="table table-sm mb-0">
          <thead class="table-light">
            <tr><th>時間</th><th>檔名</th><th>結果</th><th class="text-end">問題</th><th class="text-end">信心</th><th class="text-end">耗時</th><th>診斷摘要</th><th>動作</th></tr>
          </thead>
          <tbody>
            {% for r in audit_records %}
            <tr>
              <td><small>{{ r.audited_at }}</small></td>
              <td><code>{{ r.pptx_filename }}</code></td>
              <td>
                {% if r.audit_status == 'passed' %}<span class="badge bg-success">通過</span>
                {% elif r.audit_status == 'failed' %}<span class="badge bg-warning">有問題</span>
                {% elif r.audit_status == 'error' %}<span class="badge bg-danger">錯誤</span>
                {% elif r.audit_status == 'skipped' %}<span class="badge bg-secondary">跳過</span>
                {% else %}<span class="badge bg-light text-dark">{{ r.audit_status }}</span>{% endif %}
              </td>
              <td class="text-end">{{ r.issues_count }}</td>
              <td class="text-end">{{ "%.2f"|format(r.confidence) }}</td>
              <td class="text-end">{{ r.duration_ms }}</td>
              <td><small class="text-muted">{{ (r.issue_summary or r.error_msg or '')[:180] }}</small></td>
              <td>
                {% if r.pptx_filename %}
                <a class="btn btn-sm btn-outline-primary"
                   href="{{ url_for('admin_observability.ppt_audit_file', filename=r.pptx_filename) }}"
                   target="_blank"
                   rel="noopener"
                   data-ppt-open-preview
                   data-ppt-filename="{{ r.pptx_filename }}"
                   data-ppt-preview-title="審核回放 · {{ r.pptx_filename }}"
                   data-ppt-preview-pdf="{{ url_for('admin_observability.ppt_audit_file', filename=r.pptx_filename, action='pdf') }}"
                   data-ppt-preview-page="{{ url_for('admin_observability.ppt_audit_file', filename=r.pptx_filename) }}"
                   data-ppt-download-url="{{ url_for('admin_observability.ppt_audit_file', filename=r.pptx_filename, action='download') }}">
                  <i class="fas fa-eye me-1"></i>回放
                </a>
                {% endif %}
                {% if r.audit_status in ('failed','error') %}
                {% if r.report_type %}
                <button class="btn btn-sm btn-outline-warning"
                        type="button"
                        data-ppt-generate-one
                        data-report-type="{{ r.report_type }}"
                        data-report-label="{{ r.pptx_filename }}">
                  <i class="fas fa-rotate me-1"></i>重跑
                </button>
                {% endif %}
                <button class="btn btn-sm btn-outline-warning"
                        type="button"
                        data-ppt-aider-heal
                        data-ppt-filename="{{ r.pptx_filename }}"
                        data-ppt-error="{{ r.issue_summary or r.error_msg or '' }}">
                  <i class="fas fa-wrench me-1"></i>AiderHeal
                </button>
                {% endif %}
              </td>
            </tr>
            {% else %}
            <tr><td colspan="8" class="text-center text-muted">目前無 {{ selected_report_type.label }} 審核歷史；可按「立即視覺 QA」補跑，或等待每日 22:00 排程。</td></tr>
            {% endfor %}
          </tbody>
        </table>
      </div>
    </article>
      <article class="ppt-table-shell">
        <div class="ppt-table-title">
          <div>
            <div class="ppt-label">已產檔案</div>
            <h3>{{ report_month }} {{ selected_report_type.label }}</h3>
          </div>
        </div>
        <div class="table-responsive">
            <table class="table table-sm mb-0">
            <thead class="table-light">
            <tr><th>檔名</th><th class="text-end">KB</th><th>修改時間</th><th>狀態</th><th>操作</th></tr>
            </thead>
            <tbody>
              {% for f in files %}
              <tr>
                <td><code>{{ f.name }}</code></td>
                <td class="text-end">{{ f.size_kb if f.size_kb is not none else '—' }}</td>
                <td><small>{{ f.mtime }}</small></td>
                <td>
                  {% if f.source == 'database' %}
                    {% if f.file_exists %}
                    {% if f.is_valid_ppt %}
                    <span class="text-success">資料庫快取 + 檔案可預覽</span>
                    {% else %}
                    <span class="status-bad">資料庫快取 + 檔案損毀，建議重跑</span>
                    {% endif %}
                    {% else %}
                    <span class="text-muted">資料庫快取（檔案未落盤）</span>
                    {% endif %}
                  {% elif f.source == 'both' %}
                    {% if f.is_valid_ppt %}
                    <span class="text-success">檔案 + 資料庫</span>
                    {% else %}
                    <span class="status-bad">檔案 + 資料庫，檔案損毀</span>
                    {% endif %}
                  {% else %}
                    {% if f.is_valid_ppt %}
                    <span class="text-success">22:00 掃描落盤，可預覽</span>
                    {% else %}
                    <span class="status-bad">22:00 掃描落盤，檔案損毀</span>
                    {% endif %}
                  {% endif %}
                  {% if f.file_error %}
                  <div><small class="text-muted">{{ f.file_error }}</small></div>
                  {% endif %}
                  {% if f.file_exists and f.is_valid_ppt %}
                  <div>
                    <small class="{{ 'status-blue' if f.preview_cache_ready else 'status-warn' }}" data-ppt-preview-state="{{ f.name }}">
                      {% if f.preview_cache_ready %}
                        PDF 預覽快取已建立{% if f.preview_cache_mtime %} · {{ f.preview_cache_mtime }}{% endif %}
                      {% else %}
                        PDF 預覽尚未快取，首次開啟會自動轉檔
                      {% endif %}
                    </small>
                  </div>
                  {% endif %}
                </td>
                <td>
                  <div class="ppt-file-actions">
                    {% if f.file_exists %}
                    {% if f.is_valid_ppt %}
                    <a class="btn btn-outline-primary btn-sm"
                       href="{{ url_for('admin_observability.ppt_audit_file', filename=f.name) }}"
                       target="_blank"
                       rel="noopener"
                       data-ppt-open-preview
                       data-ppt-filename="{{ f.name }}"
                       data-ppt-preview-title="{{ selected_report_type.label }} · {{ f.name }}"
                       data-ppt-preview-pdf="{{ url_for('admin_observability.ppt_audit_file', filename=f.name, action='pdf') }}"
                       data-ppt-preview-page="{{ url_for('admin_observability.ppt_audit_file', filename=f.name) }}"
                       data-ppt-download-url="{{ url_for('admin_observability.ppt_audit_file', filename=f.name, action='download') }}">
                      <i class="fas fa-eye me-1"></i>線上預覽
                    </a>
                    {% if not f.preview_cache_ready %}
                    <button class="btn btn-outline-primary btn-sm" type="button" data-ppt-prewarm-preview data-ppt-filename="{{ f.name }}">
                      <i class="fas fa-fire me-1"></i>預熱 PDF
                    </button>
                    {% endif %}
                    {% else %}
                    <span class="small status-bad">檔案不可預覽</span>
                    {% endif %}
                    <a class="btn btn-outline-secondary btn-sm" href="{{ url_for('admin_observability.ppt_audit_file', filename=f.name, action='download') }}">
                      <i class="fas fa-download me-1"></i>下載
                    </a>
                    {% else %}
                    <span class="small text-muted">本機暫無檔案，請先至來源回補</span>
                    {% endif %}
                  </div>
                </td>
              </tr>
              {% else %}
              <tr><td colspan="5" class="text-center text-muted">本月無 {{ selected_report_type.label }} 簡報</td></tr>
              {% endfor %}
            </tbody>
          </table>
        </div>
      </article>
    </div>
    <aside class="ppt-stack">
      {% if audit_30d_stats and audit_30d_stats.total > 0 %}
      <article class="ppt-panel">
        <div class="ppt-panel-head">
          <div><div class="ppt-label">{{ report_month }} 審核分布</div><h2 class="ppt-panel-title">審核結果分布</h2></div>
        </div>
        <div class="ppt-panel-body">
          <div class="obs-chart-frame"><canvas id="pptAuditPieChart"></canvas></div>
          <div class="ppt-mini-grid mt-3">
            <div class="ppt-mini"><span class="ppt-label">通過</span><strong class="status-good">{{ audit_30d_stats.passed }}</strong></div>
            <div class="ppt-mini"><span class="ppt-label">失敗</span><strong class="{% if audit_30d_stats.failed > 0 %}status-warn{% endif %}">{{ audit_30d_stats.failed }}</strong></div>
            <div class="ppt-mini"><span class="ppt-label">錯誤</span><strong class="{% if audit_30d_stats.error > 0 %}status-bad{% endif %}">{{ audit_30d_stats.error }}</strong></div>
            <div class="ppt-mini"><span class="ppt-label">信心分</span><strong>{{ "%.2f"|format(audit_30d_stats.avg_confidence) }}</strong></div>
          </div>
        </div>
      </article>
      {% endif %}
      {% if top_failure_files %}
      <article class="ppt-panel">
        <div class="ppt-panel-head">
          <div><div class="ppt-label">失敗熱點</div><h2 class="ppt-panel-title">Top 失敗檔案</h2></div>
        </div>
        <div class="ppt-panel-body">
          {% for f in top_failure_files %}<div class="fix-card"><code>{{ f.filename }}</code><div class="d-flex justify-content-between mt-1"><small class="text-muted">{{ f.last_audit }}</small><span class="badge bg-warning">{{ f.attempts }} 次</span></div><small class="text-muted">問題 {{ f.total_issues }}</small></div>{% endfor %}
        </div>
      </article>
      {% endif %}
      {% if not (audit_30d_stats and audit_30d_stats.total > 0) %}
      <article class="ppt-panel">
        <div class="ppt-panel-head">
          <div><div class="ppt-label">審核摘要</div><h2 class="ppt-panel-title">本月審核狀態</h2></div>
        </div>
        <div class="ppt-panel-body">
          <div class="ppt-empty p-3">
            <p class="mb-1"><strong>尚未形成 daily 審核統計。</strong></p>
            <p class="mb-0">排程或立即視覺 QA 完成後，這裡會顯示本月通過率、失敗檔案與修復建議。</p>
          </div>
        </div>
      </article>
      {% endif %}
    </aside>
  </section>

  {% if rag_fixes %}
  <section class="ppt-panel mt-3">
    <div class="ppt-panel-head">
      <div><div class="ppt-label">RAG 修法建議</div><h2 class="ppt-panel-title">RAG 自動修法建議</h2></div>
    </div>
    <div class="ppt-panel-body">
      {% for fix in rag_fixes %}
      <div class="fix-card">
        <strong><code>{{ fix.pptx_filename }}</code></strong><small class="text-muted ms-2">{{ fix.audited_at }}</small>
        <div class="small status-bad mt-1">{{ fix.error_msg }}</div>
        <ul class="list-unstyled mt-2 mb-0 small">
          {% for h in fix.hits %}
          <li class="mb-1">
            <span class="badge bg-info me-1">{{ obs_label.insight(h.insight_type) }}</span>
            <span class="badge bg-light text-dark me-1">相似度 {{ "%.2f"|format(h.similarity) }}</span>{{ h.content }}{% if h.content|length >= 200 %}…{% endif %}
          </li>
          {% endfor %}
        </ul>
      </div>
      {% endfor %}
    </div>
  </section>
  {% endif %}
  {% if not vision_enabled %}
  <div class="alert alert-info mt-3">
    <strong>為什麼這頁空？</strong>
    <ul class="mb-0 small mt-2">
      <li>PPT_VISION_ENABLED=false</li>
      <li>188 主機需安裝 LibreOffice</li>
      <li>需 Ollama 拉取 minicpm-v 模型</li>
      <li>啟用後可立即補跑，或由每日 22:00 排程寫入 ppt_audit_results</li>
    </ul>
  </div>
  {% elif files|length == 0 %}
  <div class="alert alert-warning mt-3">
    <strong>本月無資料</strong>
    <ul class="mb-0 small mt-2">
      <li>若為「每日日報」，檢查 {{ report_month }} 是否由 188 排程成功落盤。</li>
      <li>若為「週報 / 月報 / 策略 / 競品 / 促銷」，請確認 Telegram 任務是否有對應產出。</li>
      <li>可回到上方月份切換器看先前月份，或調整報表類型重新查詢。</li>
    </ul>
  </div>
  {% endif %}
  <p class="text-muted mt-3"><small><i class="fas fa-robot me-1"></i>Ollama 優先策略 v5.0 — PPT 視覺 QA 產線</small></p>
</div>

<div class="ppt-preview-modal" data-ppt-preview-modal hidden aria-hidden="true">
  <div class="ppt-preview-backdrop" data-ppt-preview-close></div>
  <section class="ppt-preview-dialog" role="dialog" aria-modal="true" aria-labelledby="pptPreviewTitle">
    <header class="ppt-preview-head">
      <div>
        <div class="ppt-label">Inline PDF Preview</div>
        <h2 id="pptPreviewTitle" data-ppt-preview-modal-title>簡報線上預覽</h2>
        <small class="text-muted" data-ppt-preview-filename>尚未選擇檔案</small>
      </div>
      <div class="ppt-preview-actions">
        <a class="btn btn-outline-secondary btn-sm" href="#" target="_blank" rel="noopener" data-ppt-preview-open-page>
          <i class="fas fa-up-right-from-square me-1"></i>開新頁
        </a>
        <a class="btn btn-outline-secondary btn-sm" href="#" data-ppt-preview-download>
          <i class="fas fa-download me-1"></i>下載
        </a>
        <button class="btn btn-outline-primary btn-sm" type="button" data-ppt-preview-close aria-label="關閉預覽">
          <i class="fas fa-xmark me-1"></i>關閉
        </button>
      </div>
    </header>
    <div class="ppt-preview-frame-wrap">
      <div class="ppt-preview-loading" data-ppt-preview-loading>正在載入 PDF 預覽</div>
      <iframe data-ppt-preview-frame title="PPT PDF 線上預覽" loading="lazy"></iframe>
    </div>
  </section>
</div>

<template id="obs-ppt-audit-data">{{ audit_30d_stats | default({}) | tojson }}</template>
<template id="obs-ppt-audit-filenames">{{ vision_audit_filenames | default([]) | tojson }}</template>
<script src="{{ url_for('static', filename='js/analysis-chart-theme.js') }}"></script>
<script src="{{ url_for('static', filename='js/observability-charts.js') }}"></script>
{% endblock %}
