/**
 * ds-test-results.js
 * Test results viewer with polling for Jest/test runner output
 */

import toolBridge from '../../services/tool-bridge.js';
import { ComponentHelpers } from '../../utils/component-helpers.js';

class DSTestResults extends HTMLElement {
  constructor() {
    super();
    this.testResults = null;
    this.isRunning = false;
    this.pollInterval = null;
    this.autoRefresh = false;
  }

  async connectedCallback() {
    this.render();
    this.setupEventListeners();
    await this.loadTestResults();
  }

  disconnectedCallback() {
    if (this.pollInterval) {
      clearInterval(this.pollInterval);
    }
  }

  setupEventListeners() {
    const runBtn = this.querySelector('#run-tests-btn');
    if (runBtn) {
      runBtn.addEventListener('click', () => this.runTests());
    }

    const refreshBtn = this.querySelector('#refresh-tests-btn');
    if (refreshBtn) {
      refreshBtn.addEventListener('click', () => this.loadTestResults());
    }

    const autoRefreshToggle = this.querySelector('#auto-refresh-tests');
    if (autoRefreshToggle) {
      autoRefreshToggle.addEventListener('change', (e) => {
        this.autoRefresh = e.target.checked;
        if (this.autoRefresh) {
          this.pollInterval = setInterval(() => this.loadTestResults(), 3000);
        } else {
          if (this.pollInterval) {
            clearInterval(this.pollInterval);
            this.pollInterval = null;
          }
        }
      });
    }
  }

  /**
   * Load test results from localStorage or file system
   * In a real implementation, this would call an MCP tool to read test output files
   */
  async loadTestResults() {
    const content = this.querySelector('#test-results-content');
    if (!content) return;

    try {
      // Try to load from localStorage (mock data for now)
      const stored = localStorage.getItem('ds-test-results');
      if (stored) {
        this.testResults = JSON.parse(stored);
        this.renderResults();
      } else {
        // No results yet
        content.innerHTML = ComponentHelpers.renderEmpty(
          'No test results available. Run tests to see results.',
          '🧪'
        );
      }
    } catch (error) {
      console.error('Failed to load test results:', error);
      content.innerHTML = ComponentHelpers.renderError('Failed to load test results', error);
    }
  }

  /**
   * Run tests (would call npm test or similar via MCP)
   */
  async runTests() {
    if (this.isRunning) return;

    this.isRunning = true;
    const runBtn = this.querySelector('#run-tests-btn');

    if (runBtn) {
      runBtn.disabled = true;
      runBtn.textContent = '🧪 Running Tests...';
    }

    const content = this.querySelector('#test-results-content');
    if (content) {
      content.innerHTML = ComponentHelpers.renderLoading('Running tests...');
    }

    try {
      // MVP1: Execute real npm test command via MCP
      // Note: This requires project configuration with test scripts
      const context = toolBridge.getContext();

      // Call backend API to run tests
      // The backend will execute `npm test` and return parsed results
      const response = await fetch('/api/test/run', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          projectId: context.projectId,
          testCommand: 'npm test'
        })
      });

      if (!response.ok) {
        throw new Error(`Test execution failed: ${response.statusText}`);
      }

      const testResults = await response.json();

      // Validate results structure
      if (!testResults || !testResults.summary) {
        throw new Error('Invalid test results format');
      }

      this.testResults = {
        ...testResults,
        timestamp: new Date().toISOString()
      };

      // Save to localStorage for offline viewing
      localStorage.setItem('ds-test-results', JSON.stringify(this.testResults));

      this.renderResults();

      ComponentHelpers.showToast?.(
        `Tests completed: ${this.testResults.summary.passed}/${this.testResults.summary.total} passed`,
        this.testResults.summary.failed > 0 ? 'error' : 'success'
      );
    } catch (error) {
      console.error('Failed to run tests:', error);
      ComponentHelpers.showToast?.(`Test execution failed: ${error.message}`, 'error');

      if (content) {
        content.innerHTML = ComponentHelpers.renderError('Test execution failed', error);
      }
    } finally {
      this.isRunning = false;
      if (runBtn) {
        runBtn.disabled = false;
        runBtn.textContent = '🧪 Run Tests';
      }
    }
  }

  getStatusIcon(status) {
    const icons = {
      passed: '✅',
      failed: '❌',
      skipped: '⏭️'
    };
    return icons[status] || '⚪';
  }

  getStatusBadge(status) {
    const types = {
      passed: 'success',
      failed: 'error',
      skipped: 'warning'
    };
    return ComponentHelpers.createBadge(status, types[status] || 'info');
  }

  renderResults() {
    const content = this.querySelector('#test-results-content');
    if (!content || !this.testResults) return;

    const { summary, suites, coverage, timestamp } = this.testResults;

    // Calculate pass rate
    const passRate = ((summary.passed / summary.total) * 100).toFixed(1);

    content.innerHTML = `
      <!-- Summary Stats -->
      <div style="background-color: var(--vscode-sidebar); border: 1px solid var(--vscode-border); border-radius: 4px; padding: 16px; margin-bottom: 16px;">
        <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
          <h4 style="font-size: 12px; font-weight: 600;">Test Summary</h4>
          ${summary.failed === 0 ? ComponentHelpers.createBadge('All Tests Passed', 'success') : ComponentHelpers.createBadge(`${summary.failed} Failed`, 'error')}
        </div>

        <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 16px; font-size: 11px; margin-bottom: 12px;">
          <div style="text-align: center;">
            <div style="font-size: 24px; font-weight: 600; color: var(--vscode-text);">${summary.total}</div>
            <div style="color: var(--vscode-text-dim); margin-top: 4px;">Total Tests</div>
          </div>
          <div style="text-align: center;">
            <div style="font-size: 24px; font-weight: 600; color: #89d185;">${summary.passed}</div>
            <div style="color: var(--vscode-text-dim); margin-top: 4px;">Passed</div>
          </div>
          <div style="text-align: center;">
            <div style="font-size: 24px; font-weight: 600; color: #f48771;">${summary.failed}</div>
            <div style="color: var(--vscode-text-dim); margin-top: 4px;">Failed</div>
          </div>
          <div style="text-align: center;">
            <div style="font-size: 24px; font-weight: 600; color: #ffbf00;">${summary.skipped}</div>
            <div style="color: var(--vscode-text-dim); margin-top: 4px;">Skipped</div>
          </div>
          <div style="text-align: center;">
            <div style="font-size: 24px; font-weight: 600; color: var(--vscode-text);">${passRate}%</div>
            <div style="color: var(--vscode-text-dim); margin-top: 4px;">Pass Rate</div>
          </div>
          <div style="text-align: center;">
            <div style="font-size: 24px; font-weight: 600; color: var(--vscode-text);">${summary.duration}s</div>
            <div style="color: var(--vscode-text-dim); margin-top: 4px;">Duration</div>
          </div>
        </div>

        <div style="font-size: 10px; color: var(--vscode-text-dim);">
          Last run: ${ComponentHelpers.formatRelativeTime(new Date(timestamp))}
        </div>
      </div>

      ${coverage ? `
        <!-- Coverage Stats -->
        <div style="background-color: var(--vscode-sidebar); border: 1px solid var(--vscode-border); border-radius: 4px; padding: 16px; margin-bottom: 16px;">
          <h4 style="font-size: 12px; font-weight: 600; margin-bottom: 12px;">Code Coverage</h4>

          <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px;">
            ${this.renderCoverageBar('Lines', coverage.lines)}
            ${this.renderCoverageBar('Functions', coverage.functions)}
            ${this.renderCoverageBar('Branches', coverage.branches)}
            ${this.renderCoverageBar('Statements', coverage.statements)}
          </div>
        </div>
      ` : ''}

      <!-- Test Suites -->
      <div style="background-color: var(--vscode-sidebar); border: 1px solid var(--vscode-border); border-radius: 4px; padding: 16px;">
        <h4 style="font-size: 12px; font-weight: 600; margin-bottom: 12px;">Test Suites</h4>

        ${suites.map(suite => this.renderSuite(suite)).join('')}
      </div>
    `;
  }

  renderCoverageBar(label, percentage) {
    let color = '#f48771'; // Red
    if (percentage >= 80) color = '#89d185'; // Green
    else if (percentage >= 60) color = '#ffbf00'; // Yellow

    return `
      <div>
        <div style="display: flex; justify-content: space-between; margin-bottom: 4px; font-size: 11px;">
          <span>${label}</span>
          <span style="font-weight: 600;">${percentage}%</span>
        </div>
        <div style="height: 8px; background-color: var(--vscode-bg); border-radius: 4px; overflow: hidden;">
          <div style="height: 100%; width: ${percentage}%; background-color: ${color}; transition: width 0.3s;"></div>
        </div>
      </div>
    `;
  }

  renderSuite(suite) {
    const suiteId = `suite-${suite.name.replace(/\s+/g, '-').toLowerCase()}`;
    const passedCount = suite.tests.filter(t => t.status === 'passed').length;
    const failedCount = suite.tests.filter(t => t.status === 'failed').length;

    return `
      <div style="margin-bottom: 16px; border: 1px solid var(--vscode-border); border-radius: 4px; overflow: hidden;">
        <div
          style="padding: 12px; background-color: var(--vscode-bg); cursor: pointer; display: flex; justify-content: space-between; align-items: center;"
          onclick="document.getElementById('${suiteId}').style.display = document.getElementById('${suiteId}').style.display === 'none' ? 'block' : 'none'"
        >
          <div>
            <div style="font-size: 12px; font-weight: 600; margin-bottom: 4px;">${ComponentHelpers.escapeHtml(suite.name)}</div>
            <div style="font-size: 10px; color: var(--vscode-text-dim);">
              ${passedCount} passed, ${failedCount} failed of ${suite.tests.length} tests
            </div>
          </div>
          <div style="font-size: 18px;">▼</div>
        </div>

        <div id="${suiteId}" style="display: none;">
          ${suite.tests.map(test => this.renderTest(test)).join('')}
        </div>
      </div>
    `;
  }

  renderTest(test) {
    const icon = this.getStatusIcon(test.status);
    const badge = this.getStatusBadge(test.status);

    return `
      <div style="padding: 12px; border-top: 1px solid var(--vscode-border); display: flex; justify-content: space-between; align-items: start;">
        <div style="flex: 1;">
          <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 4px;">
            <span style="font-size: 14px;">${icon}</span>
            <span style="font-size: 11px; font-family: 'Courier New', monospace;">${ComponentHelpers.escapeHtml(test.name)}</span>
            ${badge}
          </div>

          ${test.error ? `
            <div style="margin-top: 8px; padding: 8px; background-color: rgba(244, 135, 113, 0.1); border-left: 3px solid #f48771; border-radius: 2px;">
              <div style="font-size: 10px; font-family: 'Courier New', monospace; color: #f48771;">
                ${ComponentHelpers.escapeHtml(test.error)}
              </div>
            </div>
          ` : ''}
        </div>

        <div style="font-size: 10px; color: var(--vscode-text-dim); white-space: nowrap; margin-left: 12px;">
          ${test.duration}s
        </div>
      </div>
    `;
  }

  render() {
    this.innerHTML = `
      <div style="padding: 16px; height: 100%; display: flex; flex-direction: column;">
        <div style="margin-bottom: 16px; display: flex; gap: 12px; align-items: center; justify-content: flex-end;">
          <label style="display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--vscode-text);">
            <input type="checkbox" id="auto-refresh-tests" />
            Auto-refresh
          </label>
          <button id="refresh-tests-btn" class="button" style="padding: 4px 12px; font-size: 11px;">
            🔄 Refresh
          </button>
          <button id="run-tests-btn" class="button" style="padding: 4px 12px; font-size: 11px;">
            🧪 Run Tests
          </button>
        </div>

        <div id="test-results-content" style="flex: 1; overflow-y: auto;">
          ${ComponentHelpers.renderLoading('Loading test results...')}
        </div>
      </div>
    `;
  }
}

customElements.define('ds-test-results', DSTestResults);

export default DSTestResults;
