import { ApplicationRef, Injectable, NgZone } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';

export type SupportedLanguage = 'en' | 'ar' | 'fr';

@Injectable({
  providedIn: 'root'
})
export class I18nService {
  private currentLanguageSubject = new BehaviorSubject<SupportedLanguage>('en');
  public currentLanguage$: Observable<SupportedLanguage> = this.currentLanguageSubject.asObservable();
  private translationsLoadedSubject = new BehaviorSubject<number>(0);
  public translationsLoaded$: Observable<number> = this.translationsLoadedSubject.asObservable();

  private translations: { [lang: string]: { [key: string]: string } } = {
    en: {},
    ar: {},
    fr: {}
  };

  constructor(private appRef: ApplicationRef, private ngZone: NgZone) {
    // Load translations from assets
    this.loadTranslations();
    
    // Try to restore saved language
    const savedLang = localStorage.getItem('app_language') as SupportedLanguage;
    if (savedLang && ['en', 'ar', 'fr'].includes(savedLang)) {
      this.currentLanguageSubject.next(savedLang);
    }

    this.applyDocumentLanguage(this.currentLanguageSubject.value);
  }

  private async loadTranslations() {
    try {
      const [enData, arData, frData] = await Promise.all([
        fetch('/assets/i18n/en.json').then(r => r.json()),
        fetch('/assets/i18n/ar.json').then(r => r.json()),
        fetch('/assets/i18n/fr.json').then(r => r.json())
      ]);
      
      this.translations['en'] = enData;
      this.translations['ar'] = arData;
      this.translations['fr'] = frData;

      // Notify consumers that translations are ready and force a render pass.
      this.translationsLoadedSubject.next(Date.now());
      this.currentLanguageSubject.next(this.currentLanguageSubject.value);
      this.triggerUiRefresh();
    } catch (error) {
      console.error('Failed to load translations:', error);
    }
  }

  private applyDocumentLanguage(lang: SupportedLanguage): void {
    document.documentElement.dir = lang === 'ar' ? 'rtl' : 'ltr';
    document.documentElement.lang = lang;
  }

  private triggerUiRefresh(): void {
    this.ngZone.run(() => {
      Promise.resolve().then(() => this.appRef.tick());
    });
  }

  getCurrentLanguage(): SupportedLanguage {
    return this.currentLanguageSubject.value;
  }

  setLanguage(lang: SupportedLanguage): void {
    this.currentLanguageSubject.next(lang);
    localStorage.setItem('app_language', lang);

    this.applyDocumentLanguage(lang);
    this.triggerUiRefresh();
  }

  translate(key: string, params?: { [key: string]: any }): string {
    const lang = this.currentLanguageSubject.value;
    let translation = this.translations[lang]?.[key] || key;
    
    // Replace params if provided
    if (params) {
      Object.keys(params).forEach(paramKey => {
        translation = translation.replace(`{{${paramKey}}}`, params[paramKey]);
      });
    }
    
    return translation;
  }

  instant(key: string, params?: { [key: string]: any }): string {
    return this.translate(key, params);
  }
}
