import React, { useState, useEffect, useCallback } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import type { Presentation, SlideContent } from '../../types/presentation.ts';
import type { Theme } from '../../types/theme.ts';
import { getPresentationById } from '../../utils/presentationStorage.ts';
import { getTheme } from '../../themes/index.ts';
import { renderTemplateWithSampleData } from '../../utils/templateRenderer.ts';
import { sanitizeSlideTemplate } from '../../utils/htmlSanitizer.ts';
import { loggers } from '../../utils/logger.ts';
import './PresentationMode.css';

export const PresentationMode: React.FC = () => {
  const { presentationId } = useParams<{ presentationId: string }>();
  const navigate = useNavigate();
  
  const [presentation, setPresentation] = useState<Presentation | null>(null);
  const [theme, setTheme] = useState<Theme | null>(null);
  const [currentSlideIndex, setCurrentSlideIndex] = useState(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  
  // Keyboard navigation handler
  const handleKeyPress = useCallback((event: KeyboardEvent) => {
    if (!presentation || presentation.slides.length === 0) return;
    
    switch (event.key) {
      case 'ArrowRight':
      case 'Space':
      case 'Enter':
        event.preventDefault();
        setCurrentSlideIndex(prev => 
          Math.min(prev + 1, presentation.slides.length - 1)
        );
        break;
        
      case 'ArrowLeft':
        event.preventDefault();
        setCurrentSlideIndex(prev => Math.max(prev - 1, 0));
        break;
        
      case 'Home':
        event.preventDefault();
        setCurrentSlideIndex(0);
        break;
        
      case 'End':
        event.preventDefault();
        setCurrentSlideIndex(presentation.slides.length - 1);
        break;
        
      case 'Escape':
        event.preventDefault();
        exitPresentationMode();
        break;
        
      default:
        // Handle number keys for direct slide navigation
        const slideNumber = parseInt(event.key);
        if (slideNumber >= 1 && slideNumber <= presentation.slides.length) {
          event.preventDefault();
          setCurrentSlideIndex(slideNumber - 1);
        }
        break;
    }
  }, [presentation, navigate, presentationId]);
  
  // Set up keyboard listeners
  useEffect(() => {
    document.addEventListener('keydown', handleKeyPress);
    return () => {
      document.removeEventListener('keydown', handleKeyPress);
    };
  }, [handleKeyPress]);
  
  // Load presentation and theme
  useEffect(() => {
    const loadPresentationAndTheme = async () => {
      if (!presentationId) {
        setError('No presentation ID provided');
        setLoading(false);
        return;
      }

      try {
        setLoading(true);
        
        // Load presentation
        const presentationData = await getPresentationById(presentationId);
        if (!presentationData) {
          setError(`Presentation not found: ${presentationId}`);
          return;
        }
        
        setPresentation(presentationData);
        
        // Load theme
        const themeData = await getTheme(presentationData.metadata.theme);
        if (!themeData) {
          setError(`Theme not found: ${presentationData.metadata.theme}`);
          return;
        }
        
        setTheme(themeData);
        
        // Load theme CSS
        const cssLink = document.getElementById('presentation-theme-css') as HTMLLinkElement;
        const cssPath = `${themeData.basePath}/${themeData.cssFile}`;
        if (cssLink) {
          cssLink.href = cssPath;
        } else {
          const newCssLink = document.createElement('link');
          newCssLink.id = 'presentation-theme-css';
          newCssLink.rel = 'stylesheet';
          newCssLink.href = cssPath;
          document.head.appendChild(newCssLink);
        }
        
      } catch (err) {
        setError(err instanceof Error ? err.message : 'Failed to load presentation');
      } finally {
        setLoading(false);
      }
    };

    loadPresentationAndTheme();
    
    // Cleanup theme CSS on unmount
    return () => {
      const cssLink = document.getElementById('presentation-theme-css');
      if (cssLink) {
        cssLink.remove();
      }
    };
  }, [presentationId]);
  
  const exitPresentationMode = () => {
    navigate(`/presentations/${presentationId}/view/slides/${currentSlideIndex + 1}`);
  };
  
  const renderSlideContent = (slide: SlideContent): string => {
    if (!theme) return '';
    
    const layout = theme.layouts.find(l => l.id === slide.layoutId);
    if (!layout) {
      loggers.ui.warn(`Layout ${slide.layoutId} not found in theme ${theme.name}`);
      return '<div class="error">Layout not found</div>';
    }
    
    let renderedTemplate = layout.htmlTemplate;
    
    // Replace template variables with slide content
    Object.entries(slide.content).forEach(([slotId, content]) => {
      const regex = new RegExp(`\\{\\{${slotId}\\}\\}`, 'g');
      renderedTemplate = renderedTemplate.replace(regex, content);
    });
    
    // Handle conditional blocks and clean up remaining variables
    renderedTemplate = renderTemplateWithSampleData(renderedTemplate, layout);
    
    return sanitizeSlideTemplate(renderedTemplate);
  };
  
  if (loading) {
    return (
      <div className="presentation-mode loading">
        <div className="loading-spinner">Loading presentation...</div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="presentation-mode error">
        <div className="error-content">
          <h2>Error Loading Presentation</h2>
          <p>{error}</p>
          <button onClick={exitPresentationMode} className="exit-button">
            Exit Presentation Mode
          </button>
        </div>
      </div>
    );
  }

  if (!presentation || !theme) {
    return (
      <div className="presentation-mode error">
        <div className="error-content">
          <h2>Presentation Not Found</h2>
          <button onClick={exitPresentationMode} className="exit-button">
            Exit Presentation Mode
          </button>
        </div>
      </div>
    );
  }

  if (presentation.slides.length === 0) {
    return (
      <div className="presentation-mode error">
        <div className="error-content">
          <h2>No Slides Available</h2>
          <p>This presentation is empty.</p>
          <button onClick={exitPresentationMode} className="exit-button">
            Exit Presentation Mode
          </button>
        </div>
      </div>
    );
  }

  const currentSlide = presentation.slides[currentSlideIndex];
  const totalSlides = presentation.slides.length;
  const renderedSlideContent = renderSlideContent(currentSlide);

  return (
    <div className="presentation-mode fullscreen">
      <div className="slide-container">
        <div 
          className={`slide-content ${presentation.metadata.aspectRatio ? `aspect-${presentation.metadata.aspectRatio.replace(':', '-')}` : 'aspect-16-9'}`}
          dangerouslySetInnerHTML={{ __html: renderedSlideContent }}
        />
      </div>
      
      {/* Navigation indicator */}
      <div className="navigation-indicator">
        <span className="slide-counter">
          {currentSlideIndex + 1} / {totalSlides}
        </span>
        
        <div className="navigation-hints">
          <span>← → Space: Navigate</span>
          <span>Esc: Exit</span>
        </div>
      </div>
    </div>
  );
};