/**
 * @moduleName: FeedbackManager
 * @version: 2.0.0
 * @since: 2025-07-26
 * @lastUpdated: 2025-07-26
 * @projectSummary: Enhanced MCP Quiz Server - Educational Feedback System
 * @techStack: TypeScript, DOM API, Animation API
 * @dependency: EventManagement, SettingsService
 * @interModuleDependency: EventManagement for cleanup, SettingsService for configuration
 * @requirementsTraceability:
 *   {@link Requirements.REQ_EDU_001} (Educational Feedback System for Enhanced Learning)
 *   {@link Requirements.REQ_UI_002} (Dual View Mode System - Cross-mode Support)
 * @briefDescription: Manages immediate feedback, explanations, and coaching modes for quiz interactions
 * @methods: showImmediateFeedback, showExplanation, enableCoachingMode, showCelebration
 * @contributors: GitHub Copilot
 * @examples:
 *   - const feedback = new FeedbackManager(settings); feedback.showImmediateFeedback(element, true);
 * @vulnerabilitiesAssessment: DOM manipulation with sanitization, no sensitive data exposure
 */

import { SettingsService } from '../../services/SettingsService';

export class FeedbackManager {
  private settingsService: SettingsService;
  private activeFeedback: Set<string> = new Set();

  constructor(settingsService: SettingsService) {
    this.settingsService = settingsService;
  }

  /**
   * Show immediate visual feedback for answer selection
   * @param element - The answer element that was selected
   * @param isCorrect - Whether the answer is correct
   * @param questionId - The question ID for tracking
   */
  showImmediateFeedback(element: Element, isCorrect: boolean, questionId: string): void {
    const settings = this.settingsService.getSettings();

    if (!settings.quiz.showImmediateFeedback) {
      return;
    }

    console.log(`💡 Showing immediate feedback: ${isCorrect ? 'Correct' : 'Incorrect'}`);

    // Remove any existing feedback classes
    this.clearFeedback(element);

    // Add appropriate feedback styling
    const feedbackClasses = isCorrect
      ? ['bg-green-100', 'border-green-500', 'dark:bg-green-900/20', 'animate-pulse']
      : ['bg-red-100', 'border-red-500', 'dark:bg-red-900/20', 'animate-pulse'];

    element.classList.add(...feedbackClasses);

    // Add visual indicator
    this.addFeedbackIcon(element, isCorrect);

    // Show coaching feedback if enabled
    if (settings.quiz.enableCoachingMode) {
      this.showCoachingFeedback(element, isCorrect, questionId);
    }

    // Show explanation if enabled and answer is selected
    if (settings.quiz.showExplanationsAfterAnswer) {
      setTimeout(() => {
        this.showExplanation(questionId, isCorrect);
      }, 800);
    }

    // Track active feedback
    this.activeFeedback.add(questionId);

    // Remove pulse animation after 2 seconds
    setTimeout(() => {
      element.classList.remove('animate-pulse');
    }, 2000);

    // Announce to screen readers
    this.announceToScreenReader(
      isCorrect ? 'Correct answer selected' : 'Incorrect answer selected'
    );
  }

  /**
   * Show explanation text for a question
   * @param questionId - The question to show explanation for
   * @param wasCorrect - Whether the user's answer was correct
   */
  showExplanation(questionId: string, wasCorrect: boolean): void {
    const settings = this.settingsService.getSettings();

    if (!settings.quiz.showExplanationsAfterAnswer) {
      return;
    }

    console.log(`📖 Showing explanation for question: ${questionId}`);

    // Find the question container
    const questionContainer = document.querySelector(`[data-question-id="${questionId}"]`);
    if (!questionContainer) {
      console.warn('⚠️ Question container not found for explanation');
      return;
    }

    // Check if explanation already exists
    const existingExplanation = questionContainer.querySelector('.explanation-container');
    if (existingExplanation) {
      return;
    }

    // Get explanation text (this would come from question data in real implementation)
    const explanationText = this.getExplanationText(questionId);

    if (!explanationText) {
      return;
    }

    // Create explanation container
    const explanationContainer = document.createElement('div');
    explanationContainer.className = `
      explanation-container mt-4 p-4 rounded-lg border-l-4
      ${
        wasCorrect
          ? 'bg-green-50 border-green-400 dark:bg-green-900/10 dark:border-green-500'
          : 'bg-blue-50 border-blue-400 dark:bg-blue-900/10 dark:border-blue-500'
      }
      animate-fadeIn
    `;

    explanationContainer.innerHTML = `
      <div class="flex items-start">
        <div class="flex-shrink-0">
          ${
            wasCorrect
              ? '<svg class="w-5 h-5 text-green-600 mt-0.5" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path></svg>'
              : '<svg class="w-5 h-5 text-blue-600 mt-0.5" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"></path></svg>'
          }
        </div>
        <div class="ml-3">
          <h4 class="text-sm font-medium ${wasCorrect ? 'text-green-800 dark:text-green-200' : 'text-blue-800 dark:text-blue-200'}">
            ${wasCorrect ? 'Great job!' : 'Learn more:'}
          </h4>
          <div class="mt-1 text-sm ${wasCorrect ? 'text-green-700 dark:text-green-300' : 'text-blue-700 dark:text-blue-300'}">
            ${explanationText}
          </div>
        </div>
      </div>
    `;

    // Add to question container
    questionContainer.appendChild(explanationContainer);

    // Add fade-in animation
    setTimeout(() => {
      explanationContainer.classList.add('opacity-100');
    }, 50);
  }

  /**
   * Show coaching-style feedback
   * @param element - The selected element
   * @param isCorrect - Whether the answer is correct
   * @param questionId - The question ID
   */
  showCoachingFeedback(element: Element, isCorrect: boolean, questionId: string): void {
    const settings = this.settingsService.getSettings();

    if (!settings.quiz.enableCoachingMode) {
      return;
    }

    console.log(`🏃‍♂️ Showing coaching feedback for: ${questionId}`);

    // Get coaching intensity setting
    const intensity = settings.quiz.coachingIntensity || 'detailed';

    const coachingMessages = this.getCoachingMessages(isCorrect, intensity);
    const message = coachingMessages[Math.floor(Math.random() * coachingMessages.length)];

    // Create coaching tooltip
    this.showCoachingTooltip(element, message, isCorrect);
  }

  /**
   * Show celebration effects for correct answers
   * @param element - The element to celebrate around
   * @param intensity - Celebration intensity ('subtle', 'normal', 'enthusiastic')
   */
  showCelebration(
    element: Element,
    intensity: 'subtle' | 'normal' | 'enthusiastic' = 'normal'
  ): void {
    console.log(`🎉 Showing ${intensity} celebration`);

    switch (intensity) {
      case 'subtle':
        this.showSubtleCelebration(element);
        break;
      case 'enthusiastic':
        this.showEnthusiasticCelebration(element);
        break;
      default:
        this.showNormalCelebration(element);
    }
  }

  /**
   * Clear feedback from an element
   * @param element - The element to clear feedback from
   */
  clearFeedback(element: Element): void {
    const feedbackClasses = [
      'bg-green-100',
      'border-green-500',
      'dark:bg-green-900/20',
      'bg-red-100',
      'border-red-500',
      'dark:bg-red-900/20',
      'animate-pulse',
    ];

    element.classList.remove(...feedbackClasses);

    // Remove feedback icons
    const feedbackIcon = element.querySelector('.feedback-icon');
    if (feedbackIcon) {
      feedbackIcon.remove();
    }
  }

  /**
   * Clear all active feedback
   */
  clearAllFeedback(): void {
    this.activeFeedback.forEach(questionId => {
      const questionContainer = document.querySelector(`[data-question-id="${questionId}"]`);
      if (questionContainer) {
        // Clear visual feedback
        const answerElements = questionContainer.querySelectorAll('.quiz-option-card, label');
        answerElements.forEach(element => this.clearFeedback(element));

        // Remove explanations
        const explanations = questionContainer.querySelectorAll('.explanation-container');
        explanations.forEach(explanation => explanation.remove());
      }
    });

    this.activeFeedback.clear();
    console.log('🧹 All feedback cleared');
  }

  /**
   * Add feedback icon to element
   */
  private addFeedbackIcon(element: Element, isCorrect: boolean): void {
    // Remove existing icon
    const existingIcon = element.querySelector('.feedback-icon');
    if (existingIcon) {
      existingIcon.remove();
    }

    const icon = document.createElement('div');
    icon.className =
      'feedback-icon absolute top-2 right-2 w-6 h-6 rounded-full flex items-center justify-center';

    if (isCorrect) {
      icon.classList.add('bg-green-500', 'text-white');
      icon.innerHTML =
        '<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path></svg>';
    } else {
      icon.classList.add('bg-red-500', 'text-white');
      icon.innerHTML =
        '<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>';
    }

    // Position the element relatively if it's not already
    if (getComputedStyle(element).position === 'static') {
      element.classList.add('relative');
    }

    element.appendChild(icon);
  }

  /**
   * Show coaching tooltip
   */
  private showCoachingTooltip(element: Element, message: string, isCorrect: boolean): void {
    const tooltip = document.createElement('div');
    tooltip.className = `
      coaching-tooltip absolute z-50 px-3 py-2 text-sm rounded-lg shadow-lg max-w-xs
      ${isCorrect ? 'bg-green-600 text-white' : 'bg-blue-600 text-white'}
      animate-fadeIn
    `;
    tooltip.textContent = message;

    // Position tooltip
    const rect = element.getBoundingClientRect();
    tooltip.style.top = `${rect.bottom + 8}px`;
    tooltip.style.left = `${rect.left}px`;

    document.body.appendChild(tooltip);

    // Remove tooltip after 3 seconds
    setTimeout(() => {
      tooltip.remove();
    }, 3000);
  }

  /**
   * Get explanation text for a question (placeholder - would fetch from question data)
   */
  private getExplanationText(questionId: string): string {
    // In a real implementation, this would fetch from the question data
    return "This explanation would be loaded from the question's explanation field.";
  }

  /**
   * Get coaching messages based on correctness and intensity
   */
  private getCoachingMessages(isCorrect: boolean, intensity: string): string[] {
    if (isCorrect) {
      switch (intensity) {
        case 'comprehensive':
          return ['Excellent work!', 'Outstanding!', 'Perfect!', 'You nailed it!'];
        case 'basic':
          return ['Correct', 'Good', 'Right'];
        default:
          return ['Great job!', 'Well done!', 'Correct!', 'Nice work!'];
      }
    } else {
      switch (intensity) {
        case 'comprehensive':
          return [
            'Not quite right, but keep trying!',
            'Good effort! Try again.',
            'Close! Give it another shot.',
          ];
        case 'basic':
          return ['Try again', 'Not correct'];
        default:
          return ['Not quite right', 'Try again!', 'Keep going!'];
      }
    }
  }

  /**
   * Show subtle celebration
   */
  private showSubtleCelebration(element: Element): void {
    element.classList.add('animate-bounce');
    setTimeout(() => {
      element.classList.remove('animate-bounce');
    }, 1000);
  }

  /**
   * Show normal celebration
   */
  private showNormalCelebration(element: Element): void {
    // Add celebration animation
    element.classList.add('animate-bounce');

    // Create success particles
    this.createSuccessParticles(element);

    setTimeout(() => {
      element.classList.remove('animate-bounce');
    }, 1500);
  }

  /**
   * Show enthusiastic celebration
   */
  private showEnthusiasticCelebration(element: Element): void {
    // Multiple animation effects
    element.classList.add('animate-bounce');

    // Create more particles
    for (let i = 0; i < 3; i++) {
      setTimeout(() => {
        this.createSuccessParticles(element);
      }, i * 200);
    }

    setTimeout(() => {
      element.classList.remove('animate-bounce');
    }, 2000);
  }

  /**
   * Create success particles animation
   */
  private createSuccessParticles(element: Element): void {
    const rect = element.getBoundingClientRect();
    const particles = ['🎉', '✨', '🌟', '💫'];

    for (let i = 0; i < 5; i++) {
      const particle = document.createElement('div');
      particle.textContent = particles[Math.floor(Math.random() * particles.length)];
      particle.className = 'fixed pointer-events-none z-50 text-2xl animate-bounce';
      particle.style.left = `${rect.left + Math.random() * rect.width}px`;
      particle.style.top = `${rect.top + Math.random() * rect.height}px`;

      document.body.appendChild(particle);

      // Animate and remove
      setTimeout(() => {
        particle.style.transform = `translateY(-50px) scale(0)`;
        particle.style.opacity = '0';
        particle.style.transition = 'all 1s ease-out';

        setTimeout(() => {
          particle.remove();
        }, 1000);
      }, 100);
    }
  }

  /**
   * Announce message to screen readers
   */
  private announceToScreenReader(message: string): void {
    const announcement = document.createElement('div');
    announcement.setAttribute('aria-live', 'polite');
    announcement.setAttribute('aria-atomic', 'true');
    announcement.className = 'sr-only';
    announcement.textContent = message;

    document.body.appendChild(announcement);

    setTimeout(() => {
      document.body.removeChild(announcement);
    }, 1000);
  }

  /**
   * Clean up feedback manager
   */
  cleanup(): void {
    this.clearAllFeedback();

    // Remove any lingering tooltips or particles
    const tooltips = document.querySelectorAll('.coaching-tooltip');
    tooltips.forEach(tooltip => tooltip.remove());

    console.log('🧹 FeedbackManager cleanup completed');
  }
}
