/**
 * @moduleName: Results Modal Component - Quiz Completion Display
 * @version: 2.0.0
 * @since: 2025-07-21
 * @lastUpdated: 2025-07-27
 * @projectSummary: Enhanced MCP Quiz Server - Modal component displaying quiz results with score, grade, and question breakdown
 * @techStack: TypeScript, Component Architecture, Modal UI, DOM Manipulation
 * @dependency: Component base class, AppStore, QuizResult types, utility functions
 * @interModuleDependency: AppStore for state management, DOMUtils, QuizUtils for formatting
 * @requirementsTraceability:
 *   {@link Requirements.REQ_UI_005} (Progress Visualization)
 *   {@link Requirements.REQ_INTEGRATION_001} (Results Display)
 * @briefDescription: Modal component managing quiz completion display with scores, grades, question feedback, and user actions
 * @methods: render, show, hide, bindEvents, displayResults, formatScore, handleRetake
 * @contributors: GitHub Copilot, Results Display Team
 * @examples:
 *   - const resultsModal = new ResultsModal()
 *   - resultsModal.show() // Display quiz results
 *   - resultsModal.displayResults(quizResult) // Show specific results
 * @vulnerabilitiesAssessment: Modal z-index management, XSS prevention in result display, accessibility compliance
 */

import { AppStore } from '../store/AppStore';
import { AppState } from '../types/index';
import { DOMUtils, QuizUtils } from '../utils/index';
import { Component } from './Component';

/**
 * Represents a modal component that displays quiz results to the user.
 *
 * The `ResultsModal` class manages the display and interaction logic for showing
 * quiz results, including the user's score, grade, and a breakdown of each question.
 * It subscribes to application state changes, renders result details, and provides
 * actions for retaking the quiz or closing the modal.
 *
 * @remarks
 * - Extends the base `Component` class.
 * - Listens to state changes from the `AppStore` singleton.
 * - Handles modal animations and accessibility features.
 * - Dynamically generates result summaries and binds UI events.
 *
 * @example
 * ```typescript
 * const resultsModal = new ResultsModal();
 * resultsModal.showResult(resultData);
 * ```
 */
export class ResultsModal extends Component {
  private store: AppStore;
  private unsubscribe: (() => void) | null = null;
  private currentResult: any = null;

  constructor() {
    super('#result-modal');
    this.store = AppStore.getInstance();
  }

  protected onMount(): void {
    this.unsubscribe = this.store.subscribe(state => this.onStateChange(state));
  }

  protected onUnmount(): void {
    this.unsubscribe?.();
  }

  protected bindEvents(): void {
    // Close modal on backdrop click
    this.element.addEventListener('click', e => {
      if (e.target === this.element) {
        this.store.hideResults();
      }
    });

    // Keyboard shortcuts
    document.addEventListener('keydown', e => {
      if (e.key === 'Escape') {
        this.store.hideResults();
      }
    });

    // Close button
    document.querySelector('#close-results-btn')?.addEventListener('click', () => {
      this.store.hideResults();
    });
  }

  private onStateChange(state: AppState): void {
    if (state.ui.showResults && state.currentQuiz) {
      this.show();
      this.render();
    } else {
      this.hide();
    }
  }

  protected render(): void {
    const state = this.store.getState();
    if (!state.currentQuiz) return;

    // Use actual result data if available, otherwise create from state
    const result = state.lastResult || this.createResultFromState(state);
    this.currentResult = result;

    const resultContainer = this.element.querySelector('#result-container');
    if (!resultContainer) return;

    const percentage = Math.round(
      (this.currentResult.score / this.currentResult.totalQuestions) * 100
    );
    const grade = QuizUtils.getGrade(percentage);

    // Use feedback data if available (from enhanced server response), otherwise fallback to results
    const feedbackData = this.currentResult.feedback || this.currentResult.results || [];

    const resultsHtml =
      feedbackData
        ?.map((questionResult: any, index: number) => {
          const isCorrect = questionResult.isCorrect;
          const bgColor = isCorrect
            ? 'bg-green-50 dark:bg-green-900/20'
            : 'bg-red-50 dark:bg-red-900/20';
          const borderColor = isCorrect
            ? 'border-green-200 dark:border-green-800'
            : 'border-red-200 dark:border-red-800';
          const iconColor = isCorrect
            ? 'text-green-600 dark:text-green-400'
            : 'text-red-600 dark:text-red-400';

          return `
                <div class="p-3 md:p-4 rounded-lg border ${borderColor} ${bgColor}">
                    <div class="flex items-start gap-3 mb-2">
                        <i data-lucide="${isCorrect ? 'check-circle' : 'x-circle'}"
                           class="w-4 h-4 md:w-5 md:h-5 ${iconColor} mt-1 flex-shrink-0"></i>
                        <div class="flex-1 min-w-0">
                            <p class="text-sm md:text-base font-medium text-surface-900 dark:text-surface-100 leading-snug">
                                ${index + 1}. ${DOMUtils.escapeHtml(questionResult.question)}
                            </p>
                        </div>
                    </div>

                    <div class="ml-7 md:ml-8 text-xs md:text-sm space-y-1.5">
                        <p class="text-surface-700 dark:text-surface-300">
                            <span class="font-medium">Your answer:</span>
                            <span class="${isCorrect ? 'text-green-700 dark:text-green-300' : 'text-red-700 dark:text-red-300'}">${DOMUtils.escapeHtml(questionResult.userAnswer)}</span>
                        </p>
                        ${
                          !isCorrect
                            ? `
                            <p class="text-surface-700 dark:text-surface-300">
                                <span class="font-medium">Correct answer:</span>
                                <span class="text-green-700 dark:text-green-300">${DOMUtils.escapeHtml(questionResult.correctAnswer)}</span>
                            </p>
                        `
                            : ''
                        }
                        ${
                          questionResult.explanation
                            ? `
                            <div class="mt-2 md:mt-3 p-2 md:p-3 bg-blue-50 dark:bg-blue-900/30 border-l-4 border-blue-400 dark:border-blue-500 rounded-r">
                                <div class="flex items-start gap-2">
                                    <i data-lucide="lightbulb" class="w-3 h-3 md:w-4 md:h-4 text-blue-600 dark:text-blue-400 mt-0.5 flex-shrink-0"></i>
                                    <div class="flex-1">
                                        <p class="text-xs md:text-sm font-medium text-blue-800 dark:text-blue-200 mb-1"> Explanation</p>
                                        <p class="text-xs md:text-sm text-blue-700 dark:text-blue-300 leading-relaxed">${DOMUtils.escapeHtml(questionResult.explanation)}</p>
                                    </div>
                                </div>
                            </div>
                        `
                            : ''
                        }
                    </div>
                </div>
            `;
        })
        .join('') || '';

    resultContainer.innerHTML = `
            <div class="text-center mb-6">
                <div class="inline-flex items-center justify-center w-16 h-16 bg-${grade.color}-100 dark:bg-${grade.color}-900/30 rounded-full mb-4">
                    <i data-lucide="${grade.icon}" class="w-8 h-8 text-${grade.color}-600 dark:text-${grade.color}-400"></i>
                </div>
                <h3 class="text-xl md:text-2xl font-bold text-surface-900 dark:text-surface-100 mb-2">${grade.text}</h3>
                <p class="text-surface-600 dark:text-surface-400 text-sm md:text-base">
                    You scored ${this.currentResult.score} out of ${this.currentResult.totalQuestions} questions
                </p>
                <div class="text-2xl md:text-3xl font-bold text-${grade.color}-600 dark:text-${grade.color}-400 mt-2">${percentage}%</div>
            </div>

            <div class="space-y-3 md:space-y-4">
                <h4 class="font-medium text-surface-900 dark:text-surface-100 text-sm md:text-base">Question Breakdown:</h4>
                ${resultsHtml}
            </div>
        `;

    // Update action buttons in footer
    const actionsContainer = this.element.querySelector('#result-actions');
    if (actionsContainer) {
      actionsContainer.innerHTML = `
                <div class="flex flex-col sm:flex-row gap-3">
                    <button id="retake-quiz-btn" class="flex-1 bg-primary-600 hover:bg-primary-700 text-white py-2.5 px-4 rounded-lg font-medium transition-colors text-sm md:text-base">
                        <i data-lucide="rotate-ccw" class="w-4 h-4 mr-2 inline"></i>
                        Retake Quiz
                    </button>
                    <button id="close-modal-btn" class="flex-1 bg-surface-200 hover:bg-surface-300 dark:bg-surface-600 dark:hover:bg-surface-500 text-surface-800 dark:text-surface-200 py-2.5 px-4 rounded-lg font-medium transition-colors text-sm md:text-base">
                        <i data-lucide="check" class="w-4 h-4 mr-2 inline"></i>
                        Done
                    </button>
                </div>
            `;
    }

    // Re-initialize icons and bind events
    this.reinitializeIcons();
    this.bindModalButtons();
  }

  /**
   * Generates a summary of quiz results based on the current application state.
   *
   * Iterates through each question in the current quiz, compares the user's answer to the correct answer,
   * and constructs a result object for each question including the question text, user's answer, correct answer,
   * correctness, and an optional explanation. Calculates the total score as the number of correct answers.
   *
   * @param state - The current application state containing quiz and user answer data.
   * @returns An object containing the user's score, total number of questions, and detailed results for each question,
   *          or `null` if there is no current quiz.
   */
  private createResultFromState(state: AppState): any {
    if (!state.currentQuiz) return null;

    const results = state.currentQuiz.questions.map(question => {
      const userAnswer = state.userAnswers[question.id] || '';
      const isCorrect = userAnswer === question.correctAnswer;

      return {
        question: question.question,
        userAnswer: userAnswer,
        correctAnswer: question.correctAnswer,
        isCorrect: isCorrect,
        explanation: question.explanation, // Include explanation if available
      };
    });

    const score = results.filter(r => r.isCorrect).length;

    return {
      score: score,
      totalQuestions: results.length,
      results: results,
    };
  }

  private bindModalButtons(): void {
    // Bind buttons in both containers (result-container and result-actions)
    const retakeBtn = this.element.querySelector('#retake-quiz-btn');
    const closeBtn = this.element.querySelector('#close-modal-btn');

    retakeBtn?.addEventListener('click', () => {
      this.store.hideResults();
      // Reset answers to retake quiz
      const state = this.store.getState();
      if (state.currentQuiz) {
        state.currentQuiz.questions.forEach(q => {
          this.store.updateAnswer(q.id, '');
        });
      }
    });

    closeBtn?.addEventListener('click', () => {
      this.store.hideResults();
    });
  }

  show(): void {
    this.element.classList.remove('hidden');
    this.element.classList.add('flex');

    // Trigger mobile slide-up animation
    requestAnimationFrame(() => {
      const modalContent = this.element.querySelector('.modal-content') as HTMLElement;
      if (modalContent) {
        modalContent.classList.remove('translate-y-full');
        // Reset opacity and transform for proper display
        modalContent.style.opacity = '1';
        modalContent.style.transform = 'scale(1)';
        modalContent.classList.add('scale-100');
      }
    });
  }

  /**
   * Hides the modal with an animation based on the device type.
   *
   * - On mobile devices (window width < 768px), slides the modal content down.
   * - On desktop devices, fades and scales down the modal content.
   * - After the animation (300ms), hides the modal element and resets styles.
   * - If modal content is not found, hides the modal immediately without animation.
   */
  hide(): void {
    const modalContent = this.element.querySelector('.modal-content') as HTMLElement;

    if (modalContent) {
      // Mobile: slide down, Desktop: fade out
      if (window.innerWidth < 768) {
        modalContent.classList.add('translate-y-full');
      } else {
        modalContent.style.transform = 'scale(0.95)';
        modalContent.style.opacity = '0';
      }

      // Wait for animation to complete
      setTimeout(() => {
        this.element.classList.add('hidden');
        this.element.classList.remove('flex');

        // Reset transforms
        modalContent.classList.remove('translate-y-full');
        modalContent.style.transform = '';
        modalContent.style.opacity = '';
      }, 300);
    } else {
      // Fallback without animation
      this.element.classList.add('hidden');
      this.element.classList.remove('flex');
    }
  }

  showResult(result: any): void {
    this.currentResult = result;
    this.show();
    this.render();
  }

  private reinitializeIcons(): void {
    if ((window as any).lucide?.createIcons) {
      (window as any).lucide.createIcons();
    }
  }
}

export default ResultsModal;
