import { defineStore } from "pinia";
import { ref, computed } from "vue";
import { gradeWeights, calcIMC } from "../composables/useHelpers";
import { useAuthStore } from "./auth";

const API = "/api";

async function apiFetch(path, options = {}) {
  const auth = useAuthStore();
  const headers = { "Content-Type": "application/json" };
  if (auth.token) headers["Authorization"] = `Bearer ${auth.token}`;
  const res = await fetch(`${API}${path}`, { headers, ...options });
  if (!res.ok) throw new Error(`API ${path} → ${res.status}`);
  return res.json();
}

export const useSportsStore = defineStore("sports", () => {
  const activities = ref([]);
  const students = ref([]);
  const notification = ref("");
  const loading = ref(false);

  // ── Persistence ──────────────────────────────────────────────────────────
  async function loadData() {
    loading.value = true;
    try {
      const [s, a] = await Promise.all([
        apiFetch("/students"),
        apiFetch("/activities"),
      ]);
      students.value = s;
      activities.value = a;
    } catch (e) {
      showNotification("Erreur de connexion au serveur");
      console.error(e);
    } finally {
      loading.value = false;
    }
  }

  // ── Notification ─────────────────────────────────────────────────────────
  function showNotification(msg) {
    notification.value = msg;
    setTimeout(() => (notification.value = ""), 3000);
  }

  // ── Students ─────────────────────────────────────────────────────────────
  async function saveStudent(form, editingId) {
    const imc = calcIMC(form.weight, form.height);
    if (editingId) {
      await apiFetch(`/students/${editingId}`, {
        method: "PUT",
        body: JSON.stringify({ ...form, imc }),
      });
      const idx = students.value.findIndex((s) => s.id === editingId);
      if (idx !== -1) students.value[idx] = { ...form, id: editingId, imc };
      showNotification("Profil mis à jour");
    } else {
      const id = Date.now().toString();
      await apiFetch("/students", {
        method: "POST",
        body: JSON.stringify({ id, ...form, imc }),
      });
      students.value.push({ id, ...form, imc });
      showNotification("Étudiant inscrit");
    }
  }

  async function deleteStudent(id) {
    await apiFetch(`/students/${id}`, { method: "DELETE" });
    students.value = students.value.filter((s) => s.id !== id);
    activities.value = activities.value.filter((a) => a.studentId !== id);
    showNotification("Étudiant supprimé");
  }

  // ── Activities ───────────────────────────────────────────────────────────
  async function saveActivity(act, editingId) {
    let norm = act.durationInput;
    if (act.durationUnit === "sec") norm /= 60;
    if (act.durationUnit === "h") norm *= 60;

    const record = {
      ...act,
      id: editingId || Date.now().toString(),
      duration: norm,
      displayDuration: `${act.durationInput} ${act.durationUnit}`,
    };

    if (editingId) {
      await apiFetch(`/activities/${editingId}`, {
        method: "PUT",
        body: JSON.stringify(record),
      });
      const idx = activities.value.findIndex((a) => a.id === editingId);
      if (idx !== -1) activities.value[idx] = record;
      showNotification("Activité mise à jour");
    } else {
      await apiFetch("/activities", {
        method: "POST",
        body: JSON.stringify(record),
      });
      activities.value.unshift(record);
      showNotification("Activité enregistrée");
    }
  }

  async function deleteActivity(index) {
    const act = activities.value[index];
    await apiFetch(`/activities/${act.id}`, { method: "DELETE" });
    activities.value.splice(index, 1);
    showNotification("Supprimé");
  }

  // ── Helpers ──────────────────────────────────────────────────────────────
  function getStudentName(id) {
    const s = students.value.find((st) => st.id === id);
    return s ? `${s.lastName} ${s.firstName}` : "Inconnu";
  }

  function getSelectedStudentIMC(id) {
    return students.value.find((s) => s.id === id)?.imc || 0;
  }

  function getStudentAveragePoints(studentId) {
    const evals = activities.value.filter(
      (a) => a.studentId === studentId && a.grade,
    );
    if (!evals.length) return -1;
    return (
      evals.reduce((acc, a) => acc + gradeWeights[a.grade], 0) / evals.length
    );
  }

  function getStudentAverageLiteral(studentId) {
    const avg = getStudentAveragePoints(studentId);
    if (avg === -1) return "Non noté";
    const rounded = Math.round(avg);
    return Object.keys(gradeWeights).find((k) => gradeWeights[k] === rounded);
  }

  function getStudentEvaluationsCount(id) {
    return activities.value.filter((a) => a.studentId === id && a.grade).length;
  }

  // ── Computed stats ────────────────────────────────────────────────────────
  const totalMinutes = computed(() =>
    activities.value.reduce((acc, c) => acc + (c.duration || 0), 0),
  );

  const successRate = computed(() =>
    activities.value.length
      ? Math.round(
          (activities.value.filter((a) => a.grade && a.grade !== "Redouble")
            .length /
            activities.value.length) *
            100,
        )
      : 0,
  );

  const gradeStats = computed(() => {
    const total = students.value.length || 1;
    const averages = students.value.map((s) => getStudentAverageLiteral(s.id));
    const pct = (g) =>
      Math.round((averages.filter((v) => v === g).length / total) * 100);
    return {
      excellent: pct("Excellent"),
      tresBien: pct("Très bien"),
      bien: pct("Bien"),
      assezBien: pct("Assez bien"),
      redouble: pct("Redouble"),
    };
  });

  const activityLifestyleStats = computed(() => {
    const stats = {
      Inactif: { count: 0, percentage: 0 },
      Sédentaire: { count: 0, percentage: 0 },
      Actif: { count: 0, percentage: 0 },
      "Très actif": { count: 0, percentage: 0 },
    };
    activities.value.forEach((a) => {
      const key = a.lifestyle || "Sédentaire";
      if (stats[key]) stats[key].count++;
    });
    const total = activities.value.length || 1;
    Object.keys(stats).forEach(
      (k) => (stats[k].percentage = Math.round((stats[k].count / total) * 100)),
    );
    return stats;
  });

  return {
    activities,
    students,
    notification,
    loading,
    loadData,
    showNotification,
    saveStudent,
    deleteStudent,
    saveActivity,
    deleteActivity,
    getStudentName,
    getSelectedStudentIMC,
    getStudentAveragePoints,
    getStudentAverageLiteral,
    getStudentEvaluationsCount,
    totalMinutes,
    successRate,
    gradeStats,
    activityLifestyleStats,
  };
});
