<!-- ── Engine selector bar ───────────────────────────────────────────────────── -->
<div class="container engine-toggle-bar">
  <button class="engine-tab" [class.active]="engine() === 'onnx'" (click)="onEngineChange('onnx')">
    🧠 ONNX (YOLOv8)
  </button>
  <button class="engine-tab" [class.active]="engine() === 'tflite'" (click)="onEngineChange('tflite')">
    ⚡ TFLite (FP32)
  </button>
  <button class="engine-tab"
          [class.active]="engine() === 'socket'"
          [class.disabled]="surveillance.nestStatus() === 'OFFLINE'"
          [disabled]="surveillance.nestStatus() === 'OFFLINE'"
          (click)="onEngineChange('socket')">
    🔌 NestJS Socket
    <span class="socket-status" [class.live]="visionSocket.connected()">
      {{ visionSocket.connected() ? '●' : '○' }}
    </span>
  </button>
</div>

<!-- ── NestJS Offline Banner ─────────────────────────────────────────────────── -->
@if (surveillance.nestStatus() === 'OFFLINE') {
  <div class="container nest-offline-banner">
    ⚠ Backend Inference Engine Offline — Local TFLite active. Socket engine disabled.
  </div>
}

<!-- ─────────────────────────────────────────────────────────────────────────── -->
<!--  BROWSER ENGINES (ONNX / TFLite) — file upload + local inference           -->
<!-- ─────────────────────────────────────────────────────────────────────────── -->
@if (isBrowserEngine()) {
  <div class="container main-content">
    <div class="row">

      <!-- Controls column -->
      <div class="col-left">
        <div class="glass-panel upload-zone"
             (click)="fileInput.click()"
             [class.has-file]="selectedFile"
             [class.dragging]="isDragging"
             (dragover)="onDragOver($event)"
             (dragleave)="onDragLeave($event)"
             (drop)="onDrop($event)">
          <input type="file" #fileInput multiple (change)="onFileSelected($event)" accept="image/*">
          <div class="upload-icon">📁</div>
          @if (!selectedFile) { <p>Drop image here or click to upload</p> }
          @if (selectedFile)  { <p>{{ selectedFile.name }}</p> }
        </div>

        <div class="controls glass-panel">
          <div class="engine-info">
            @if (engine() === 'onnx') {
              <span class="engine-chip">YOLOv8 ONNX · WASM · Local</span>
            } @else {
              <span class="engine-chip">TFLite FP32 · WASM · Local</span>
            }
          </div>

          <button
            class="btn btn-primary snap-btn"
            (click)="runLocalInference()"
            [disabled]="!selectedFile || loading">
            {{ loading ? 'Running Inference...' : 'Run Inference' }}
          </button>

          <div class="lego-note">
            Snap runs entirely in-browser. No network call. Model loaded from
            <code>/assets/models/</code>.
          </div>
        </div>
      </div>

      <!-- Results column -->
      <div class="col-right">
        <div class="glass-panel results-panel">
          <h2 class="panel-title">
            Inference Results
            <span class="engine-label">{{ engine() === 'onnx' ? 'ONNX' : 'TFLite' }} · Lego 02</span>
          </h2>

          @if (!results && !loading) {
            <div class="no-results">Upload an image and run inference to see bounding boxes.</div>
          }
          @if (loading) {
            <div class="loading-state">
              <div class="spinner"></div>
              <p>Running {{ engine() === 'onnx' ? 'ONNX' : 'TFLite' }} inference...</p>
            </div>
          }
          @if (results) {
            <div class="results-data">
              <div class="summary-cards">
                @for (key of getSummaryKeys(); track key) {
                  <div class="card"
                       [class.alert]="inferenceService.summary()[key] > 0 && (key === 'Abnormal' || key === 'Empty_Bunch')">
                    <span class="card-label">{{ key }}</span>
                    <span class="card-value">{{ inferenceService.summary()[key] }}</span>
                  </div>
                }
                <div class="card highlight">
                  <span class="card-label">Latency</span>
                  <span class="card-value">{{ results.inference_ms.toFixed(1) }} ms</span>
                </div>
              </div>
              <div class="detection-canvas-wrapper">
                <canvas #resultCanvas></canvas>
              </div>
            </div>
          }
        </div>
      </div>

    </div>
  </div>
}

<!-- ─────────────────────────────────────────────────────────────────────────── -->
<!--  SOCKET ENGINE — Three-Column Command Center                                -->
<!-- ─────────────────────────────────────────────────────────────────────────── -->
@if (isSocketEngine()) {
  <div class="container main-content">
    <div class="dashboard-layout">

      <!-- ── COL 1: Configuration Sidebar ──────────────────────────────────── -->
      <div class="dash-sidebar">
        <div class="glass-panel backend-controls">
          <h3 class="panel-title">NestJS Socket Engine</h3>

          <div class="status-row">
            <span class="status-label">WebSocket</span>
            <span class="status-badge" [class.live]="visionSocket.connected()">
              {{ visionSocket.connected() ? 'CONNECTED' : 'DISCONNECTED' }}
            </span>
          </div>

          <div class="status-row">
            <span class="status-label">Webcam</span>
            <span class="status-badge" [class.live]="webcamActive">
              {{ webcamActive ? 'LIVE PREVIEW' : 'OFF' }}
            </span>
          </div>

          <div class="status-row">
            <span class="status-label">Analysis</span>
            <span class="status-badge" [class.live]="visionSocket.analyzing()">
              {{ visionSocket.analyzing() ? 'PROCESSING...' : 'IDLE' }}
            </span>
          </div>

          <!-- Batch Status HUD — active while queue is running -->
          @if (isBatchActive()) {
            <div class="batch-status-hud glass-panel">
              <div class="batch-status-label">
                Batch Status — Processing Image {{ currentBatchIndex() + 1 }} of {{ totalBatchCount }}
              </div>
              <div class="batch-progress-row">
                <div class="batch-progress-bar">
                  <div class="batch-progress-fill"
                       [style.width.%]="(currentBatchIndex() / totalBatchCount) * 100">
                  </div>
                </div>
                <button class="btn btn-danger btn-sm abort-btn" (click)="abortBatch()">
                  Abort
                </button>
              </div>
            </div>
          }

          <!-- Batch Complete HUD -->
          @if (completedReport()) {
            <div class="batch-complete-hud glass-panel">
              <div class="batch-complete-title">Batch Complete</div>
              <div class="batch-complete-stats">
                <div class="bc-stat">
                  <span class="bc-label">Images</span>
                  <span class="bc-value">{{ completedReport()!.meta.total_images }}</span>
                </div>
                <div class="bc-stat">
                  <span class="bc-label">OK</span>
                  <span class="bc-value ok">{{ completedReport()!.meta.successful }}</span>
                </div>
                <div class="bc-stat">
                  <span class="bc-label">Failed</span>
                  <span class="bc-value" [class.alert]="completedReport()!.meta.failed > 0">
                    {{ completedReport()!.meta.failed }}
                  </span>
                </div>
                <div class="bc-stat highlight">
                  <span class="bc-label">Avg Inference</span>
                  <span class="bc-value">{{ completedReport()!.meta.avg_inference_ms }} ms</span>
                </div>
                <div class="bc-stat">
                  <span class="bc-label">Avg RTT</span>
                  <span class="bc-value">{{ completedReport()!.meta.avg_round_trip_ms }} ms</span>
                </div>
                <div class="bc-stat">
                  <span class="bc-label">Total</span>
                  <span class="bc-value">{{ completedReport()!.meta.total_time_ms }} ms</span>
                </div>
              </div>
              @if (getBatchDistribution().length > 0) {
                <div class="bc-distribution">
                  <div class="bc-dist-label">Ripeness Distribution</div>
                  @for (item of getBatchDistribution(); track item.class) {
                    <div class="bc-dist-row">
                      <span class="bc-dist-name">{{ item.class }}</span>
                      <div class="bc-dist-bar-track">
                        <div class="bc-dist-bar-fill" [style.width.%]="item.pct" [style.background]="item.color"></div>
                      </div>
                      <span class="bc-dist-pct">{{ item.pct }}%</span>
                    </div>
                  }
                </div>
              }
              <button class="btn btn-outline btn-sm" (click)="completedReport.set(null)">
                Dismiss
              </button>
            </div>
          }

          <!-- Input source toggle -->
          <div class="input-mode-toggle">
            <button class="input-mode-btn" [class.active]="socketInputMode() === 'webcam'"
                    (click)="onSocketInputModeChange('webcam')">📷 Webcam</button>
            <button class="input-mode-btn" [class.active]="socketInputMode() === 'gallery'"
                    (click)="onSocketInputModeChange('gallery')">🖼 Gallery</button>
          </div>

          <div class="lego-note">
            <strong>Lego 11:</strong> One frame per analyze. Transmitted as raw Base64
            via <code>vision:analyze</code>. Every snap is a Batch of 1.
          </div>

          <!-- Webcam controls -->
          @if (socketInputMode() === 'webcam') {
            @if (!webcamActive) {
              <button class="btn btn-primary snap-btn" (click)="startWebcam()">
                Start Webcam Preview
              </button>
            } @else {
              <button class="btn btn-primary snap-btn"
                      (click)="snapAndAnalyze()"
                      [disabled]="isBatchActive() || !visionSocket.connected()">
                {{ isBatchActive() ? 'Processing...' : '📸 Snap & Analyze' }}
              </button>
              <button class="btn btn-outline" (click)="stopWebcam()">Stop Webcam</button>
            }
          }

          <!-- Gallery controls -->
          @if (socketInputMode() === 'gallery') {
            <div class="glass-panel upload-zone gallery-upload-zone"
                 (click)="galleryInput.click()"
                 [class.has-file]="socketGalleryFile"
                 [class.dragging]="isDragging"
                 (dragover)="onDragOver($event)"
                 (dragleave)="onDragLeave($event)"
                 (drop)="onGalleryDrop($event)">
              <input type="file" #galleryInput accept="image/*" multiple
                     (change)="onGalleryFileSelected($event)" style="display:none">
              <div class="upload-icon">📁</div>
              @if (!socketGalleryFile && batchQueue().length === 0) {
                <p>Drop images here or click to select</p>
                <p class="upload-hint">Multiple images = Batch Audit</p>
              } @else if (batchQueue().length > 0) {
                <p>{{ batchQueue().length }} image(s) queued</p>
              } @else {
                <p>{{ socketGalleryFile!.name }}</p>
              }
            </div>
            <button class="btn btn-primary snap-btn"
                    (click)="analyzeGalleryImage()"
                    [disabled]="(!socketGalleryFile && batchQueue().length === 0) || isBatchActive() || !visionSocket.connected()">
              {{ isBatchActive() ? 'Processing...' : (batchQueue().length > 1 ? '🚀 Start Batch Audit' : '🔍 Analyze Image') }}
            </button>
          }

          @if (visionSocket.lastError()) {
            <div class="error-note">{{ visionSocket.lastError() }}</div>
          }
        </div>
      </div>

      <!-- ── COL 2: Active View ─────────────────────────────────────────────── -->
      <div class="dash-main">
        <div class="glass-panel webcam-panel">

          <!-- Webcam mode -->
          @if (socketInputMode() === 'webcam') {
            @if (webcamActive) {
              <h2 class="panel-title">
                Live Preview
                <span class="engine-label">NestJS ONNX · Batch-1 · Lego 11</span>
              </h2>
              <div class="webcam-wrapper active">
                <video #videoEl autoplay playsinline muted class="webcam-video"></video>
              </div>
            }
            @if (!webcamActive) {
              <div class="no-results">
                Click "Start Webcam Preview" to open the camera.<br>
                Each "Snap &amp; Analyze" submits a Batch of 1 to NestJS.
              </div>
            }
          }

          <!-- Gallery mode — show last processed image result -->
          @if (socketInputMode() === 'gallery') {
            @if (completedReport() && completedReport()!.results.length > 0) {
              @if (selectedAuditEntry()?.localBlobUrl) {
                <h2 class="panel-title">
                  Evidence View
                  <span class="engine-label">{{ selectedAuditEntry()!.image_id }}</span>
                </h2>
                <div class="evidence-canvas-wrapper">
                  <canvas #evidenceCanvas class="evidence-canvas"></canvas>
                </div>
              } @else {
                <div class="no-results">Select a row in the manifest to view evidence.</div>
              }
            } @else if (isBatchActive()) {
              <div class="no-results">
                <div class="spinner"></div>
                <p>Processing image {{ currentBatchIndex() + 1 }} of {{ totalBatchCount }}…</p>
              </div>
            } @else {
              <div class="no-results">
                Select images from Gallery and click "Start Batch Audit".
              </div>
            }
          }
        </div>

        <!-- Evidence JSON blocks — shown below the canvas when an entry is selected -->
        @if (selectedAuditEntry()) {
          <div class="evidence-panel">
            <div class="evidence-header">
              <div>
                <span class="evidence-title">Technical Evidence</span>
                <span class="evidence-id">{{ selectedAuditEntry()!.image_id }}</span>
              </div>
              <button class="btn btn-outline btn-sm" (click)="selectedAuditEntry.set(null)">✕ Close</button>
            </div>
            <div class="evidence-grid">
              <div class="evidence-block">
                <div class="evidence-block-label">Raw Tensor Sample</div>
                <pre class="json-viewer">{{ selectedAuditEntry()!.technical_evidence.raw_tensor_sample | json }}</pre>
              </div>
              <div class="evidence-block">
                <div class="evidence-block-label">Industrial Summary</div>
                <pre class="json-viewer">{{ selectedAuditEntry()!.technical_evidence.industrial_summary | json }}</pre>
              </div>
              <div class="evidence-block evidence-block--full">
                <div class="evidence-block-label">Full technical_evidence</div>
                <pre class="json-viewer">{{ selectedAuditEntry()!.technical_evidence | json }}</pre>
              </div>
              <div class="evidence-block evidence-block--full">
                <div class="evidence-block-label">Performance</div>
                <pre class="json-viewer">{{ selectedAuditEntry()!.performance | json }}</pre>
              </div>
            </div>
          </div>
        }
      </div>

      <!-- ── COL 3: Live Audit Manifest ────────────────────────────────────── -->
      <div class="dash-manifest">
        <div class="glass-panel manifest-panel">
          <div class="manifest-header">
            <span class="manifest-title">Audit Manifest</span>
            @if (completedReport()) {
              <span class="manifest-session-id">{{ completedReport()!.session_id | slice:0:8 }}…</span>
            } @else if (isBatchActive()) {
              <span class="manifest-live-badge">LIVE</span>
            }
          </div>

          @if (!completedReport() && !isBatchActive()) {
            <div class="manifest-empty">
              Results will appear here as each image is processed.
            </div>
          }

          <!-- Live rows during batch run -->
          @if (isBatchActive() && sessionManifest.length > 0) {
            <div class="manifest-table-scroll">
              <table class="audit-table">
                <thead>
                  <tr><th>Image</th><th>Status</th><th>ms</th></tr>
                </thead>
                <tbody>
                  @for (entry of sessionManifest; track entry.image_id) {
                    <tr [class.row-error]="entry.status === 'error'">
                      <td class="cell-id">{{ entry.image_id }}</td>
                      <td>
                        <span class="status-pill" [class.pill-ok]="entry.status === 'ok'" [class.pill-err]="entry.status === 'error'">
                          {{ entry.status === 'ok' ? '✅' : '❌' }}
                        </span>
                      </td>
                      <td class="cell-ms">{{ entry.status === 'ok' ? (entry.performance.inference_ms | number:'1.0-0') : '—' }}</td>
                    </tr>
                  }
                </tbody>
              </table>
            </div>
          }

          <!-- Final manifest after completion -->
          @if (completedReport()) {
            <div class="manifest-table-scroll">
              <table class="audit-table">
                <thead>
                  <tr><th>Image</th><th>Status</th><th>ms</th><th></th></tr>
                </thead>
                <tbody>
                  @for (entry of completedReport()!.results; track entry.image_id) {
                    <tr [class.row-error]="entry.status === 'error'"
                        [class.row-selected]="selectedAuditEntry()?.image_id === entry.image_id"
                        (click)="selectedAuditEntry.set(entry)">
                      <td class="cell-id">{{ entry.image_id }}</td>
                      <td>
                        <span class="status-pill" [class.pill-ok]="entry.status === 'ok'" [class.pill-err]="entry.status === 'error'">
                          {{ entry.status === 'ok' ? '✅' : '❌' }}
                        </span>
                      </td>
                      <td class="cell-ms">{{ entry.status === 'ok' ? (entry.performance.inference_ms | number:'1.0-0') : '—' }}</td>
                      <td>
                        @if (entry.localBlobUrl) {
                          <button class="btn-evidence" (click)="selectedAuditEntry.set(entry); $event.stopPropagation()">View</button>
                        }
                      </td>
                    </tr>
                  }
                </tbody>
              </table>
            </div>
          }
        </div>
      </div>

    </div>
  </div>
}
