// GUS backend adapter for the Strata theme.
// Replaces Claude Design mock data with the live Express API / db.json data.
(function() {
  const MUSCLE_MAP = {
    chest:'chest', pectoraux:'chest',
    back:'back', dos:'back', trapezius:'back', trapezes:'back', trapezius:'back',
    shoulders:'shoulders', epaules:'shoulders', épaules:'shoulders',
    biceps:'biceps',
    triceps:'triceps',
    quadriceps:'legs', hamstrings:'legs', glutes:'legs', calves:'legs', jambes:'legs',
    ischio_jambiers:'legs', 'ischio-jambiers':'legs', fessiers:'legs', mollets:'legs',
    adductors:'legs', abductors:'legs', adducteurs:'legs', abducteurs:'legs',
    abs:'core', abdominaux:'core', core:'core',
    cardio:'cardio', stretching:'core', 'full body':'core', 'corps entier':'core'
  };
  const MUSCLE_LABELS = {
    chest:{id:'chest',fr:'Poitrine',en:'Chest'},
    back:{id:'back',fr:'Dos',en:'Back'},
    legs:{id:'legs',fr:'Jambes',en:'Legs'},
    shoulders:{id:'shoulders',fr:'Épaules',en:'Shoulders'},
    biceps:{id:'biceps',fr:'Biceps',en:'Biceps'},
    triceps:{id:'triceps',fr:'Triceps',en:'Triceps'},
    core:{id:'core',fr:'Abdos',en:'Core'},
    cardio:{id:'cardio',fr:'Cardio',en:'Cardio'}
  };
  const COLORS = {
    push:'#E8682C', pull:'#3B7DD8', legs:'#5B9E3C', upper:'#9B5BC2',
    full_body:'#D8A93B', chest:'#E8682C', back:'#3B7DD8', shoulders:'#9B5BC2',
    biceps:'#B66DDF', triceps:'#D85B66', core:'#D8A93B', cardio:'#4BAE8F'
  };

  function token() { return localStorage.getItem('gym_token') || ''; }
  async function api(path, opts = {}) {
    const res = await fetch('/api' + path, {
      ...opts,
      headers: {
        'Content-Type':'application/json',
        ...(token() ? { Authorization:'Bearer ' + token() } : {}),
        ...(opts.headers || {})
      }
    });
    const data = await res.json().catch(() => ({}));
    if (!res.ok) throw new Error(data.error || ('Erreur ' + res.status));
    return data;
  }
  function norm(s) {
    return String(s || '').normalize('NFD').replace(/[\u0300-\u036f]/g,'').toLowerCase().trim();
  }
  function muscleId(group) {
    const g = norm(group).replace(/\s+/g, '_');
    return MUSCLE_MAP[g] || MUSCLE_MAP[norm(group)] || 'core';
  }
  function equipmentId(eq) {
    const e = norm(eq);
    if (e.includes('barbell') || e.includes('barre')) return 'barbell';
    if (e.includes('dumbbell') || e.includes('haltere')) return 'dumbbell';
    if (e.includes('machine')) return 'machine';
    if (e.includes('cable') || e.includes('poulie')) return 'cable';
    if (e.includes('kettlebell')) return 'kettlebell';
    return 'bodyweight';
  }
  function levelId(d) {
    const v = norm(d);
    if (v.includes('advanced') || v.includes('avance')) return 'advanced';
    if (v.includes('inter')) return 'intermediate';
    return 'beginner';
  }
  function mapExercise(e) {
    const muscle = muscleId(e.muscleGroup || e.group);
    return {
      id:e.id,
      name:e.name || e.id,
      fr:e.name || e.id,
      muscle,
      secondary:Array.isArray(e.secondary) ? e.secondary : [],
      equipment:equipmentId(e.equipment),
      level:levelId(e.difficulty),
      thumb:e.localImg || e.imgStart || '',
      pageUrl:e.pageUrl || '',
      youtube:e.youtube || '',
      videoUrl:e.videoUrl || '',
      cues:{
        en:[e.instructions || e.description || 'Control the movement', 'Use a full range of motion'],
        fr:[e.instructions || e.description || 'Contrôler le mouvement', 'Utiliser une amplitude complète']
      }
    };
  }
  function templateCategory(tpl) {
    const txt = norm([tpl.name, tpl.description, tpl.tags].join(' '));
    if (txt.includes('push')) return 'push';
    if (txt.includes('pull')) return 'pull';
    if (txt.includes('legs') || txt.includes('jambe')) return 'legs';
    if (txt.includes('upper') || txt.includes('haut')) return 'upper';
    if (txt.includes('full') || txt.includes('corps')) return 'full_body';
    const first = (tpl.days || [])[0]?.exercises?.[0]?.exerciseId;
    const ex = EXERCISES.find(e => e.id === first);
    return ex?.muscle || 'full_body';
  }
  function mapTemplate(tpl) {
    const exercises = [];
    (tpl.days || []).forEach(day => (day.exercises || []).forEach(ex => {
      exercises.push({
        exerciseId:ex.exerciseId,
        sets:ex.sets || ex.targetSets || 3,
        repsRange:String(ex.reps || ex.targetReps || 10),
        restSeconds:Number(ex.restSeconds ?? ex.rest ?? 90)
      });
    }));
    const cat = templateCategory(tpl);
    return {
      id:tpl.id,
      name:tpl.name,
      category:cat,
      color:COLORS[cat] || '#E8682C',
      duration:Math.max(25, exercises.length * 12),
      exercises,
      runs:0,
      raw:tpl
    };
  }
  function mapWorkout(w) {
    const exercises = (w.exercises || []).map(ex => {
      const meta = EXERCISES.find(e => e.id === ex.exerciseId);
      const sets = (ex.sets || []).map(s => ({
        weight:Number(s.weight || 0),
        reps:Number(s.reps || 0),
        done:s.completed !== false,
        isPR:!!s.isPR
      }));
      return { exerciseId:ex.exerciseId, name:meta?.name || ex.exerciseId, sets };
    });
    const volume = exercises.reduce((sum, e) => sum + e.sets.reduce((s, set) => s + set.weight * set.reps, 0), 0);
    const dateText = w.date || (w.createdAt || '').slice(0,10);
    const dateTs = dateText && /^\d{4}-\d{2}-\d{2}$/.test(dateText)
      ? new Date(Number(dateText.slice(0,4)), Number(dateText.slice(5,7)) - 1, Number(dateText.slice(8,10))).getTime()
      : new Date(w.date || w.createdAt || Date.now()).getTime();
    return {
      id:w.id,
      date:dateText,
      dateTs,
      templateId:w.templateId,
      name:w.name || 'Workout',
      duration:w.durationMinutes || w.duration || 45,
      volume:Math.round(volume),
      prs:exercises.reduce((sum, e) => sum + e.sets.filter(s => s.isPR).length, 0),
      exercises
    };
  }
  function displayName(u) {
    return [u.firstName, u.lastName].filter(Boolean).join(' ') || u.username || u.email || ('User ' + u.id);
  }
  function mapDbUser(u, currentUserId, history) {
    const name = displayName(u);
    const isCurrent = String(u.id) === String(currentUserId);
    const workouts = isCurrent ? history : [];
    const workouts30 = workouts.filter(w => Date.now() - w.dateTs < 30 * 86400000).length;
    const role = u.role || 'user';
    return {
      id:u.id,
      name,
      email:u.email || '',
      username:u.username || '',
      role,
      coachId:u.coachId || null,
      coach:u.coachId || null,
      workouts30,
      lastActive:workouts[0]?.date || '—',
      plan:role === 'admin' ? 'Admin' : role === 'coach' ? 'Coach' : 'Member',
      gender:u.sex || 'male',
      goal:'General fitness',
      streak:0,
      complianceTraining:workouts30 ? 100 : 0,
      complianceNutrition:0,
      weight:0,
      weightDelta:0,
      mealPlan:null
    };
  }
  function recalcDerived() {
    window.MUSCLE_GROUPS = Object.values(MUSCLE_LABELS);
    window.MUSCLES = window.MUSCLE_GROUPS;
    window.EQUIPMENT = ['barbell','dumbbell','machine','cable','bodyweight','kettlebell'];
    window.LEVELS = ['beginner','intermediate','advanced'];
    MUSCLE_GROUPS = window.MUSCLE_GROUPS;
    MUSCLES = window.MUSCLES;
    EQUIPMENT = window.EQUIPMENT;
    LEVELS = window.LEVELS;

    const stats = {};
    window.HISTORY.forEach(w => (w.exercises || []).forEach(e => {
      if (!stats[e.exerciseId]) stats[e.exerciseId] = { sessions:0, bestWeight:0, bestE1RM:0 };
      stats[e.exerciseId].sessions++;
      (e.sets || []).forEach(s => {
        if (s.weight > stats[e.exerciseId].bestWeight) stats[e.exerciseId].bestWeight = s.weight;
        const e1rm = s.weight * (1 + s.reps / 30);
        if (e1rm > stats[e.exerciseId].bestE1RM) stats[e.exerciseId].bestE1RM = Math.round(e1rm);
      });
    }));
    Object.keys(stats).forEach(k => {
      stats[k].bestWeight = stats[k].bestWeight ? stats[k].bestWeight + ' kg' : '—';
      stats[k].bestE1RM = stats[k].bestE1RM ? stats[k].bestE1RM + ' kg' : '—';
    });
    window.HISTORY_STATS_BY_EXERCISE = stats;
    HISTORY_STATS_BY_EXERCISE = stats;
    window.TEMPLATES = window.TEMPLATES.map(t => ({
      ...t,
      runs:window.HISTORY.filter(w => w.templateId === t.id).length
    }));
    TEMPLATES = window.TEMPLATES;
  }
  async function loadGusBackendData() {
    if (!token()) return { ok:false, auth:false, error:'Connexion requise' };
    const today = new Date();
    const todayKey = new Date(today.getTime() - today.getTimezoneOffset() * 60000).toISOString().slice(0,10);
    const [me, catalog, custom, templates, workouts, bio, users, nutritionLog, nutritionPlans] = await Promise.all([
      api('/auth/me').catch(() => null),
      api('/exercises/catalog'),
      api('/exercises/custom').catch(() => []),
      api('/templates').catch(() => []),
      api('/workouts').catch(() => []),
      api('/stats/body').catch(() => []),
      api('/users').catch(() => []),
      api('/nutrition/logs/' + todayKey).catch(() => null),
      api('/nutrition/plans').catch(() => [])
    ]);
    window.EXERCISES = (catalog.exercises || []).concat(custom || []).map(mapExercise);
    EXERCISES = window.EXERCISES;
    window.TEMPLATES = (templates || []).map(mapTemplate);
    TEMPLATES = window.TEMPLATES;
    window.HISTORY = (workouts || []).map(mapWorkout).sort((a,b) => b.dateTs - a.dateTs);
    HISTORY = window.HISTORY;
    window.BIOMETRICS = (bio || []).map(s => ({
      date:(s.recordedAt || '').slice(0,10),
      weight:s.weightKg || 0,
      bodyFat:s.bodyFatPercent || 0,
      chest:0, waist:0, arm:0, thigh:0
    })).filter(s => s.date);
    BIOMETRICS = window.BIOMETRICS;
    if (nutritionLog) {
      const mealLabels = { breakfast:'Breakfast', lunch:'Lunch', dinner:'Dinner', snacks:'Snack' };
      const meals = Object.entries(nutritionLog.meals || {}).map(([type, items]) => {
        const clean = (items || []).map(it => ({
          name:it.name || it.product_name || 'Food',
          fr:it.fr || it.name || it.product_name || 'Food',
          amount:it.amount || it.portion || '100g',
          kcal:Math.round(Number(it.kcal ?? it.calories ?? it.energy ?? 0)),
          protein:Number(it.protein ?? it.p ?? 0),
          carbs:Number(it.carbs ?? it.c ?? 0),
          fat:Number(it.fat ?? it.f ?? 0)
        }));
        return {
          type:mealLabels[type] || type,
          key:type,
          time:'',
          kcal:clean.reduce((s, it) => s + it.kcal, 0),
          protein:Math.round(clean.reduce((s, it) => s + it.protein, 0)),
          carbs:Math.round(clean.reduce((s, it) => s + it.carbs, 0)),
          fat:Math.round(clean.reduce((s, it) => s + it.fat, 0)),
          items:clean
        };
      });
      const totals = meals.reduce((a, m) => ({
        kcal:a.kcal + m.kcal,
        protein:a.protein + m.protein,
        carbs:a.carbs + m.carbs,
        fat:a.fat + m.fat
      }), { kcal:0, protein:0, carbs:0, fat:0 });
      window.NUTRITION_TODAY = { ...window.NUTRITION_TODAY, date:todayKey, meals, totals };
      NUTRITION_TODAY = window.NUTRITION_TODAY;
    }
    window.MEAL_PLANS = (nutritionPlans || []).map(p => ({
      id:p.id,
      name:p.name || 'Plan alimentaire',
      note:p.description || p.note || '',
      raw:p,
      sharedWith:p.sharedWith || [],
      days:Array.isArray(p.days) ? p.days : [],
      numDays:Number(p.numDays || (Array.isArray(p.days) ? p.days.length : 0) || 1),
      target:p.target || p.goals || {
        kcal:Number(p.kcal || 2200),
        protein:Number(p.protein || 160),
        carbs:Number(p.carbs || 240),
        fat:Number(p.fat || 70)
      },
      suggestions:p.suggestions || p.meals || { breakfast:[], lunch:[], dinner:[], snacks:[] }
    }));
    if (me) {
      const name = displayName(me);
      const dbUsers = (Array.isArray(users) && users.length ? users : [me]).map(u => mapDbUser(u, me.id, window.HISTORY));
      window.USERS = dbUsers;
      window.MEMBERS = dbUsers;
      window.COACH_ATHLETES = me.role === 'coach'
        ? dbUsers.filter(u => u.role === 'user' && String(u.coachId || '') === String(me.id))
        : dbUsers.filter(u => u.role === 'user');
      window.COACH_AVAILABLE_USERS = me.role === 'coach'
        ? dbUsers.filter(u => u.role === 'user' && !u.coachId)
        : [];
      window.USER = {
        ...window.USER,
        id:me.id,
        firstName:me.firstName || '',
        lastName:me.lastName || '',
        name,
        full:name,
        initial:name[0] || 'G',
        email:me.email || '',
        username:me.username || '',
        avatar:me.avatar || '',
        avatarColor:me.avatarColor || window.USER.avatarColor || '',
        role:me.role || 'user',
        member_since:(me.createdAt || '').slice(0,10) || window.USER.member_since,
        gender:me.sex || window.USER.gender || 'male',
        totalWorkouts:window.HISTORY.length,
        thisWeek:window.HISTORY.filter(w => Date.now() - w.dateTs < 7 * 86400000).length
      };
      USER = window.USER;
    }
    recalcDerived();
    window.dispatchEvent(new CustomEvent('gus-backend-ready'));
    return { ok:true, auth:true };
  }
  window.GusApi = { api, loadGusBackendData };
  window.loadGusBackendData = loadGusBackendData;
})();
