/**
 * GeoGraSim — Persistence Layer
 *
 * Dualer Speicher: localStorage (immer, schnell, offline) + PHP-API (wenn Session vorhanden).
 * Wird von game-ui.ts und den Simulationen verwendet.
 */

interface GGSContext {
  sessionId: string | null
  teacherId: number | null
  baseUrl: string
  basePath: string
}

function getContext(): GGSContext {
  return (window as any).__GGS__ ?? { sessionId: null, teacherId: null, baseUrl: '', basePath: '' }
}

function hasSession(): boolean {
  return !!getContext().sessionId
}

function apiUrl(path: string): string {
  return getContext().baseUrl + '/api/' + path
}

export const persistence = {

  /**
   * Spielstand speichern.
   * Schreibt IMMER in localStorage (schnell + offline).
   * Spiegelt an PHP-API wenn eine Session existiert (fire-and-forget).
   */
  async save(key: string, data: string, version = 2): Promise<void> {
    // 1. Immer localStorage (synchron, schnell)
    try { localStorage.setItem(key, data) } catch { /* quota exceeded */ }

    // 2. Spiegeln an Server wenn Session vorhanden
    if (!hasSession()) return
    try {
      await fetch(apiUrl('saves'), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'same-origin',
        body: JSON.stringify({ key, data, version }),
      })
    } catch { /* Netzwerk offline — localStorage hat den Save */ }
  },

  /**
   * Spielstand laden.
   * Bevorzugt Server (aktueller ueber Geraete hinweg), Fallback auf localStorage.
   */
  async load(key: string): Promise<string | null> {
    if (hasSession()) {
      try {
        const res = await fetch(apiUrl('saves') + '?key=' + encodeURIComponent(key), {
          credentials: 'same-origin',
        })
        const json = await res.json()
        if (json.data) return json.data
      } catch { /* Fallback auf localStorage */ }
    }
    return localStorage.getItem(key)
  },

  /**
   * Assessment-Daten an den Server senden (fuer Lehrkraefte-Dashboard).
   */
  async submitAssessment(simId: string, data: Record<string, unknown>): Promise<void> {
    if (!hasSession()) return
    try {
      await fetch(apiUrl('assessment'), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'same-origin',
        body: JSON.stringify({ simId, ...data }),
      })
    } catch { /* best-effort */ }
  },

  /** Session-Status abfragen */
  async getSessionStatus(): Promise<Record<string, unknown> | null> {
    try {
      const res = await fetch(apiUrl('sessions'), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'same-origin',
        body: JSON.stringify({ action: 'status' }),
      })
      return await res.json()
    } catch { return null }
  },

  /** Einer Klasse beitreten */
  async joinClass(joinCode: string, displayName: string): Promise<Record<string, unknown>> {
    const res = await fetch(apiUrl('sessions'), {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      credentials: 'same-origin',
      body: JSON.stringify({ action: 'join', joinCode, displayName }),
    })
    return await res.json()
  },

  /** Pruefen ob Session existiert (synchron, liest nur window.__GGS__) */
  hasSession,
}
