import React, { Component } from 'react';
import { withTranslation as reactI18nextWithTranslation } from 'react-i18next';
import { loadLanguage } from './index.js';

// HOC to provide translation functions to class components
export const withTranslation = (namespaces = 'translation') => (WrappedComponent) => {
  return reactI18nextWithTranslation(namespaces)(WrappedComponent);
};

// Context for language switching
export const LanguageContext = React.createContext({
  currentLanguage: 'de',
  changeLanguage: () => {},
  availableLanguages: ['de'] // Start with only German
});

// Provider component for language management
export class LanguageProvider extends Component {
  constructor(props) {
    super(props);
    
    // Try to get the current language from i18n or storage, fallback to German
    let currentLanguage = 'de';
    console.log("LanguageProvider constructor - Debug info:");
    console.log("  props.i18n:", props.i18n);
    console.log("  props.i18n.language:", props.i18n?.language);
    
    if (props.i18n && props.i18n.language) {
      currentLanguage = props.i18n.language;
      console.log("  Using language from i18n:", currentLanguage);
    } else if (typeof window !== 'undefined') {
      // Try to get from sessionStorage first, then localStorage
      try {
        const sessionLang = sessionStorage.getItem('i18nextLng');
        const localLang = localStorage.getItem('i18nextLng');
        console.log("  sessionStorage i18nextLng:", sessionLang);
        console.log("  localStorage i18nextLng:", localLang);
        currentLanguage = sessionLang || localLang || 'de';
        console.log("  Using language from storage:", currentLanguage);
      } catch (error) {
        console.warn('Could not read language from storage:', error);
      }
    }
    
    console.log("  Final currentLanguage:", currentLanguage);
    
    this.state = {
      currentLanguage,
      availableLanguages: ['de'], // Start with only German visible
      allLanguages: ['ar', 'bg', 'cs', 'de', 'el', 'en', 'es', 'fr', 'hr', 'hu', 'it', 'pl', 'ro', 'ru', 'sk', 'sl', 'sq', 'sr', 'sv', 'tr', 'uk', 'zh'],
      demoMode: false,
      currentLanguageIndex: 0,
      loadingLanguages: new Set()
    };
    
    this.demoInterval = null;
  }

  componentDidMount() {
    if (this.props.i18n) {
      this.props.i18n.on('languageChanged', this.handleLanguageChanged);
      
      console.log("LanguageProvider componentDidMount:");
      console.log("  current state.currentLanguage:", this.state.currentLanguage);
      console.log("  props.i18n.language:", this.props.i18n.language);
      
      // Only update state if i18n language is different and not the default 'de'
      // This prevents overriding the language we restored from storage
      if (this.props.i18n.language !== this.state.currentLanguage && 
          this.props.i18n.language !== 'de') {
        console.log("  Updating language from i18n:", this.props.i18n.language);
        this.setState({ currentLanguage: this.props.i18n.language });
        document.documentElement.lang = this.props.i18n.language;
      } else {
        console.log("  Keeping language from constructor:", this.state.currentLanguage);
        document.documentElement.lang = this.state.currentLanguage;
      }
      
      // Start demo mode
      if (this.state.demoMode) {
        this.startDemo();
      }
    }
  }

  componentWillUnmount() {
    if (this.props.i18n) {
      this.props.i18n.off('languageChanged', this.handleLanguageChanged);
    }
    
    // Clean up demo interval
    if (this.demoInterval) {
      clearInterval(this.demoInterval);
    }
  }

  startDemo = () => {
    // Find current language index
    const currentIndex = this.state.availableLanguages.indexOf(this.state.currentLanguage);
    this.setState({ currentLanguageIndex: currentIndex >= 0 ? currentIndex : 0 });
    
    this.demoInterval = setInterval(() => {
      const nextIndex = (this.state.currentLanguageIndex + 1) % this.state.availableLanguages.length;
      const nextLanguage = this.state.availableLanguages[nextIndex];
      
      this.setState({ currentLanguageIndex: nextIndex });
      
      if (this.props.i18n) {
        this.props.i18n.changeLanguage(nextLanguage);
      }
    }, 5000); // Change language every 5 seconds
  };

  stopDemo = () => {
    if (this.demoInterval) {
      clearInterval(this.demoInterval);
      this.demoInterval = null;
    }
    this.setState({ demoMode: false });
  };

  handleLanguageChanged = (lng) => {
    this.setState({ currentLanguage: lng });
    
    // Update HTML lang attribute for SEO
    document.documentElement.lang = lng;
    
    // Ensure language is saved to localStorage
    try {
      localStorage.setItem('i18nextLng', lng);
    } catch (error) {
      console.warn('Could not save language to localStorage:', error);
    }
    
    // Update config if available
    if (window.shopConfig) {
      // Language code mapping for all supported languages
      const languageMap = {
        'ar': 'ar-EG',
        'bg': 'bg-BG',
        'cs': 'cs-CZ',
        'de': 'de-DE',
        'el': 'el-GR',
        'en': 'en-US',
        'es': 'es-ES',
        'fr': 'fr-FR',
        'hr': 'hr-HR',
        'hu': 'hu-HU',
        'it': 'it-IT',
        'pl': 'pl-PL',
        'ro': 'ro-RO',
        'ru': 'ru-RU',
        'sk': 'sk-SK',
        'sl': 'sl-SI',
        'sr': 'sr-RS',
        'sv': 'sv-SE',
        'tr': 'tr-TR',
        'uk': 'uk-UA',
        'zh': 'zh-CN'
      };
      window.shopConfig.language = languageMap[lng] || 'de-DE';
    }
  };

  changeLanguage = async (language) => {
    if (this.props.i18n && this.state.allLanguages.includes(language)) {
      // Stop demo mode if user manually changes language
      if (this.state.demoMode) {
        this.stopDemo();
      }
      
      // If language is not German and not already available, load it
      if (language !== 'de' && !this.state.availableLanguages.includes(language)) {
        // Check if already loading
        if (this.state.loadingLanguages.has(language)) {
          return; // Already loading
        }
        
        // Mark as loading
        this.setState(prevState => ({
          loadingLanguages: new Set([...prevState.loadingLanguages, language])
        }));
        
        try {
          console.log(`🌍 Loading language: ${language}`);
          await loadLanguage(language);
          
          // Add to available languages after successful load
          this.setState(prevState => ({
            availableLanguages: [...prevState.availableLanguages, language],
            loadingLanguages: new Set([...prevState.loadingLanguages].filter(l => l !== language))
          }));
          
          console.log(`✅ Language ${language} now available`);
        } catch (error) {
          console.error(`❌ Failed to load language ${language}:`, error);
          this.setState(prevState => ({
            loadingLanguages: new Set([...prevState.loadingLanguages].filter(l => l !== language))
          }));
          return; // Don't change language if loading failed
        }
      }
      
      // Change the language
      await this.props.i18n.changeLanguage(language);
    }
  };

  render() {
    const contextValue = {
      currentLanguage: this.state.currentLanguage,
      changeLanguage: this.changeLanguage,
      availableLanguages: this.state.availableLanguages,
      allLanguages: this.state.allLanguages,
      loadingLanguages: this.state.loadingLanguages,
      demoMode: this.state.demoMode,
      stopDemo: this.stopDemo
    };

    return (
      <LanguageContext.Provider value={contextValue}>
        {this.props.children}
      </LanguageContext.Provider>
    );
  }
}

// HOC to inject language context into class components
export const withLanguage = (WrappedComponent) => {
  return class extends Component {
    render() {
      return (
        <LanguageContext.Consumer>
          {(languageContext) => (
            <WrappedComponent {...this.props} languageContext={languageContext} />
          )}
        </LanguageContext.Consumer>
      );
    }
  };
};

// Combined HOC that provides both translation and language context
export const withI18n = (namespaces = 'translation') => (WrappedComponent) => {
  const WithTranslationComponent = withTranslation(namespaces)(WrappedComponent);
  return withLanguage(WithTranslationComponent);
}; 