// inMOLA Analytics — React Native SDK (tek dosya, paket bağımlılığı yok). iOS + Android, React Native 0.64+ ve Expo.
// TypeScript dosyasıdır; düz JavaScript projelerinde de olduğu gibi çalışır (Metro .ts'yi derler).
//
// Kurulum: bu dosyayı projenize kopyalayın (ör. src/InmolaAnalytics.ts).
//   Açılış (index.js / App.tsx en üst):
//     import InmolaAnalytics from './src/InmolaAnalytics';
//     InmolaAnalytics.init({ siteKey: 'SITE_ANAHTARI', appId: 'com.ornek.uygulama', appVersion: '1.4.0' });
//   Ekranlar — React Navigation:
//     const nav = useNavigationContainerRef();
//     <NavigationContainer ref={nav} onReady={() => InmolaAnalytics.screen(nav.getCurrentRoute()?.name)}
//                          onStateChange={() => InmolaAnalytics.screen(nav.getCurrentRoute()?.name)}>
//   Ekranlar — Expo Router (app/_layout.tsx):
//     const path = usePathname(); useEffect(() => InmolaAnalytics.screen(path), [path]);
//   Olay:        InmolaAnalytics.event('sepete_ekle', 'SKU-1');
//   Satın alma:  InmolaAnalytics.purchase('SIP-1001', 1499.90, 'TRY', [{ id: 'SKU-1', name: 'Ürün', price: 1499.90, quantity: 1 }]);
//
// appId: panele kaydettiğiniz kimlik (iOS bundle ID / Android applicationId). İki platformda farklıysa
//   appId: Platform.OS === 'ios' ? 'com.ornek.ios' : 'com.ornek.android'  — ve ikisini panele ayrı uygulama olarak ekleyin.
// Gizlilik: cihaz kimliği KULLANILMAZ, cihaza hiçbir şey yazılmaz, kişisel veri gönderilmez.
// Kayıtlar bellekte toplanır, ~10 sn'de bir ve uygulama arka plana geçerken gönderilir.

import { AppState, Dimensions, Platform } from 'react-native';

export type InmolaItem = { id: string; name: string; price: number; quantity?: number };
export type InmolaOptions = { siteKey: string; appId: string; appVersion?: string; endpoint?: string };
type Ev = Record<string, unknown>;

const DEFAULT_ENDPOINT = 'https://inmola-analytics.iletisim-845.workers.dev/m';

let core: Core | null = null;

class Core {
  private pending: Ev[] = [];
  screen: string | null = null;
  private screenStart = Date.now();
  private screenEntry = false;
  private newSession = true;
  private backgroundAt = 0;

  constructor(private key: string, private endpoint: string, private base: Ev) {
    setInterval(() => { this.flush(); }, 10000);
  }

  show(name: string) {
    if (name === this.screen) return;
    const now = Date.now();
    this.end(true, now);
    this.screen = name; this.screenStart = now; this.screenEntry = this.newSession;
    this.add({ t: 'pv', sc: name, ent: this.newSession ? 1 : 0 });
    this.newSession = false;
  }

  private end(next: boolean, now: number) {
    if (this.screen === null) return;
    this.add({ t: 'en', sc: this.screen, sec: Math.min(Math.floor((now - this.screenStart) / 1000), 3600), nx: next ? 1 : 0,
      ent: this.screenEntry ? 1 : 0 });
  }

  background() {
    if (this.backgroundAt) return;
    this.backgroundAt = Date.now();
    this.end(false, this.backgroundAt);
    this.flush();
  }

  foreground() {
    if (!this.backgroundAt) return;
    const away = Date.now() - this.backgroundAt;
    this.backgroundAt = 0;
    const s = this.screen;
    if (s === null) return;
    // 30 dk'dan uzun arka planda kaldıysa yeni oturum; değilse aynı ekran yeniden açılmış sayılır
    this.newSession = away > 30 * 60 * 1000;
    this.screen = null;
    this.show(s);
  }

  add(e: Ev) {
    if (!InmolaAnalytics.enabled || !this.key) return;
    this.pending.push(e);
    if (this.pending.length >= 20) this.flush();
  }

  async flush(): Promise<void> {
    if (!this.pending.length) return;
    const batch = this.pending.splice(0, 50);
    let ok = false;
    const ctl = typeof AbortController !== 'undefined' ? new AbortController() : null;
    const tm = setTimeout(() => ctl?.abort(), 15000);
    try {
      const r = await fetch(this.endpoint, { method: 'POST', headers: { 'Content-Type': 'text/plain' },
        body: JSON.stringify({ ...this.base, ev: batch }), signal: ctl?.signal });
      ok = r.status < 500;
    } catch (e) { /* ağ yok */ }
    clearTimeout(tm);
    // Ağ yoksa geri koy (bellekte en fazla 200 kayıt), sonraki turda tekrar denenir
    if (!ok && this.pending.length < 200) this.pending.unshift(...batch);
  }
}

function locale(): string {
  try { return Intl.DateTimeFormat().resolvedOptions().locale || ''; } catch (e) { return ''; }
}

const InmolaAnalytics = {
  /** Gönderim kapalı (ör. kullanıcı analitiği reddettiyse). Kapalıyken hiçbir şey toplanmaz. */
  enabled: true,

  init(o: InmolaOptions) {
    if (core || (Platform.OS !== 'ios' && Platform.OS !== 'android')) return;
    const pc: any = (Platform as any).constants || {};
    const ios = Platform.OS === 'ios';
    const { width, height } = Dimensions.get('window');
    core = new Core(o.siteKey, o.endpoint || DEFAULT_ENDPOINT, {
      s: o.siteKey, b: String(o.appId || '').trim().toLowerCase(), p: Platform.OS,
      ov: String(ios ? Platform.Version : pc.Release || Platform.Version || ''), dm: ios ? '' : String(pc.Model || ''),
      av: o.appVersion || '', l: locale(),
      tab: (ios ? (Platform as any).isPad : Math.min(width, height) >= 600) ? 1 : 0, w: Math.round(width),
    });
    const c = core;
    AppState.addEventListener('change', (s) => {
      if (s === 'background') c.background();
      else if (s === 'active') c.foreground();
    });
  },

  /** Ekran açıldı. Boş ad yok sayılır (React Navigation'da ilk an rota adı gelmeyebilir). */
  screen(name: string | null | undefined) {
    if (InmolaAnalytics.enabled && name) core?.show(String(name));
  },

  event(name: string, detail = '') {
    if (InmolaAnalytics.enabled && core) core.add({ t: 'ev', sc: core.screen || '', n: name, dd: detail });
  },

  purchase(transactionId: string, value: number, currency: string, items: InmolaItem[] = []) {
    if (!InmolaAnalytics.enabled || !core) return;
    core.add({ t: 'ev', sc: core.screen || '', n: 'purchase', dd: transactionId, v: value, cur: currency.toUpperCase(),
      it: items.slice(0, 50).map((i) => ({ n: i.name, id: i.id, p: i.price, q: i.quantity || 1 })) });
    core.flush();
  },

  /** Test için: bekleyen kayıtları hemen gönder. */
  flushNow(): Promise<void> { return core ? core.flush() : Promise.resolve(); },
};

export default InmolaAnalytics;
