import { StrictMode, Suspense } from 'react';
import { createRoot } from 'react-dom/client';
import AppWrapper from './AppWrapper.tsx';
import ErrorBoundary from './components/Shared/ErrorBoundary';
import './index.css';
import i18n from './i18n';
import { logger } from './utils/logger';

// المزودين
import { CurrencyProvider } from './contexts/CurrencyContext.tsx';
import { ThemeProvider } from './contexts/ThemeContext.tsx';
import { AuthProvider } from './contexts/AuthContext.tsx';
import { InvoiceProvider } from './contexts/InvoiceContext.tsx';

// التكوين
import { currentConfig, BUILD_INFO } from './config/appConfig';

// مكون شاشة التحميل المحسنة
const LoadingFallback = () => (
  <div className="min-h-screen bg-gradient-to-br from-primary via-primary-dark to-secondary flex items-center justify-center">
    <div className="text-center text-white">
      <div className="w-20 h-20 mx-auto mb-6 bg-white/20 rounded-2xl flex items-center justify-center">
        <svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
          <rect width="40" height="40" rx="8" fill="white"/>
          <path d="M10 16H30V18H10V16ZM10 20H30V22H10V20ZM10 24H26V26H10V24Z" fill="#3366FF"/>
        </svg>
      </div>
      
      <h1 className="text-2xl font-bold mb-2">ARWA GROUP</h1>
      <p className="text-lg opacity-90 mb-4">{i18n.t('common.loadingSubtitle')}</p>
      
      <div className="w-48 h-1 bg-white/20 rounded-full mx-auto mb-4">
        <div className="h-full bg-white rounded-full animate-pulse" style={{width: '70%'}}></div>
      </div>
      
      <div className="animate-spin w-8 h-8 border-2 border-white/30 border-t-white rounded-full mx-auto mb-4"></div>
      
      <p className="text-sm opacity-75">
        {i18n.t('common.loadingFeatures', { version: BUILD_INFO.version })}
      </p>
    </div>
  </div>
);

// تهيئة التطبيق
const initializeApp = () => {
  logger.log(`
🏢 ARWA GROUP Accounting System v${BUILD_INFO.version}
📅 تاريخ البناء: ${new Date(BUILD_INFO.buildDate).toLocaleDateString(i18n.language)}
🌍 البيئة: ${BUILD_INFO.environment}
🔧 الميزات المفعلة:
${Object.entries(currentConfig.features)
  .filter(([_, enabled]) => enabled)
  .map(([feature]) => `   ✅ ${feature}`)
  .join('\n')}
  `);

  if (currentConfig.development.showPerformanceMetrics) {
    logger.log('📊 إعدادات الأداء:', {
      'ذاكرة التخزين المؤقت': currentConfig.performance.enableCaching ? 'مفعل' : 'معطل',
      'التحميل الكسول': currentConfig.performance.lazyLoading ? 'مفعل' : 'معطل',
      'حجم الذاكرة المسموح': `${currentConfig.performance.maxMemoryUsage} MB`
    });
  }

  if ('serviceWorker' in navigator && BUILD_INFO.environment === 'production') {
    navigator.serviceWorker.register('/sw.js')
      .then(() => logger.log('✅ Service Worker مسجل بنجاح'))
      .catch(error => logger.error('❌ فشل تسجيل Service Worker:', error));
  }

  if (currentConfig.development.showPerformanceMetrics) {
    const observer = new PerformanceObserver((list) => {
      for (const entry of list.getEntries()) {
        if (entry.entryType === 'measure') {
          logger.log(`⚡ ${entry.name}: ${entry.duration.toFixed(2)}ms`);
        }
      }
    });
    observer.observe({ entryTypes: ['measure'] });
  }
};

// توحيد تنسيق الأرقام/التواريخ في كل مكان:
// - أرقام إنجليزية (Latin digits) فقط
// - تاريخ ميلادي (Gregorian) فقط
//
// ملاحظة: بعض أجزاء الكود تستخدم `toLocaleString(i18n.language)` مباشرة،
// لذلك نحتاج override موحّد بدل استبدال جميع الاستدعاءات يدوياً.
const applyArwaLocaleOverrides = () => {
  const w = window as any;
  if (w.__arwaLocaleOverridesApplied) return;
  w.__arwaLocaleOverridesApplied = true;

  const getBaseLang = (): 'ar' | 'en' | 'zh' => {
    try {
      const lang = (document?.documentElement?.lang || i18n.language || '').toLowerCase();
      if (lang.startsWith('ar')) return 'ar';
      if (lang.startsWith('zh')) return 'zh';
    } catch {
      // ignore
    }
    return 'en';
  };

  // إجباري: تقويم ميلادي + أرقام لاتينية في كل اللغات
  const getForcedDateLocale = (): string => {
    const base = getBaseLang();
    if (base === 'ar') return 'ar-SA-u-ca-gregory-nu-latn';
    if (base === 'zh') return 'zh-CN-u-ca-gregory-nu-latn';
    return 'en-GB-u-ca-gregory-nu-latn';
  };

  const getForcedNumberLocale = (): string => {
    const base = getBaseLang();
    if (base === 'ar') return 'ar-SA-u-nu-latn';
    if (base === 'zh') return 'zh-CN-u-nu-latn';
    return 'en-US-u-nu-latn';
  };

  const originalToLocaleDateString = Date.prototype.toLocaleDateString;
  Date.prototype.toLocaleDateString = function (locales?: unknown, options?: unknown): string {
    try {
      return originalToLocaleDateString.call(this, getForcedDateLocale(), options as any);
    } catch {
      return originalToLocaleDateString.call(this, 'en-GB', options as any);
    }
  };

  const originalToLocaleTimeString = Date.prototype.toLocaleTimeString;
  Date.prototype.toLocaleTimeString = function (locales?: unknown, options?: unknown): string {
    try {
      return originalToLocaleTimeString.call(this, getForcedNumberLocale(), options as any);
    } catch {
      return originalToLocaleTimeString.call(this, locales as any, options as any);
    }
  };

  const originalToLocaleString = Date.prototype.toLocaleString;
  Date.prototype.toLocaleString = function (locales?: unknown, options?: unknown): string {
    try {
      return originalToLocaleString.call(this, getForcedDateLocale(), options as any);
    } catch {
      return originalToLocaleString.call(this, locales as any, options as any);
    }
  };

  const originalNumberToLocaleString = Number.prototype.toLocaleString;
  Number.prototype.toLocaleString = function (locales?: unknown, options?: unknown): string {
    try {
      return originalNumberToLocaleString.call(this, getForcedNumberLocale(), options as any);
    } catch {
      return originalNumberToLocaleString.call(this, locales as any, options as any);
    }
  };

  // بعض المكونات تستخدم Intl مباشرة بدل toLocale*، لذلك نطبّعها هنا أيضاً.
  try {
    const OriginalNumberFormat = Intl.NumberFormat;
    const PatchedNumberFormat = function (this: Intl.NumberFormat, locales?: unknown, options?: Intl.NumberFormatOptions) {
      return new OriginalNumberFormat(getForcedNumberLocale() as Intl.LocalesArgument, options);
    } as unknown as typeof Intl.NumberFormat;
    // Note: نتجنب تعديل `prototype`/خصائص static لأن TypeScript يراها read-only.
    Intl.NumberFormat = PatchedNumberFormat as any;
  } catch {
    // ignore when runtime doesn't allow patching Intl.NumberFormat
  }

  try {
    const OriginalDateTimeFormat = Intl.DateTimeFormat;
    const PatchedDateTimeFormat = function (this: Intl.DateTimeFormat, locales?: unknown, options?: Intl.DateTimeFormatOptions) {
      return new OriginalDateTimeFormat(getForcedDateLocale() as Intl.LocalesArgument, options);
    } as unknown as typeof Intl.DateTimeFormat;
    // Note: نتجنب تعديل `prototype`/خصائص static لأن TypeScript يراها read-only.
    Intl.DateTimeFormat = PatchedDateTimeFormat as any;
  } catch {
    // ignore when runtime doesn't allow patching Intl.DateTimeFormat
  }
};

// تشغيل التطبيق
const rootElement = document.getElementById('root');
if (!rootElement) {
  throw new Error('عنصر الجذر غير موجود في HTML');
}

// تهيئة التطبيق
applyArwaLocaleOverrides();
initializeApp();

// إشارة جاهزية التطبيق لإخفاء شاشة التحميل الأولى (تعمل مع الحد الأدنى للوقت في index.html)
const signalAppReady = () => {
  window.dispatchEvent(new CustomEvent('arwa:app-ready'));
};

// إنشاء التطبيق
createRoot(rootElement).render(
  <StrictMode>
    <ErrorBoundary>
      <Suspense fallback={<LoadingFallback />}>
        <ThemeProvider>
          <CurrencyProvider>
            <InvoiceProvider>
              <AuthProvider>
                <AppWrapper />
              </AuthProvider>
            </InvoiceProvider>
          </CurrencyProvider>
        </ThemeProvider>
      </Suspense>
    </ErrorBoundary>
  </StrictMode>
);

// إخفاء شاشة التحميل عند جاهزية React (بعد أول رسم)
requestAnimationFrame(() => {
  requestAnimationFrame(() => {
    setTimeout(signalAppReady, 50);
  });
});

window.addEventListener('error', (event) => {
  logger.error('خطأ في التطبيق:', {
    message: event.message,
    filename: event.filename,
    lineno: event.lineno,
    colno: event.colno,
    error: event.error
  });
});

window.addEventListener('unhandledrejection', (event) => {
  logger.error('رفض غير معالج:', event.reason);
  event.preventDefault();
});

// تصدير معلومات النظام للوصول العام
(window as any).ARWA_SYSTEM = {
  version: BUILD_INFO.version,
  config: currentConfig,
  build: BUILD_INFO
};