"""
Admin GPU Infrastructure Component.

Provides UI controls for vast.ai GPU management:
- Start/Stop buttons
- Status display with GPU info
- Cost tracking
- Auto-shutdown timer
"""


def get_admin_gpu_css() -> str:
    """CSS fuer GPU Control Panel."""
    return """
/* ==========================================
   GPU INFRASTRUCTURE STYLES
   ========================================== */
.gpu-control-panel {
  background: var(--bp-surface-elevated);
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 20px;
  border: 1px solid var(--bp-border);
}

.gpu-status-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.gpu-status-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 20px;
  font-size: 13px;
  font-weight: 600;
}

.gpu-status-badge.running {
  background: rgba(34, 197, 94, 0.15);
  color: #22c55e;
}

.gpu-status-badge.stopped {
  background: rgba(156, 163, 175, 0.15);
  color: #9ca3af;
}

.gpu-status-badge.loading {
  background: rgba(59, 130, 246, 0.15);
  color: #3b82f6;
}

.gpu-status-badge.error {
  background: rgba(239, 68, 68, 0.15);
  color: #ef4444;
}

.gpu-status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
}

.gpu-status-dot.running {
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

.gpu-info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}

.gpu-info-card {
  background: var(--bp-surface);
  border-radius: 8px;
  padding: 12px;
  border: 1px solid var(--bp-border-subtle);
}

.gpu-info-label {
  font-size: 11px;
  color: var(--bp-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 4px;
}

.gpu-info-value {
  font-size: 16px;
  font-weight: 600;
  color: var(--bp-text);
}

.gpu-info-value.cost {
  color: #f59e0b;
}

.gpu-info-value.time {
  color: #3b82f6;
}

.gpu-controls {
  display: flex;
  gap: 12px;
  margin-top: 20px;
}

.gpu-btn {
  flex: 1;
  padding: 12px 20px;
  border: none;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: all 0.2s ease;
}

.gpu-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.gpu-btn-start {
  background: #22c55e;
  color: white;
}

.gpu-btn-start:hover:not(:disabled) {
  background: #16a34a;
}

.gpu-btn-stop {
  background: #ef4444;
  color: white;
}

.gpu-btn-stop:hover:not(:disabled) {
  background: #dc2626;
}

.gpu-btn-refresh {
  background: var(--bp-surface);
  color: var(--bp-text);
  border: 1px solid var(--bp-border);
  flex: 0 0 auto;
  padding: 12px;
}

.gpu-btn-refresh:hover:not(:disabled) {
  background: var(--bp-surface-elevated);
}

.gpu-shutdown-warning {
  background: rgba(251, 191, 36, 0.1);
  border: 1px solid rgba(251, 191, 36, 0.3);
  border-radius: 8px;
  padding: 12px;
  margin-top: 16px;
  display: flex;
  align-items: center;
  gap: 10px;
  color: #fbbf24;
  font-size: 13px;
}

.gpu-shutdown-warning svg {
  flex-shrink: 0;
}

.gpu-cost-summary {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--bp-border);
}

.gpu-cost-summary h4 {
  margin: 0 0 12px 0;
  font-size: 14px;
  color: var(--bp-text-muted);
}

.gpu-audit-log {
  margin-top: 20px;
  max-height: 200px;
  overflow-y: auto;
  background: var(--bp-surface);
  border-radius: 8px;
  border: 1px solid var(--bp-border-subtle);
}

.gpu-audit-entry {
  padding: 8px 12px;
  border-bottom: 1px solid var(--bp-border-subtle);
  font-size: 12px;
  font-family: monospace;
}

.gpu-audit-entry:last-child {
  border-bottom: none;
}

.gpu-audit-time {
  color: var(--bp-text-muted);
  margin-right: 8px;
}

.gpu-audit-event {
  color: var(--bp-text);
}

.gpu-endpoint-url {
  margin-top: 12px;
  padding: 10px 12px;
  background: var(--bp-surface);
  border-radius: 8px;
  font-family: monospace;
  font-size: 12px;
  color: var(--bp-text-muted);
  word-break: break-all;
}

.gpu-endpoint-url.active {
  color: #22c55e;
}

.gpu-spinner {
  width: 16px;
  height: 16px;
  border: 2px solid transparent;
  border-top-color: currentColor;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

[data-theme="light"] .gpu-control-panel {
  background: #fafafa;
}

[data-theme="light"] .gpu-info-card {
  background: #ffffff;
}
"""


def get_admin_gpu_html() -> str:
    """HTML fuer GPU Control Tab."""
    return """
<!-- GPU Infrastructure Tab Content -->
<div id="admin-content-gpu" class="admin-content">
  <div class="gpu-control-panel">
    <div class="gpu-status-header">
      <h3 style="margin: 0; font-size: 16px;">vast.ai GPU Instance</h3>
      <div id="gpu-status-badge" class="gpu-status-badge stopped">
        <span class="gpu-status-dot"></span>
        <span id="gpu-status-text">Unbekannt</span>
      </div>
    </div>

    <div class="gpu-info-grid">
      <div class="gpu-info-card">
        <div class="gpu-info-label">GPU</div>
        <div id="gpu-name" class="gpu-info-value">-</div>
      </div>
      <div class="gpu-info-card">
        <div class="gpu-info-label">Kosten/Stunde</div>
        <div id="gpu-dph" class="gpu-info-value cost">-</div>
      </div>
      <div class="gpu-info-card">
        <div class="gpu-info-label">Session</div>
        <div id="gpu-session-time" class="gpu-info-value time">-</div>
      </div>
      <div class="gpu-info-card">
        <div class="gpu-info-label">Gesamt</div>
        <div id="gpu-total-cost" class="gpu-info-value cost">-</div>
      </div>
    </div>

    <div id="gpu-endpoint" class="gpu-endpoint-url" style="display: none;">
      Endpoint: <span id="gpu-endpoint-url">-</span>
    </div>

    <div id="gpu-shutdown-warning" class="gpu-shutdown-warning" style="display: none;">
      <svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
          d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
      </svg>
      <span>Auto-Shutdown in <strong id="gpu-shutdown-minutes">0</strong> Minuten (bei Inaktivitaet)</span>
    </div>

    <div class="gpu-controls">
      <button id="gpu-btn-start" class="gpu-btn gpu-btn-start" onclick="gpuPowerOn()">
        <svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 3l14 9-14 9V3z"/>
        </svg>
        Starten
      </button>
      <button id="gpu-btn-stop" class="gpu-btn gpu-btn-stop" onclick="gpuPowerOff()" disabled>
        <svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 10a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z"/>
        </svg>
        Stoppen
      </button>
      <button class="gpu-btn gpu-btn-refresh" onclick="gpuRefreshStatus()" title="Status aktualisieren">
        <svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
            d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
        </svg>
      </button>
    </div>

    <div class="gpu-cost-summary">
      <h4>Kosten-Zusammenfassung</h4>
      <div class="gpu-info-grid">
        <div class="gpu-info-card">
          <div class="gpu-info-label">Laufzeit Gesamt</div>
          <div id="gpu-total-runtime" class="gpu-info-value time">0h 0m</div>
        </div>
        <div class="gpu-info-card">
          <div class="gpu-info-label">Kosten Gesamt</div>
          <div id="gpu-total-cost-all" class="gpu-info-value cost">$0.00</div>
        </div>
      </div>
    </div>

    <details style="margin-top: 20px;">
      <summary style="cursor: pointer; color: var(--bp-text-muted); font-size: 13px;">
        Audit Log (letzte Aktionen)
      </summary>
      <div id="gpu-audit-log" class="gpu-audit-log">
        <div class="gpu-audit-entry">Keine Eintraege</div>
      </div>
    </details>
  </div>

  <div style="padding: 12px; background: var(--bp-surface-elevated); border-radius: 8px; font-size: 12px; color: var(--bp-text-muted);">
    <strong>Hinweis:</strong> Die GPU-Instanz wird automatisch nach 30 Minuten Inaktivitaet gestoppt.
    Bei jedem LLM-Request wird die Aktivitaet aufgezeichnet und der Timer zurueckgesetzt.
  </div>
</div>
"""


def get_admin_gpu_js() -> str:
    """JavaScript fuer GPU Control."""
    return """
// ==========================================
// GPU INFRASTRUCTURE CONTROLS
// ==========================================

let gpuStatusInterval = null;
const GPU_CONTROL_KEY = window.CONTROL_API_KEY || '';

async function gpuFetch(endpoint, options = {}) {
  const headers = {
    'Content-Type': 'application/json',
    'X-API-Key': GPU_CONTROL_KEY,
    ...options.headers,
  };

  try {
    const response = await fetch(`/infra/vast${endpoint}`, {
      ...options,
      headers,
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({ detail: response.statusText }));
      throw new Error(error.detail || 'Request failed');
    }

    return await response.json();
  } catch (error) {
    console.error('GPU API Error:', error);
    throw error;
  }
}

async function gpuRefreshStatus() {
  const btnRefresh = document.querySelector('.gpu-btn-refresh');
  const btnStart = document.getElementById('gpu-btn-start');
  const btnStop = document.getElementById('gpu-btn-stop');

  try {
    if (btnRefresh) btnRefresh.disabled = true;

    const status = await gpuFetch('/status');

    // Update status badge
    const badge = document.getElementById('gpu-status-badge');
    const statusText = document.getElementById('gpu-status-text');
    const statusDot = badge.querySelector('.gpu-status-dot');

    badge.className = 'gpu-status-badge ' + status.status;
    statusText.textContent = formatGpuStatus(status.status);
    statusDot.className = 'gpu-status-dot ' + status.status;

    // Update info cards
    document.getElementById('gpu-name').textContent = status.gpu_name || '-';
    document.getElementById('gpu-dph').textContent = status.dph_total
      ? `$${status.dph_total.toFixed(2)}/h`
      : '-';

    // Update endpoint
    const endpointDiv = document.getElementById('gpu-endpoint');
    const endpointUrl = document.getElementById('gpu-endpoint-url');
    if (status.endpoint_base_url && status.status === 'running') {
      endpointDiv.style.display = 'block';
      endpointDiv.className = 'gpu-endpoint-url active';
      endpointUrl.textContent = status.endpoint_base_url;
    } else {
      endpointDiv.style.display = 'none';
    }

    // Update shutdown warning
    const warningDiv = document.getElementById('gpu-shutdown-warning');
    const shutdownMinutes = document.getElementById('gpu-shutdown-minutes');
    if (status.auto_shutdown_in_minutes !== null && status.status === 'running') {
      warningDiv.style.display = 'flex';
      shutdownMinutes.textContent = status.auto_shutdown_in_minutes;
    } else {
      warningDiv.style.display = 'none';
    }

    // Update totals
    document.getElementById('gpu-total-runtime').textContent = formatRuntime(status.total_runtime_hours || 0);
    document.getElementById('gpu-total-cost-all').textContent = `$${(status.total_cost_usd || 0).toFixed(2)}`;

    // Update buttons
    const isRunning = status.status === 'running';
    const isLoading = ['loading', 'scheduling', 'creating'].includes(status.status);

    btnStart.disabled = isRunning || isLoading;
    btnStop.disabled = !isRunning;

    if (isLoading) {
      btnStart.innerHTML = '<span class="gpu-spinner"></span> Startet...';
    } else {
      btnStart.innerHTML = `
        <svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 3l14 9-14 9V3z"/>
        </svg>
        Starten
      `;
    }

    // Load audit log
    loadGpuAuditLog();

  } catch (error) {
    console.error('Failed to refresh GPU status:', error);
    document.getElementById('gpu-status-text').textContent = 'Fehler';
    document.getElementById('gpu-status-badge').className = 'gpu-status-badge error';
  } finally {
    if (btnRefresh) btnRefresh.disabled = false;
  }
}

async function gpuPowerOn() {
  const btnStart = document.getElementById('gpu-btn-start');
  const btnStop = document.getElementById('gpu-btn-stop');

  if (!confirm('GPU-Instanz starten? Es fallen Kosten an solange sie laeuft.')) {
    return;
  }

  try {
    btnStart.disabled = true;
    btnStop.disabled = true;
    btnStart.innerHTML = '<span class="gpu-spinner"></span> Startet...';

    const result = await gpuFetch('/power/on', {
      method: 'POST',
      body: JSON.stringify({
        wait_for_health: true,
      }),
    });

    showNotification('GPU gestartet: ' + (result.message || result.status), 'success');
    await gpuRefreshStatus();

    // Start polling for status updates
    startGpuStatusPolling();

  } catch (error) {
    showNotification('GPU Start fehlgeschlagen: ' + error.message, 'error');
    await gpuRefreshStatus();
  }
}

async function gpuPowerOff() {
  const btnStart = document.getElementById('gpu-btn-start');
  const btnStop = document.getElementById('gpu-btn-stop');

  if (!confirm('GPU-Instanz stoppen?')) {
    return;
  }

  try {
    btnStart.disabled = true;
    btnStop.disabled = true;
    btnStop.innerHTML = '<span class="gpu-spinner"></span> Stoppt...';

    const result = await gpuFetch('/power/off', {
      method: 'POST',
      body: JSON.stringify({}),
    });

    const msg = result.session_runtime_minutes
      ? `GPU gestoppt. Session: ${result.session_runtime_minutes.toFixed(1)} min, $${result.session_cost_usd.toFixed(3)}`
      : 'GPU gestoppt';

    showNotification(msg, 'success');
    await gpuRefreshStatus();

    // Stop polling
    stopGpuStatusPolling();

  } catch (error) {
    showNotification('GPU Stop fehlgeschlagen: ' + error.message, 'error');
    await gpuRefreshStatus();
  } finally {
    btnStop.innerHTML = `
      <svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 10a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z"/>
      </svg>
      Stoppen
    `;
  }
}

async function loadGpuAuditLog() {
  try {
    const entries = await gpuFetch('/audit?limit=20');
    const container = document.getElementById('gpu-audit-log');

    if (!entries || entries.length === 0) {
      container.innerHTML = '<div class="gpu-audit-entry">Keine Eintraege</div>';
      return;
    }

    container.innerHTML = entries.map(entry => {
      const time = new Date(entry.ts).toLocaleString('de-DE', {
        hour: '2-digit',
        minute: '2-digit',
        day: '2-digit',
        month: '2-digit',
      });
      return `
        <div class="gpu-audit-entry">
          <span class="gpu-audit-time">${time}</span>
          <span class="gpu-audit-event">${entry.event}</span>
        </div>
      `;
    }).join('');

  } catch (error) {
    console.error('Failed to load audit log:', error);
  }
}

function formatGpuStatus(status) {
  const statusMap = {
    'running': 'Laeuft',
    'stopped': 'Gestoppt',
    'exited': 'Beendet',
    'loading': 'Laedt...',
    'scheduling': 'Plane...',
    'creating': 'Erstelle...',
    'unconfigured': 'Nicht konfiguriert',
    'not_found': 'Nicht gefunden',
    'unknown': 'Unbekannt',
    'error': 'Fehler',
  };
  return statusMap[status] || status;
}

function formatRuntime(hours) {
  const h = Math.floor(hours);
  const m = Math.round((hours - h) * 60);
  return `${h}h ${m}m`;
}

function startGpuStatusPolling() {
  stopGpuStatusPolling();
  gpuStatusInterval = setInterval(gpuRefreshStatus, 30000); // Every 30s
}

function stopGpuStatusPolling() {
  if (gpuStatusInterval) {
    clearInterval(gpuStatusInterval);
    gpuStatusInterval = null;
  }
}

function showNotification(message, type = 'info') {
  // Use existing notification system if available
  if (window.showToast) {
    window.showToast(message, type);
    return;
  }

  // Fallback
  alert(message);
}

// Initialize when GPU tab is activated
document.addEventListener('DOMContentLoaded', () => {
  const gpuTab = document.querySelector('.admin-tab[data-tab="gpu"]');
  if (gpuTab) {
    gpuTab.addEventListener('click', () => {
      gpuRefreshStatus();
      startGpuStatusPolling();
    });
  }
});
"""
