/**
 * @fileoverview Dashboard Component - Modern MVVM Architecture
 * @version 1.0.0
 * @since 2025-08-04
 * @lastUpdated 2025-08-04
 * @module Dashboard
 * @description Main dashboard component with progressive enhancement and unified auth
 * @contributors Claude Code Agent
 * @dependencies Component base class, AuthManager, DashboardService
 * @requirements REQ-UI-001, REQ-AUTH-002 (Unified Dashboard)
 * @testCoverage Dashboard rendering, authentication integration, data loading
 */

import { DashboardService } from '../services/DashboardService';
import { AppStore } from '../store/AppStore';
import { AuthManager } from './AuthManager';
import { Component } from './Component';

/**
 * Dashboard Component
 *
 * @description Main dashboard component with progressive enhancement.
 *              Replaces server-generated HTML with modern TypeScript architecture.
 *
 * @example
 * ```typescript
 * const dashboard = new Dashboard();
 * dashboard.mount();
 * ```
 *
 * @since 2025-08-04
 * @author Claude Code Agent
 * @requirements REQ-UI-001 (Modern dashboard), REQ-AUTH-002 (Integrated auth)
 */
export class Dashboard extends Component {
  private authManager: AuthManager;
  private dashboardService: DashboardService;
  private appStore: AppStore;
  private unsubscribeStore: (() => void) | null = null;

  // Component state
  private isLoading = true;
  private dashboardData: any = null;
  private error: string | null = null;

  constructor() {
    // Mount to existing dashboard container or create new one
    if (!document.getElementById('dashboard-app')) {
      const container = document.createElement('div');
      container.id = 'dashboard-app';
      container.className = 'min-h-screen bg-gray-50';
      document.body.appendChild(container);
    }

    super('#dashboard-app');
    this.authManager = AuthManager.getInstance();
    this.dashboardService = new DashboardService();
    this.appStore = AppStore.getInstance();
  }

  /**
   * Initialize dashboard component
   *
   * @description Sets up authentication and loads dashboard data
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  protected async onMount(): Promise<void> {
    this.setupStoreSubscription();
    this.render(); // Initial render with loading state

    try {
      // Ensure authentication
      if (!this.authManager.isAuthenticated()) {
        const authenticated = await this.authManager.requireAuthentication();
        if (!authenticated) {
          this.redirectToLogin();
          return;
        }
      }

      // Load dashboard data
      await this.loadDashboardData();
    } catch (error) {
      console.error('Dashboard initialization failed:', error);
      this.error = 'Failed to load dashboard. Please try again.';
      this.isLoading = false;
      this.render();
    }
  }

  /**
   * Render dashboard UI
   *
   * @description Renders dashboard based on current state
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  protected render(): void {
    if (this.isLoading) {
      this.renderLoading();
    } else if (this.error) {
      this.renderError();
    } else {
      this.renderDashboard();
    }
  }

  /**
   * Bind dashboard event listeners
   *
   * @description Sets up event listeners for dashboard interactions
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  protected bindEvents(): void {
    // Create Quiz button
    const createQuizBtn = this.element.querySelector('.create-quiz-btn');
    createQuizBtn?.addEventListener('click', this.handleCreateQuiz.bind(this));

    // Refresh button
    const refreshBtn = this.element.querySelector('.refresh-btn');
    refreshBtn?.addEventListener('click', this.handleRefresh.bind(this));

    // Quiz list interactions
    this.bindQuizListEvents();
  }

  /**
   * Render loading state
   *
   * @description Shows loading spinner and message
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private renderLoading(): void {
    this.element.innerHTML = `
      <div class="dashboard-loading">
        <div class="min-h-screen flex items-center justify-center">
          <div class="text-center">
            <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div>
            <h2 class="text-lg font-medium text-gray-900 mb-2">Loading Dashboard</h2>
            <p class="text-gray-600">Please wait while we load your information...</p>
          </div>
        </div>
      </div>
    `;
  }

  /**
   * Render error state
   *
   * @description Shows error message with retry option
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private renderError(): void {
    this.element.innerHTML = `
      <div class="dashboard-error">
        <div class="min-h-screen flex items-center justify-center">
          <div class="text-center max-w-md mx-auto">
            <div class="text-red-500 mb-4">
              <svg class="w-16 h-16 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
              </svg>
            </div>
            <h2 class="text-xl font-semibold text-gray-900 mb-2">Dashboard Error</h2>
            <p class="text-gray-600 mb-6">${this.error}</p>
            <button class="retry-btn bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
              Try Again
            </button>
          </div>
        </div>
      </div>
    `;

    // Bind retry button
    const retryBtn = this.element.querySelector('.retry-btn');
    retryBtn?.addEventListener('click', this.handleRetry.bind(this));
  }

  /**
   * Render main dashboard
   *
   * @description Renders the complete dashboard interface
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private renderDashboard(): void {
    const user = this.authManager.getCurrentUser();
    const stats = this.dashboardData?.stats || {};
    const recentQuizzes = this.dashboardData?.recentQuizzes || [];

    this.element.innerHTML = `
      <div class="dashboard">
        <!-- Navigation -->
        <nav class="bg-white shadow-sm border-b">
          <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
            <div class="flex justify-between h-16">
              <div class="flex items-center">
                <h1 class="text-xl font-semibold text-gray-900">Quiz Dashboard</h1>
              </div>
              <div class="auth-container"></div>
            </div>
          </div>
        </nav>

        <!-- Main Content -->
        <main class="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
          <!-- Welcome Section -->
          <div class="mb-8">
            <h2 class="text-2xl font-bold text-gray-900 mb-2">
              Welcome back, ${user?.username || 'User'}!
            </h2>
            <p class="text-gray-600">Manage your quizzes and track your progress</p>
          </div>

          <!-- Quick Actions -->
          <div class="mb-8">
            <div class="flex flex-wrap gap-4">
              <button class="create-quiz-btn bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-lg font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 flex items-center">
                <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
                </svg>
                Create New Quiz
              </button>
              <button class="refresh-btn bg-gray-100 hover:bg-gray-200 text-gray-700 px-6 py-3 rounded-lg font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 flex items-center">
                <svg class="w-5 h-5 mr-2" 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"></path>
                </svg>
                Refresh
              </button>
            </div>
          </div>

          <!-- Dashboard Cards -->
          <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
            <!-- My Quizzes Card -->
            <div class="card bg-white rounded-lg shadow p-6">
              <div class="flex items-center justify-between mb-4">
                <h3 class="text-lg font-medium text-gray-900">My Quizzes</h3>
                <div class="text-3xl font-bold text-blue-600">${stats.totalQuizzes || 0}</div>
              </div>
              <p class="text-gray-600 text-sm mb-4">Total quizzes created</p>
              <a href="/dashboard/quizzes" class="text-blue-600 hover:text-blue-700 text-sm font-medium">
                View all →
              </a>
            </div>

            <!-- Recent Activity Card -->
            <div class="card bg-white rounded-lg shadow p-6">
              <div class="flex items-center justify-between mb-4">
                <h3 class="text-lg font-medium text-gray-900">Recent Activity</h3>
                <div class="text-3xl font-bold text-green-600">${stats.recentActivity || 0}</div>
              </div>
              <p class="text-gray-600 text-sm mb-4">Actions this week</p>
              <a href="/dashboard/analytics" class="text-green-600 hover:text-green-700 text-sm font-medium">
                View analytics →
              </a>
            </div>

            <!-- Profile Card -->
            <div class="card bg-white rounded-lg shadow p-6">
              <div class="flex items-center justify-between mb-4">
                <h3 class="text-lg font-medium text-gray-900">Profile</h3>
                <div class="w-12 h-12 bg-blue-600 rounded-full flex items-center justify-center">
                  <span class="text-white font-medium">${this.getUserInitials(user?.username)}</span>
                </div>
              </div>
              <p class="text-gray-600 text-sm mb-4">${user?.email || 'No email'}</p>
              <a href="/dashboard/profile" class="text-blue-600 hover:text-blue-700 text-sm font-medium">
                Manage profile →
              </a>
            </div>
          </div>

          <!-- Recent Quizzes -->
          <div class="bg-white rounded-lg shadow">
            <div class="px-6 py-4 border-b border-gray-200">
              <h3 class="text-lg font-medium text-gray-900">Recent Quizzes</h3>
            </div>
            <div class="quiz-list">
              ${this.renderQuizList(recentQuizzes)}
            </div>
          </div>
        </main>
      </div>
    `;

    // Mount auth manager in navigation
    const authContainer = this.element.querySelector('.auth-container');
    if (authContainer) {
      this.authManager.mount();
    }

    this.bindEvents();
  }

  /**
   * Render quiz list
   *
   * @description Renders list of recent quizzes
   *
   * @param {Array} quizzes - Array of quiz objects
   * @returns {string} HTML string for quiz list
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private renderQuizList(quizzes: any[]): string {
    if (!quizzes || quizzes.length === 0) {
      return `
        <div class="px-6 py-8 text-center">
          <div class="text-gray-400 mb-4">
            <svg class="w-12 h-12 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
            </svg>
          </div>
          <h4 class="text-lg font-medium text-gray-900 mb-2">No quizzes yet</h4>
          <p class="text-gray-600 mb-4">Get started by creating your first quiz</p>
          <button class="create-quiz-btn bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg font-medium transition-colors">
            Create Quiz
          </button>
        </div>
      `;
    }

    return quizzes
      .map(
        quiz => `
      <div class="quiz-item px-6 py-4 border-b border-gray-200 hover:bg-gray-50 transition-colors">
        <div class="flex items-center justify-between">
          <div class="flex-1">
            <h4 class="text-md font-medium text-gray-900 mb-1">${quiz.title}</h4>
            <p class="text-sm text-gray-600 mb-2">${quiz.description || 'No description'}</p>
            <div class="flex items-center text-xs text-gray-500 space-x-4">
              <span>${quiz.questions?.length || 0} questions</span>
              <span>Created ${this.formatDate(quiz.createdAt)}</span>
              <span class="quiz-status ${quiz.status}">${quiz.status || 'draft'}</span>
            </div>
          </div>
          <div class="flex items-center space-x-2">
            <button class="edit-quiz-btn text-blue-600 hover:text-blue-700 text-sm font-medium" data-quiz-id="${quiz.id}">
              Edit
            </button>
            <button class="view-quiz-btn text-green-600 hover:text-green-700 text-sm font-medium" data-quiz-id="${quiz.id}">
              View
            </button>
          </div>
        </div>
      </div>
    `
      )
      .join('');
  }

  /**
   * Setup app store subscription
   *
   * @description Subscribes to app store state changes
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private setupStoreSubscription(): void {
    this.unsubscribeStore = this.appStore.subscribe(state => {
      // Re-render if auth state changes
      if (!state.auth.isAuthenticated) {
        this.redirectToLogin();
      }
    });
  }

  /**
   * Load dashboard data
   *
   * @description Fetches dashboard data from API
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private async loadDashboardData(): Promise<void> {
    try {
      this.isLoading = true;
      this.render();

      const data = await this.dashboardService.getDashboardData();
      this.dashboardData = data;
      this.error = null;
    } catch (error) {
      console.error('Failed to load dashboard data:', error);
      this.error = 'Failed to load dashboard data. Please try again.';
    } finally {
      this.isLoading = false;
      this.render();
    }
  }

  /**
   * Handle create quiz action
   *
   * @description Navigates to quiz creation page
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private handleCreateQuiz(): void {
    // Navigate to quiz creation
    window.location.href = '/quiz/create';
  }

  /**
   * Handle refresh action
   *
   * @description Reloads dashboard data
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private async handleRefresh(): Promise<void> {
    await this.loadDashboardData();
  }

  /**
   * Handle retry action
   *
   * @description Retries dashboard initialization
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private async handleRetry(): Promise<void> {
    this.error = null;
    await this.onMount();
  }

  /**
   * Bind quiz list events
   *
   * @description Sets up event listeners for quiz list items
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private bindQuizListEvents(): void {
    // Edit quiz buttons
    const editButtons = this.element.querySelectorAll('.edit-quiz-btn');
    editButtons.forEach(btn => {
      btn.addEventListener('click', e => {
        const quizId = (e.target as HTMLElement).dataset.quizId;
        if (quizId) this.handleEditQuiz(quizId);
      });
    });

    // View quiz buttons
    const viewButtons = this.element.querySelectorAll('.view-quiz-btn');
    viewButtons.forEach(btn => {
      btn.addEventListener('click', e => {
        const quizId = (e.target as HTMLElement).dataset.quizId;
        if (quizId) this.handleViewQuiz(quizId);
      });
    });
  }

  /**
   * Handle edit quiz action
   *
   * @description Navigates to quiz editor
   *
   * @param {string} quizId - Quiz ID to edit
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private handleEditQuiz(quizId: string): void {
    window.location.href = `/quiz/edit/${quizId}`;
  }

  /**
   * Handle view quiz action
   *
   * @description Navigates to quiz viewer
   *
   * @param {string} quizId - Quiz ID to view
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private handleViewQuiz(quizId: string): void {
    window.location.href = `/quiz/view/${quizId}`;
  }

  /**
   * Get user initials
   *
   * @description Generates user initials for avatar
   *
   * @param {string} username - Username
   * @returns {string} User initials
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private getUserInitials(username?: string): string {
    if (!username) return 'U';

    const parts = username.split(/[\s@_.-]+/);
    if (parts.length >= 2) {
      return (parts[0][0] + parts[1][0]).toUpperCase();
    }

    return username.substring(0, 2).toUpperCase();
  }

  /**
   * Format date for display
   *
   * @description Formats date in user-friendly format
   *
   * @param {string | Date} date - Date to format
   * @returns {string} Formatted date
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private formatDate(date: string | Date): string {
    if (!date) return 'Unknown';

    const d = new Date(date);
    const now = new Date();
    const diffTime = Math.abs(now.getTime() - d.getTime());
    const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));

    if (diffDays === 1) return 'Today';
    if (diffDays === 2) return 'Yesterday';
    if (diffDays <= 7) return `${diffDays} days ago`;

    return d.toLocaleDateString();
  }

  /**
   * Redirect to login
   *
   * @description Redirects user to login page
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  private redirectToLogin(): void {
    window.location.href = '/auth/login.html';
  }

  /**
   * Clean up resources
   *
   * @description Removes subscriptions and event listeners
   *
   * @since 2025-08-04
   * @author Claude Code Agent
   */
  protected onUnmount(): void {
    this.unsubscribeStore?.();
  }
}
