import { db } from "./firebase-config.js";
import { requireAuth, setupLogoutButton } from "./app-guard.js";
import { showLoader, hideLoader } from "./loader.js";
import { showToast } from "./toast.js";

import {
  doc,
  getDoc,
  collection,
  getDocs,
  query,
  where,
  updateDoc,
  serverTimestamp
} from "https://www.gstatic.com/firebasejs/10.12.2/firebase-firestore.js";

const urlParams = new URLSearchParams(window.location.search);
const playerId = urlParams.get("id");

const playerName = document.getElementById("playerName");
const playerMeta = document.getElementById("playerMeta");

const playerStatus = document.getElementById("playerStatus");
const playerAttendance = document.getElementById("playerAttendance");
const playerWellness = document.getElementById("playerWellness");
const playerInjuries = document.getElementById("playerInjuries");

const playerProfileDetails = document.getElementById("playerProfileDetails");

const playerReadiness = document.getElementById("playerReadiness");
const playerAttendanceList = document.getElementById("playerAttendanceList");
const playerWellnessList = document.getElementById("playerWellnessList");
const playerInjuryList = document.getElementById("playerInjuryList");

const coachNotesForm = document.getElementById("coachNotesForm");
const coachNotes = document.getElementById("coachNotes");

const playerRatingsList = document.getElementById("playerRatingsList");

const playerAverageRating = document.getElementById("playerAverageRating");
const playerMatchesPlayed = document.getElementById("playerMatchesPlayed");
const playerTotalTries = document.getElementById("playerTotalTries");
const playerTotalCards = document.getElementById("playerTotalCards");

const playerInsights = document.getElementById("playerInsights");

const ratingTrendChart = document.getElementById("ratingTrendChart");
const wellnessTrendChart = document.getElementById("wellnessTrendChart");
const trainingLoadTrendChart = document.getElementById("trainingLoadTrendChart");

const playerTotalTrainingLoad = document.getElementById("playerTotalTrainingLoad");
const playerAverageTrainingLoad = document.getElementById("playerAverageTrainingLoad");
const playerHighLoadSessions = document.getElementById("playerHighLoadSessions");
const playerOverloadRisk = document.getElementById("playerOverloadRisk");
const playerTrainingLoadList = document.getElementById("playerTrainingLoadList");

let activeProfile = null;
let currentPlayer = null;
let currentTeam = null;

let attendanceRecords = [];
let trainingAttendanceRecords = [];
let wellnessRecords = [];
let injuryRecords = [];
let ratingRecords = [];
let matchEventRecords = [];
let trainingSessionRecords = [];

let ratingChartInstance = null;
let wellnessChartInstance = null;
let trainingLoadChartInstance = null;

function escapeHTML(value) {
  return String(value ?? "")
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;")
    .replaceAll("'", "&#039;");
}

function canRenderChart() {
  return typeof Chart !== "undefined";
}

function getSessionLoad(session) {
  return Number(
    session.sessionLoad ||
    session.trainingLoad ||
    session.load ||
    0
  );
}

function getSessionDuration(session) {
  return Number(
    session.durationMinutes ||
    session.trainingDuration ||
    session.duration ||
    0
  );
}

function getSessionType(session) {
  return session.type || session.trainingType || "training";
}

function getPlayerTeamIds(player) {
  const teamIds = Array.isArray(player?.teamIds)
    ? [...player.teamIds]
    : [];

  if (player?.teamId && !teamIds.includes(player.teamId)) {
    teamIds.push(player.teamId);
  }

  return teamIds.filter(Boolean);
}

function canAccessPlayer(player) {
  const role = activeProfile.role;
  const assignedTeamIds = activeProfile.assignedTeamIds || [];
  const assignedPlayerIds = activeProfile.assignedPlayerIds || [];
  const playerTeamIds = getPlayerTeamIds(player);

  if (role === "director") return true;

  if (role === "coach") {
    return playerTeamIds.some((teamId) => assignedTeamIds.includes(teamId));
  }

  if (role === "biokineticist") {
    return (
      playerTeamIds.some((teamId) => assignedTeamIds.includes(teamId)) ||
      assignedPlayerIds.includes(player.id)
    );
  }

  if (role === "player") {
    return (
      player.userId === activeProfile.uid ||
      player.id === activeProfile.playerId ||
      assignedPlayerIds.includes(player.id)
    );
  }

  return false;
}

function getDateValue(record) {
  if (record.createdAt?.toDate) return record.createdAt.toDate();
  if (record.createdDate) return new Date(record.createdDate);
  if (record.date) return new Date(record.date);
  if (record.sessionDate) return new Date(record.sessionDate);
  return new Date(0);
}

function getPlayerName(player) {
  return `${player?.firstName || ""} ${player?.lastName || ""}`.trim() || "Unnamed Player";
}

function isActiveInjury(record) {
  const status = String(record.status || "").toLowerCase();
  return status !== "cleared" && status !== "closed" && status !== "resolved";
}

function getWellnessScore(record) {
  if (!record) return 0;

  const sleep = Number(record.sleep || 0);
  const fatigue = Number(record.fatigue || 0);
  const soreness = Number(record.soreness || 0);

  return sleep + (6 - fatigue) + (6 - soreness);
}

function destroyChart(chartInstance) {
  if (chartInstance) {
    chartInstance.destroy();
  }
}

async function getPlayerRecords(collectionName) {
  const q = query(
    collection(db, collectionName),
    where("organisationId", "==", activeProfile.organisationId),
    where("playerId", "==", playerId)
  );

  const snapshot = await getDocs(q);

  return snapshot.docs.map((docSnap) => ({
    id: docSnap.id,
    ...docSnap.data()
  }));
}

async function getTeamTrainingSessions() {
  const teamIds = getPlayerTeamIds(currentPlayer);

  if (!teamIds.length) return [];

  const sessionSnapshots = await Promise.all(
    teamIds.slice(0, 10).map((teamId) =>
      getDocs(
        query(
          collection(db, "trainingSessions"),
          where("organisationId", "==", activeProfile.organisationId),
          where("teamId", "==", teamId)
        )
      )
    )
  );

  const uniqueSessions = new Map();

  sessionSnapshots.forEach((snapshot) => {
    snapshot.docs.forEach((docSnap) => {
      uniqueSessions.set(docSnap.id, {
        id: docSnap.id,
        ...docSnap.data()
      });
    });
  });

  return Array.from(uniqueSessions.values());
}

async function loadPlayerProfile() {
  const playerRef = doc(db, "players", playerId);
  const snapshot = await getDoc(playerRef);

  if (!snapshot.exists()) {
    playerName.textContent = "Player not found";
    return false;
  }

  currentPlayer = {
    id: snapshot.id,
    ...snapshot.data()
  };

  if (currentPlayer.organisationId !== activeProfile.organisationId) {
    showToast("This player does not belong to your organisation.", "error");

    if (activeProfile.role === "player") {
      window.location.href = "player-dashboard.html";
    } else {
      window.location.href = "players.html";
    }

    return false;
  }

  if (!canAccessPlayer(currentPlayer)) {
    showToast("You do not have access to this player profile.", "error");

    if (activeProfile.role === "player") {
      window.location.href = "player-dashboard.html";
    } else {
      window.location.href = "players.html";
    }

    return false;
  }

  const teamIds = getPlayerTeamIds(currentPlayer);

  if (teamIds.length) {
    const teamSnap = await getDoc(doc(db, "teams", teamIds[0]));

    if (teamSnap.exists()) {
      currentTeam = {
        id: teamSnap.id,
        ...teamSnap.data()
      };
    }
  }

  renderPlayerProfile();
  return true;
}

async function loadPlayerData() {
  const [
    attendance,
    trainingAttendance,
    wellness,
    injuries,
    ratings,
    matchEvents,
    trainingSessions
  ] = await Promise.all([
    getPlayerRecords("attendance"),
    getPlayerRecords("trainingAttendance"),
    getPlayerRecords("wellness"),
    getPlayerRecords("injuries"),
    getPlayerRecords("playerRatings"),
    getPlayerRecords("matchEvents"),
    getTeamTrainingSessions()
  ]);

  attendanceRecords = attendance;
  trainingAttendanceRecords = trainingAttendance;
  wellnessRecords = wellness.sort((a, b) => getDateValue(b) - getDateValue(a));
  injuryRecords = injuries.sort((a, b) => getDateValue(b) - getDateValue(a));
  ratingRecords = ratings.sort((a, b) => getDateValue(a) - getDateValue(b));
  matchEventRecords = matchEvents;
  trainingSessionRecords = trainingSessions;
}

function renderPlayerProfile() {
  playerName.textContent = getPlayerName(currentPlayer);

  const teamDisplay =
    currentPlayer.teamNames?.length
      ? currentPlayer.teamNames.join(", ")
      : currentPlayer.teamName || currentTeam?.name || "No team";

  playerMeta.textContent = `
    ${teamDisplay} •
    ${currentPlayer.position || "No position"} •
    ${currentPlayer.ageGroup || "No age group"}
  `;

  playerStatus.textContent = currentPlayer.status || "available";

  playerProfileDetails.innerHTML = `
    <div><span>Teams</span><strong>${escapeHTML(teamDisplay)}</strong></div>
    <div><span>Jersey</span><strong>${escapeHTML(currentPlayer.jerseyNumber || "N/A")}</strong></div>
    <div><span>Height</span><strong>${escapeHTML(currentPlayer.heightCm || "N/A")} cm</strong></div>
    <div><span>Weight</span><strong>${escapeHTML(currentPlayer.weightKg || "N/A")} kg</strong></div>
    <div><span>Dominant Side</span><strong>${escapeHTML(currentPlayer.dominantSide || "N/A")}</strong></div>
    <div><span>Guardian</span><strong>${escapeHTML(currentPlayer.guardianName || "N/A")}</strong></div>
    <div><span>Guardian Phone</span><strong>${escapeHTML(currentPlayer.guardianPhone || "N/A")}</strong></div>
    <div><span>Medical Aid</span><strong>${escapeHTML(currentPlayer.medicalAid || "N/A")}</strong></div>
    <div><span>Allergies</span><strong>${escapeHTML(currentPlayer.allergies || "None")}</strong></div>
    <div class="profile-notes-cell"><span>Medical Notes</span><strong>${escapeHTML(currentPlayer.medicalNotes || "None")}</strong></div>
  `;

  if (coachNotes) {
    coachNotes.value = currentPlayer.coachNotes || "";
  }
}

function renderAttendance() {
  const matchRecords = attendanceRecords.map((record) => ({
    source: "General",
    date: record.date || "No date",
    status: record.status || "No status",
    detail: record.teamName || "No team",
    ...record
  }));

  const trainingRecords = trainingAttendanceRecords.map((record) => ({
    source: "Training",
    date: record.sessionDate || "No date",
    status: record.status || "No status",
    detail: `${record.teamName || "No team"} • ${record.sessionType || "training"}`,
    ...record
  }));

  const records = [...matchRecords, ...trainingRecords].sort((a, b) => {
    return getDateValue(b) - getDateValue(a);
  });

  const presentCount = records.filter((record) => {
    return record.status === "present";
  }).length;

  const attendanceRate = records.length
    ? Math.round((presentCount / records.length) * 100)
    : 0;

  playerAttendance.textContent = `${attendanceRate}%`;

  playerAttendanceList.innerHTML = "";

  if (!records.length) {
    playerAttendanceList.innerHTML = `
      <div class="list-item">No attendance records.</div>
    `;
    return;
  }

  records.forEach((record) => {
    const item = document.createElement("div");
    item.className = "attendance-card";

    item.innerHTML = `
      <div>
        <h3>${record.date || "No date"}</h3>
        <p>
          ${record.source}
          <span class="record-separator">&bull;</span>
          ${record.status || "No status"}
          <span class="record-separator">&bull;</span>
          ${record.detail || ""}
        </p>
      </div>
    `;

    playerAttendanceList.appendChild(item);
  });
}

function renderWellness() {
  playerWellnessList.innerHTML = "";

  if (!wellnessRecords.length) {
    playerWellnessList.innerHTML = `
      <div class="list-item">No wellness records.</div>
    `;

    playerWellness.textContent = "-";
    return;
  }

  const latest = wellnessRecords[0];

  const totalScore = getWellnessScore(latest);

  playerWellness.textContent = `${totalScore}/15`;

  wellnessRecords.forEach((record) => {
    const item = document.createElement("div");
    item.className = "wellness-card";

    item.innerHTML = `
      <div class="wellness-card-header">
        <div>
          <h3>${record.createdDate || "No date"}</h3>
        </div>

        <span class="wellness-score">
          ${getWellnessScore(record)}/15
        </span>
      </div>

      <div class="wellness-metrics">
        <div><span>Sleep</span><strong>${record.sleep}/5</strong></div>
        <div><span>Fatigue</span><strong>${record.fatigue}/5</strong></div>
        <div><span>Soreness</span><strong>${record.soreness}/5</strong></div>
      </div>
    `;

    playerWellnessList.appendChild(item);
  });

  renderWellnessTrendChart(wellnessRecords);
}

function renderInjuries() {
  const activeInjuries = injuryRecords.filter((record) => {
    return isActiveInjury(record);
  });

  playerInjuries.textContent = activeInjuries.length;

  playerInjuryList.innerHTML = "";

  if (!injuryRecords.length) {
    playerInjuryList.innerHTML = `
      <div class="list-item">No injury history.</div>
    `;
    return;
  }

  injuryRecords.forEach((record) => {
    const item = document.createElement("div");
    item.className = "injury-card";

    item.innerHTML = `
      <div class="injury-card-header">
        <div>
          <h3>${record.type || "Unknown Injury"}</h3>
          <p>${record.createdDate || "No date"}</p>
        </div>

        <span class="status-pill injury-${record.status || "active"}">
          ${record.status || "active"}
        </span>
      </div>

      <div class="injury-card-grid">
        <div><span>Severity</span><strong>${record.severity || "N/A"}</strong></div>
        <div><span>Status</span><strong>${record.status || "N/A"}</strong></div>
      </div>
    `;

    playerInjuryList.appendChild(item);
  });
}

function updateReadinessStatus() {
  const status = (currentPlayer?.status || "available").toLowerCase();
  const attendanceText = playerAttendance.textContent.replace("%", "");
  const attendanceScore = Number(attendanceText || 0);

  const wellnessText = playerWellness.textContent.replace("/15", "");
  const wellnessScore = Number(wellnessText || 0);

  const injuryTotal = Number(playerInjuries.textContent || 0);

  if (status === "injured" || status === "rehab" || injuryTotal > 0) {
    playerReadiness.textContent = "Unavailable";
    playerReadiness.className = "readiness-unavailable";
    return;
  }

  if (attendanceScore < 70 || wellnessScore < 11) {
    playerReadiness.textContent = "Monitor";
    playerReadiness.className = "readiness-monitor";
    return;
  }

  playerReadiness.textContent = "Ready";
  playerReadiness.className = "readiness-ready";
}

if (coachNotesForm) {
  coachNotesForm.addEventListener("submit", async function (event) {
    event.preventDefault();

    if (activeProfile.role === "player") {
      showToast("Players can view their profile but cannot edit coach notes.", "warning");
      return;
    }

    try {
      await updateDoc(doc(db, "players", playerId), {
        coachNotes: coachNotes.value.trim(),
        coachNotesUpdatedAt: serverTimestamp()
      });

      if (currentPlayer) {
        currentPlayer.coachNotes = coachNotes.value.trim();
      }

      showToast("Coach notes saved successfully.", "success");
    } catch (error) {
      console.error("Error saving coach notes:", error);
      showToast("Could not save coach notes: " + error.message, "error");
    }
  });
}

function renderPlayerRatings() {
  playerRatingsList.innerHTML = "";

  if (!ratingRecords.length) {
    playerRatingsList.innerHTML = `<div class="list-item">No match ratings yet.</div>`;
    playerAverageRating.textContent = "0";
    playerMatchesPlayed.textContent = "0";
    return;
  }

  const totalRating = ratingRecords.reduce((sum, rating) => {
    return sum + Number(rating.rating || 0);
  }, 0);

  const averageRating = ratingRecords.length
    ? (totalRating / ratingRecords.length).toFixed(1)
    : 0;

  playerAverageRating.textContent = averageRating;
  playerMatchesPlayed.textContent = ratingRecords.length;

  ratingRecords.forEach((rating) => {
    const item = document.createElement("div");
    item.className = "list-item";

    item.innerHTML = `
      <strong>${rating.playerName || "Unknown Player"}</strong>
      <small>Rating: ${rating.rating || "-"}/10</small>
      <small>${rating.comment || "No comment"}</small>
    `;

    playerRatingsList.appendChild(item);
  });

  renderRatingTrendChart(ratingRecords);
}

function renderPlayerMatchEvents() {
  const tries = matchEventRecords.filter((event) => event.type === "try").length;

  const cards = matchEventRecords.filter((event) => {
    return event.type === "yellow_card" || event.type === "red_card";
  }).length;

  playerTotalTries.textContent = tries;
  playerTotalCards.textContent = cards;
}

function renderPlayerTrainingLoad() {
  const presentRecords = trainingAttendanceRecords.filter((record) => {
    return record.status === "present" || record.status === "late";
  });

  const sessionIds = new Set(
    presentRecords.map((record) => record.trainingSessionId)
  );

  const sessions = trainingSessionRecords.filter((session) => {
    return sessionIds.has(session.id);
  });

  if (!sessions.length) {
    playerTotalTrainingLoad.textContent = "0";
    playerAverageTrainingLoad.textContent = "0";
    playerHighLoadSessions.textContent = "0";
    playerOverloadRisk.textContent = "0";
    playerTrainingLoadList.innerHTML = `<div class="list-item">No training load records yet.</div>`;
    return;
  }

  const totalLoad = sessions.reduce((sum, session) => {
    return sum + getSessionLoad(session);
  }, 0);

  const averageLoad = sessions.length
    ? Math.round(totalLoad / sessions.length)
    : 0;

  const highLoadCount = sessions.filter((session) => {
    return getSessionLoad(session) >= 350;
  }).length;

  const overloadCount = sessions.filter((session) => {
    return getSessionLoad(session) >= 500;
  }).length;

  playerTotalTrainingLoad.textContent = totalLoad;
  playerAverageTrainingLoad.textContent = averageLoad;
  playerHighLoadSessions.textContent = highLoadCount;
  playerOverloadRisk.textContent = overloadCount;

  playerTrainingLoadList.innerHTML = "";

  const sortedSessions = [...sessions].sort((a, b) => {
    return new Date(b.date || "1900-01-01") - new Date(a.date || "1900-01-01");
  });

  sortedSessions.forEach((session) => {
    const item = document.createElement("div");
    item.className = "attendance-card";

    item.innerHTML = `
      <div>
        <h3>${escapeHTML(session.date || "No date")} • ${escapeHTML(getSessionType(session))}</h3>
        <p>
          ${escapeHTML(session.teamName || "No team")}
          <span class="record-separator">&bull;</span>
          Load: ${getSessionLoad(session)}
          <span class="record-separator">&bull;</span>
          Duration: ${getSessionDuration(session)} min
          <span class="record-separator">&bull;</span>
          Intensity: ${escapeHTML(session.intensity || session.trainingIntensity || "-")}
        </p>
      </div>
    `;

    playerTrainingLoadList.appendChild(item);
  });

  renderTrainingLoadTrendChart(sessions);
}

function renderPlayerInsights() {
  const insights = [];

  const attendanceScore = Number(playerAttendance.textContent.replace("%", "") || 0);
  const wellnessScore = Number(playerWellness.textContent.replace("/15", "") || 0);
  const injuryTotal = Number(playerInjuries.textContent || 0);
  const averageRating = Number(playerAverageRating.textContent || 0);
  const matchesPlayed = Number(playerMatchesPlayed.textContent || 0);
  const tries = Number(playerTotalTries.textContent || 0);
  const cards = Number(playerTotalCards.textContent || 0);

  const totalTrainingLoad = Number(playerTotalTrainingLoad.textContent || 0);
  const averageTrainingLoad = Number(playerAverageTrainingLoad.textContent || 0);
  const highLoadSessions = Number(playerHighLoadSessions.textContent || 0);
  const overloadRisk = Number(playerOverloadRisk.textContent || 0);

  if (attendanceScore >= 85) {
    insights.push({
      title: "Strong Attendance",
      text: "This player has a strong attendance record and is consistently available for training or match activity."
    });
  } else if (attendanceScore > 0 && attendanceScore < 70) {
    insights.push({
      title: "Attendance Concern",
      text: "This player has a lower attendance rate and may need follow-up from the coach."
    });
  }

  if (wellnessScore > 0 && wellnessScore < 11) {
    insights.push({
      title: "Wellness Risk",
      text: "The latest wellness score is high. Monitor fatigue, soreness and recovery before selection."
    });
  } else if (wellnessScore >= 11) {
    insights.push({
      title: "Positive Wellness",
      text: "The latest wellness score is within a healthy range."
    });
  }

  if (injuryTotal > 0) {
    insights.push({
      title: "Injury Watch",
      text: "This player currently has active injury records and should be reviewed before selection."
    });
  }

  if (matchesPlayed >= 3 && averageRating >= 8) {
    insights.push({
      title: "High Performer",
      text: "This player is showing strong match performance based on coach ratings."
    });
  } else if (matchesPlayed >= 3 && averageRating < 6) {
    insights.push({
      title: "Performance Support Needed",
      text: "Match ratings indicate that this player may need additional coaching support."
    });
  }

  if (tries > 0) {
    insights.push({
      title: "Scoring Contribution",
      text: `This player has scored ${tries} trie(s) in recorded match events.`
    });
  }

  if (cards > 0) {
    insights.push({
      title: "Discipline Alert",
      text: `This player has received ${cards} recorded card(s). Discipline should be monitored.`
    });
  }

  if (overloadRisk > 0) {
    insights.push({
      title: "Overload Risk",
      text: `This player has ${overloadRisk} overload-risk training session(s). Monitor recovery and injury risk.`
    });
  } else if (highLoadSessions > 0) {
    insights.push({
      title: "High Training Load",
      text: `This player has completed ${highLoadSessions} high-load training session(s). Recovery should be monitored.`
    });
  }

  if (averageTrainingLoad >= 350 && injuryTotal > 0) {
    insights.push({
      title: "Load + Injury Concern",
      text: "This player has a high average training load and active injury records. Selection should be reviewed carefully."
    });
  }

  if (totalTrainingLoad > 0 && attendanceScore >= 85) {
    insights.push({
      title: "Consistent Training Exposure",
      text: "This player has strong attendance and recorded training load, indicating consistent training exposure."
    });
  }

  if (!insights.length) {
    insights.push({
      title: "No Major Alerts",
      text: "There are no major performance alerts for this player yet."
    });
  }

  playerInsights.innerHTML = "";

  insights.forEach((insight) => {
    const item = document.createElement("div");
    item.className = "insight-card";

    item.innerHTML = `
      <h3>${insight.title}</h3>
      <p>${insight.text}</p>
    `;

    playerInsights.appendChild(item);
  });
}

function renderRatingTrendChart(ratings) {
  if (!ratings.length || !ratingTrendChart || !canRenderChart()) return;

  destroyChart(ratingChartInstance);
  ratingChartInstance = null;

  const labels = ratings.map((_, index) => `Match ${index + 1}`);
  const data = ratings.map((rating) => Number(rating.rating || 0));

  ratingChartInstance = new Chart(ratingTrendChart, {
    type: "line",

    data: {
      labels,
      datasets: [
        {
          label: "Match Rating",
          data,
          tension: 0.3,
          fill: false
        }
      ]
    },

    options: {
      responsive: true,
      plugins: {
        legend: {
          labels: {
            color: "#ffffff"
          }
        }
      },

      scales: {
        y: {
          beginAtZero: true,
          max: 10,
          ticks: {
            color: "#ffffff"
          }
        },

        x: {
          ticks: {
            color: "#ffffff"
          }
        }
      }
    }
  });
}

function renderWellnessTrendChart(records) {
  if (!records.length || !wellnessTrendChart || !canRenderChart()) return;

  destroyChart(wellnessChartInstance);
  wellnessChartInstance = null;

  const sortedRecords = [...records].sort((a, b) => {
    return getDateValue(a) - getDateValue(b);
  });

  const labels = sortedRecords.map((record) => {
    return record.createdDate || "Wellness";
  });

  const data = sortedRecords.map((record) => {
    return getWellnessScore(record);
  });

  wellnessChartInstance = new Chart(wellnessTrendChart, {
    type: "line",

    data: {
      labels,
      datasets: [
        {
          label: "Wellness Score",
          data,
          tension: 0.3,
          fill: false
        }
      ]
    },

    options: {
      responsive: true,

      plugins: {
        legend: {
          labels: {
            color: "#ffffff"
          }
        }
      },

      scales: {
        y: {
          beginAtZero: true,
          max: 15,

          ticks: {
            color: "#ffffff"
          }
        },

        x: {
          ticks: {
            color: "#ffffff"
          }
        }
      }
    }
  });
}

function renderTrainingLoadTrendChart(sessions) {
  if (!sessions.length || !trainingLoadTrendChart || !canRenderChart()) return;

  destroyChart(trainingLoadChartInstance);
  trainingLoadChartInstance = null;

  const sortedSessions = [...sessions].sort((a, b) => {
    return new Date(a.date || "1900-01-01") - new Date(b.date || "1900-01-01");
  });

  const labels = sortedSessions.map((session) => {
    return session.date || "Session";
  });

  const data = sortedSessions.map((session) => {
    return getSessionLoad(session);
  });

  trainingLoadChartInstance = new Chart(trainingLoadTrendChart, {
    type: "line",

    data: {
      labels,
      datasets: [
        {
          label: "Training Load",
          data,
          tension: 0.3,
          fill: false
        }
      ]
    },

    options: {
      responsive: true,

      plugins: {
        legend: {
          labels: {
            color: "#ffffff"
          }
        }
      },

      scales: {
        y: {
          beginAtZero: true,
          ticks: {
            color: "#ffffff"
          }
        },

        x: {
          ticks: {
            color: "#ffffff"
          }
        }
      }
    }
  });
}

function renderPage() {
  renderAttendance();
  renderWellness();
  renderInjuries();
  renderPlayerRatings();
  renderPlayerMatchEvents();
  renderPlayerTrainingLoad();

  updateReadinessStatus();
  renderPlayerInsights();
}

requireAuth(async function (user, profile) {
  activeProfile = profile;
  setupLogoutButton();

  if (!playerId) {
    playerName.textContent = "Invalid Player";

    if (playerProfileDetails) {
      playerProfileDetails.innerHTML = `
        <div class="list-item">
          <strong>Invalid player.</strong>
          <p>No player ID was found in the page URL.</p>
        </div>
      `;
    }

    return;
  }

  showLoader("Loading player profile...");

  try {
    const loaded = await loadPlayerProfile();

    if (!loaded || !currentPlayer) return;

    await loadPlayerData();
    renderPage();

  } catch (error) {
    console.error("Player detail error:", error);
    playerName.textContent = "Could not load player profile";
    playerProfileDetails.innerHTML = `<div class="list-item">Error: ${error.message}</div>`;
    showToast("Could not load player profile: " + error.message, "error");
  } finally {
    hideLoader();
  }
});