import { LitElement, html, css, property, state, customElement } from './plugins.js';
import type { CSSResult, TemplateResult } from './plugins.js';
import { sharedStyles, panelStyles, gaugeStyles, buttonStyles, speedtestStyles } from './sw-dash-styles.js';
import { SwDashTable } from './sw-dash-table.js';

export interface IMetricsData {
  cache: {
    hits: number;
    misses: number;
    errors: number;
    bytesServedFromCache: number;
    bytesFetched: number;
    averageResponseTime: number;
  };
  network: {
    totalRequests: number;
    successfulRequests: number;
    failedRequests: number;
    timeouts: number;
    averageLatency: number;
    totalBytesTransferred: number;
  };
  update: {
    totalChecks: number;
    successfulChecks: number;
    failedChecks: number;
    updatesFound: number;
    updatesApplied: number;
    lastCheckTimestamp: number;
    lastUpdateTimestamp: number;
  };
  connection: {
    connectedClients: number;
    totalConnectionAttempts: number;
    successfulConnections: number;
    failedConnections: number;
  };
  speedtest: {
    lastDownloadSpeedMbps: number;
    lastUploadSpeedMbps: number;
    lastLatencyMs: number;
    lastTestTimestamp: number;
    testCount: number;
    isOnline: boolean;
  };
  startTime: number;
  uptime: number;
  cacheHitRate: number;
  networkSuccessRate: number;
  resourceCount: number;
}

/**
 * Overview panel component with metrics gauges and stats
 */
@customElement('sw-dash-overview')
export class SwDashOverview extends LitElement {
  public static styles: CSSResult[] = [
    sharedStyles,
    panelStyles,
    gaugeStyles,
    buttonStyles,
    speedtestStyles,
    css`
      :host {
        display: block;
      }

      .panel-content {
        padding: var(--space-4);
      }

      .section-divider {
        margin-top: var(--space-4);
        padding-top: var(--space-4);
        border-top: 1px solid var(--border-muted);
      }
    `
  ];

  @property({ type: Object }) accessor metrics: IMetricsData | null = null;
  @property({ type: Number }) accessor eventCountLastHour = 0;
  @state() accessor speedtestRunning = false;
  @state() accessor speedtestPhase: 'idle' | 'latency' | 'download' | 'upload' | 'complete' = 'idle';
  @state() accessor speedtestProgress = 0;
  @state() accessor speedtestElapsed = 0;

  // Speedtest timing constants (must match service worker)
  private static readonly TEST_DURATION_MS = 5000;  // 5 seconds per test
  private progressInterval: number | null = null;

  private async runSpeedtest(): Promise<void> {
    if (this.speedtestRunning) return;
    this.speedtestRunning = true;
    this.speedtestPhase = 'latency';
    this.speedtestProgress = 0;
    this.speedtestElapsed = 0;

    // Start progress animation (total ~10.5s: latency ~0.5s + 5s download + 5s upload)
    const totalEstimatedMs = 10500;
    const startTime = Date.now();

    this.progressInterval = window.setInterval(() => {
      this.speedtestElapsed = Date.now() - startTime;
      this.speedtestProgress = Math.min(100, (this.speedtestElapsed / totalEstimatedMs) * 100);

      // Estimate phase based on elapsed time
      if (this.speedtestElapsed < 500) {
        this.speedtestPhase = 'latency';
      } else if (this.speedtestElapsed < 5500) {
        this.speedtestPhase = 'download';
      } else {
        this.speedtestPhase = 'upload';
      }
    }, 100);

    try {
      const response = await fetch('/sw-dash/speedtest');
      const result = await response.json();

      this.speedtestPhase = 'complete';
      this.speedtestProgress = 100;

      // Dispatch event to parent to update metrics
      this.dispatchEvent(new CustomEvent('speedtest-complete', {
        detail: result,
        bubbles: true,
        composed: true
      }));
    } catch (err) {
      console.error('Speedtest failed:', err);
      this.speedtestPhase = 'idle';
    } finally {
      if (this.progressInterval) {
        window.clearInterval(this.progressInterval);
        this.progressInterval = null;
      }
      // Keep showing complete state briefly, then reset
      setTimeout(() => {
        this.speedtestRunning = false;
        this.speedtestPhase = 'idle';
        this.speedtestProgress = 0;
      }, 1500);
    }
  }

  private getPhaseLabel(): string {
    switch (this.speedtestPhase) {
      case 'latency': return 'Testing latency';
      case 'download': return 'Download test';
      case 'upload': return 'Upload test';
      case 'complete': return 'Complete';
      default: return '';
    }
  }

  private formatElapsed(): string {
    const seconds = Math.floor(this.speedtestElapsed / 1000);
    return `${seconds}s`;
  }

  public render(): TemplateResult {
    if (!this.metrics) {
      return html`<div class="panel"><div class="panel-content">Loading metrics...</div></div>`;
    }

    const m = this.metrics;
    const gaugeClass = SwDashTable.getGaugeClass;

    return html`
      <div class="grid">
        <!-- Cache Panel -->
        <div class="panel">
          <div class="panel-title">Cache</div>
          <div class="panel-content">
            <div class="gauge">
              <div class="gauge-header">
                <span class="gauge-label">Hit Rate</span>
                <span class="gauge-value">${m.cacheHitRate}%</span>
              </div>
              <div class="gauge-bar">
                <div class="gauge-fill ${gaugeClass(m.cacheHitRate)}" style="width: ${m.cacheHitRate}%"></div>
              </div>
            </div>
            <div class="row"><span class="label">Hits</span><span class="value success">${SwDashTable.formatNumber(m.cache.hits)}</span></div>
            <div class="row"><span class="label">Misses</span><span class="value warning">${SwDashTable.formatNumber(m.cache.misses)}</span></div>
            <div class="row"><span class="label">Errors</span><span class="value ${m.cache.errors > 0 ? 'error' : ''}">${SwDashTable.formatNumber(m.cache.errors)}</span></div>
            <div class="row"><span class="label">From Cache</span><span class="value">${SwDashTable.formatBytes(m.cache.bytesServedFromCache)}</span></div>
            <div class="row"><span class="label">Fetched</span><span class="value">${SwDashTable.formatBytes(m.cache.bytesFetched)}</span></div>
            <div class="row"><span class="label">Resources</span><span class="value">${m.resourceCount}</span></div>
          </div>
        </div>

        <!-- Network Panel -->
        <div class="panel">
          <div class="panel-title">Network</div>
          <div class="panel-content">
            <div class="gauge">
              <div class="gauge-header">
                <span class="gauge-label">Success Rate</span>
                <span class="gauge-value">${m.networkSuccessRate}%</span>
              </div>
              <div class="gauge-bar">
                <div class="gauge-fill ${gaugeClass(m.networkSuccessRate)}" style="width: ${m.networkSuccessRate}%"></div>
              </div>
            </div>
            <div class="row"><span class="label">Total Requests</span><span class="value">${SwDashTable.formatNumber(m.network.totalRequests)}</span></div>
            <div class="row"><span class="label">Successful</span><span class="value success">${SwDashTable.formatNumber(m.network.successfulRequests)}</span></div>
            <div class="row"><span class="label">Failed</span><span class="value ${m.network.failedRequests > 0 ? 'error' : ''}">${SwDashTable.formatNumber(m.network.failedRequests)}</span></div>
            <div class="row"><span class="label">Timeouts</span><span class="value ${m.network.timeouts > 0 ? 'warning' : ''}">${SwDashTable.formatNumber(m.network.timeouts)}</span></div>
            <div class="row"><span class="label">Avg Latency</span><span class="value">${m.network.averageLatency}ms</span></div>
            <div class="row"><span class="label">Transferred</span><span class="value">${SwDashTable.formatBytes(m.network.totalBytesTransferred)}</span></div>
          </div>
        </div>

        <!-- Updates Panel -->
        <div class="panel">
          <div class="panel-title">Updates</div>
          <div class="panel-content">
            <div class="row"><span class="label">Total Checks</span><span class="value">${SwDashTable.formatNumber(m.update.totalChecks)}</span></div>
            <div class="row"><span class="label">Successful</span><span class="value success">${SwDashTable.formatNumber(m.update.successfulChecks)}</span></div>
            <div class="row"><span class="label">Failed</span><span class="value ${m.update.failedChecks > 0 ? 'error' : ''}">${SwDashTable.formatNumber(m.update.failedChecks)}</span></div>
            <div class="row"><span class="label">Updates Found</span><span class="value">${SwDashTable.formatNumber(m.update.updatesFound)}</span></div>
            <div class="row"><span class="label">Updates Applied</span><span class="value success">${SwDashTable.formatNumber(m.update.updatesApplied)}</span></div>
            <div class="row"><span class="label">Last Check</span><span class="value">${SwDashTable.formatTimestamp(m.update.lastCheckTimestamp)}</span></div>
          </div>
        </div>

        <!-- Connections Panel -->
        <div class="panel">
          <div class="panel-title">Connections</div>
          <div class="panel-content">
            <div class="row"><span class="label">Active Clients</span><span class="value success">${SwDashTable.formatNumber(m.connection.connectedClients)}</span></div>
            <div class="row"><span class="label">Total Attempts</span><span class="value">${SwDashTable.formatNumber(m.connection.totalConnectionAttempts)}</span></div>
            <div class="row"><span class="label">Successful</span><span class="value success">${SwDashTable.formatNumber(m.connection.successfulConnections)}</span></div>
            <div class="row"><span class="label">Failed</span><span class="value ${m.connection.failedConnections > 0 ? 'error' : ''}">${SwDashTable.formatNumber(m.connection.failedConnections)}</span></div>
            <div class="section-divider">
              <div class="row"><span class="label">Events (1h)</span><span class="value">${this.eventCountLastHour}</span></div>
              <div class="row"><span class="label">Started</span><span class="value">${SwDashTable.formatTimestamp(m.startTime)}</span></div>
            </div>
          </div>
        </div>

        <!-- Speedtest Panel -->
        <div class="panel">
          <div class="panel-title">Speedtest</div>
          <div class="panel-content">
            <div class="online-indicator ${m.speedtest.isOnline ? 'online' : 'offline'}">
              <span class="online-dot"></span>
              <span>${m.speedtest.isOnline ? 'Online' : 'Offline'}</span>
            </div>
            ${this.speedtestRunning ? html`
              <div class="speedtest-progress">
                <div class="progress-header">
                  <span class="progress-phase">${this.getPhaseLabel()}</span>
                  <span class="progress-time">${this.formatElapsed()}</span>
                </div>
                <div class="progress-bar">
                  <div class="progress-fill ${this.speedtestPhase === 'complete' ? 'complete' : ''}" style="width: ${this.speedtestProgress}%"></div>
                </div>
              </div>
            ` : html`
              <div class="speedtest-results">
                <div class="speedtest-metric">
                  <div class="speedtest-value">${m.speedtest.lastDownloadSpeedMbps.toFixed(1)}</div>
                  <div class="speedtest-unit">Mbps</div>
                  <div class="speedtest-label">Download</div>
                </div>
                <div class="speedtest-metric">
                  <div class="speedtest-value">${m.speedtest.lastUploadSpeedMbps.toFixed(1)}</div>
                  <div class="speedtest-unit">Mbps</div>
                  <div class="speedtest-label">Upload</div>
                </div>
                <div class="speedtest-metric">
                  <div class="speedtest-value">${m.speedtest.lastLatencyMs.toFixed(0)}</div>
                  <div class="speedtest-unit">ms</div>
                  <div class="speedtest-label">Latency</div>
                </div>
              </div>
            `}
            <div class="btn-row">
              <button class="btn btn-secondary" ?disabled="${this.speedtestRunning}" @click="${this.runSpeedtest}">
                ${this.speedtestRunning ? 'Testing...' : 'Run Test'}
              </button>
            </div>
          </div>
        </div>
      </div>
    `;
  }
}
