import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import { Analytics } from '@vercel/analytics/react'

// Exclut tes propres visites des statistiques Vercel Analytics.
// Ouvre une fois l'URL avec ?sr_dev=1 sur chaque appareil/navigateur que tu utilises
// (ex: https://www.getstudyreach.com/?sr_dev=1) : le flag reste posé ensuite (localStorage),
// pas besoin de répéter à chaque visite. Les vrais visiteurs ne voient jamais ce paramètre.
try {
  if (new URLSearchParams(window.location.search).get('sr_dev') === '1') {
    localStorage.setItem('sr_dev', '1')
  }
} catch (e) {}

const isDevVisitor = (() => {
  try { return localStorage.getItem('sr_dev') === '1' } catch (e) { return false }
})()

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//  TRACKING DES VISITES → table Supabase "page_visits"
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// Une ligne par page vue (chargement + navigation interne).
// Échoue toujours en silence : ne doit jamais casser le site.
const SR_SUPA_URL = 'https://bwaoxwfkqqpqvtpynwzh.supabase.co'
const SR_SUPA_KEY = 'sb_publishable_SsnkELg6dLx--AjHaW0ShA_N1ISmMKg'

function srSessionId() {
  try {
    let id = sessionStorage.getItem('sr_visit_session')
    if (!id) {
      id = crypto.randomUUID
        ? crypto.randomUUID()
        : 'sid-' + Date.now() + '-' + Math.random().toString(36).slice(2)
      sessionStorage.setItem('sr_visit_session', id)
    }
    return id
  } catch (e) { return null }
}

let srLastPath = null
let srFirstHit = true
function trackPageVisit() {
  try {
    const path = window.location.pathname
    if (path === srLastPath) return
    srLastPath = path
    const p = new URLSearchParams(window.location.search)
    const first = srFirstHit
    srFirstHit = false
    fetch(SR_SUPA_URL + '/rest/v1/page_visits', {
      method: 'POST',
      keepalive: true,
      headers: {
        'Content-Type': 'application/json',
        'apikey': SR_SUPA_KEY,
        'Authorization': 'Bearer ' + SR_SUPA_KEY,
        'Prefer': 'return=minimal',
      },
      body: JSON.stringify({
        session_id: srSessionId(),
        path,
        referrer: first ? (document.referrer || null) : null,
        utm_source: p.get('utm_source'),
        utm_medium: p.get('utm_medium'),
        utm_campaign: p.get('utm_campaign'),
        user_agent: navigator.userAgent,
        is_dev: isDevVisitor,
      }),
    }).catch(() => {})
  } catch (e) {}
}

// Événements d'inscription (invisibles pour le visiteur) : mêmes lignes que
// page_visits, avec un chemin "/evt/<nom>". Échoue toujours en silence.
window.__srTrack = function (evt, detail) {
  try {
    let path = '/evt/' + String(evt).slice(0, 40)
    if (detail) {
      const d = String(detail).replace(/\S+@\S+/g, 'x').slice(0, 80)
      path += '?d=' + encodeURIComponent(d)
    }
    fetch(SR_SUPA_URL + '/rest/v1/page_visits', {
      method: 'POST',
      keepalive: true,
      headers: {
        'Content-Type': 'application/json',
        'apikey': SR_SUPA_KEY,
        'Authorization': 'Bearer ' + SR_SUPA_KEY,
        'Prefer': 'return=minimal',
      },
      body: JSON.stringify({
        session_id: srSessionId(),
        path,
        user_agent: navigator.userAgent,
        is_dev: isDevVisitor,
      }),
    }).catch(() => {})
  } catch (e) {}
}

try {
  const origPush = window.history.pushState
  window.history.pushState = function () {
    const r = origPush.apply(this, arguments)
    setTimeout(trackPageVisit, 0)
    return r
  }
  window.addEventListener('popstate', () => setTimeout(trackPageVisit, 0))
  trackPageVisit()
} catch (e) {}

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//  DIAGNOSTIC TEMPORAIRE — chute des inscriptions (27/09/2026)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// Capture toute erreur JS non interceptée (render, handler, promise) et
// l'envoie dans la table Supabase "client_errors" (créée pour ce diagnostic).
// Objectif : voir le message d'erreur exact du prochain visiteur qui échoue,
// sans avoir besoin d'ouvrir la console soi-même. Échoue toujours en
// silence. À retirer une fois le bug trouvé.
function reportClientError(source, err) {
  try {
    fetch(SR_SUPA_URL + '/rest/v1/client_errors', {
      method: 'POST',
      keepalive: true,
      headers: {
        'Content-Type': 'application/json',
        'apikey': SR_SUPA_KEY,
        'Authorization': 'Bearer ' + SR_SUPA_KEY,
        'Prefer': 'return=minimal',
      },
      body: JSON.stringify({
        session_id: srSessionId(),
        source,
        message: String((err && err.message) || err || '').slice(0, 500),
        stack: String((err && err.stack) || '').slice(0, 2000),
        path: window.location.pathname,
        user_agent: navigator.userAgent,
      }),
    }).catch(() => {})
  } catch (e) {}
}
window.__srReportError = reportClientError
try {
  window.addEventListener('error', (e) => reportClientError('window.onerror', e.error || e.message))
  window.addEventListener('unhandledrejection', (e) => reportClientError('unhandledrejection', e.reason))
} catch (e) {}

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//  RÉVÉLATION UNIQUE APRÈS MONTAGE
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// #root démarre caché (opacity:0 posé dans index.html, avant même que ce
// script ne s'exécute) : le texte pré-rendu (voir scripts/prerender.mjs)
// reste dans le HTML pour les robots, mais n'est jamais peint à l'écran pour
// un humain. On monte React pendant que #root est encore invisible, puis on
// révèle une seule fois une fois le montage terminé — donc plus de "texte
// pré-rendu qui se fait remplacer par le rendu React", juste une seule
// apparition du contenu final. Double requestAnimationFrame : garantit que
// le navigateur a bien peint le DOM final avant de déclencher le fondu
// d'apparition (sinon le changement d'opacité risque de se fondre avec le
// montage dans la même frame et sauter sans transition visible).
const rootEl = document.getElementById('root')

ReactDOM.createRoot(rootEl).render(
  <React.StrictMode>
    <App />
    <Analytics beforeSend={(event) => (isDevVisitor ? null : event)} />
  </React.StrictMode>
)

requestAnimationFrame(() => {
  requestAnimationFrame(() => {
    rootEl.style.opacity = '1'
  })
})
