// =========================================================
// FILE: post-match-report.js | TYPE: Elite Post-Match Report
// =========================================================

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,
  addDoc,
  query,
  where,
  updateDoc,
  deleteDoc,
  serverTimestamp
} from "https://www.gstatic.com/firebasejs/10.12.2/firebase-firestore.js";

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

const reportTitle = document.getElementById("reportTitle");
const reportMeta = document.getElementById("reportMeta");

const reportHomeScore = document.getElementById("reportHomeScore");
const reportAwayScore = document.getElementById("reportAwayScore");
const reportHomeTeam = document.getElementById("reportHomeTeam");
const reportAwayTeam = document.getElementById("reportAwayTeam");
const reportTries = document.getElementById("reportTries");
const reportCards = document.getElementById("reportCards");
const reportAverageRating = document.getElementById("reportAverageRating");
const reportBestRating = document.getElementById("reportBestRating");
const reportBestPlayer = document.getElementById("reportBestPlayer");
const reportResult = document.getElementById("reportResult");
const reportMatchGrade = document.getElementById("reportMatchGrade");
const reportMatchGradeText = document.getElementById("reportMatchGradeText");
const reportStatus = document.getElementById("reportStatus");
const reportStatusText = document.getElementById("reportStatusText");

const reportScrumSuccess = document.getElementById("reportScrumSuccess");
const reportScrumsWon = document.getElementById("reportScrumsWon");
const reportScrumsLost = document.getElementById("reportScrumsLost");

const reportLineoutSuccess = document.getElementById("reportLineoutSuccess");
const reportLineoutsWon = document.getElementById("reportLineoutsWon");
const reportLineoutsLost = document.getElementById("reportLineoutsLost");

const reportRuckTurnoverBalance = document.getElementById("reportRuckTurnoverBalance");
const reportRuckTurnoversFor = document.getElementById("reportRuckTurnoversFor");
const reportRuckTurnoversAgainst = document.getElementById("reportRuckTurnoversAgainst");

const reportTackleCompletion = document.getElementById("reportTackleCompletion");
const reportTacklesMade = document.getElementById("reportTacklesMade");
const reportTacklesMissed = document.getElementById("reportTacklesMissed");

const forwardOfMatchName = document.getElementById("forwardOfMatchName");
const forwardOfMatchPosition = document.getElementById("forwardOfMatchPosition");
const forwardOfMatchRating = document.getElementById("forwardOfMatchRating");

const backOfMatchName = document.getElementById("backOfMatchName");
const backOfMatchPosition = document.getElementById("backOfMatchPosition");
const backOfMatchRating = document.getElementById("backOfMatchRating");

const matchInsightsGrid = document.getElementById("matchInsightsGrid");
const coachSummary = document.getElementById("coachSummary");

const reportStartingSquad = document.getElementById("reportStartingSquad");
const reportBenchSquad = document.getElementById("reportBenchSquad");
const reportTimeline = document.getElementById("reportTimeline");

const printPostMatchBtn = document.getElementById("printPostMatchBtn");
const postMatchNotesForm = document.getElementById("postMatchNotesForm");
const postMatchNotes = document.getElementById("postMatchNotes");
const exportPostMatchCsvBtn = document.getElementById("exportPostMatchCsvBtn");
const saveReportStatusBtn = document.getElementById("saveReportStatusBtn");
const unlockReportBtn = document.getElementById("unlockReportBtn");

const playerRatingForm = document.getElementById("playerRatingForm");
const ratingPlayer = document.getElementById("ratingPlayer");
const ratingScore = document.getElementById("ratingScore");
const ratingComment = document.getElementById("ratingComment");
const playerRatingsList = document.getElementById("playerRatingsList");

let activeProfile = null;
let currentMatch = null;
let currentTeam = null;
let eventsCache = [];
let playersCache = [];
let ratingsCache = [];
let latestSelection = null;
let editingRatingId = null;

const ratingSubmitButton = playerRatingForm?.querySelector("button[type='submit']");

function getPercentage(success, failed) {
  const total = Number(success || 0) + Number(failed || 0);

  if (!total) return "0%";

  return `${Math.round((Number(success || 0) / total) * 100)}%`;
}

function getEventPoints(event) {
  if (event.type === "try") return 5;

  if (event.type === "conversion") {
    return event.conversionResult === "successful" ? 2 : 0;
  }

  if (event.type === "penalty") return 3;
  if (event.type === "drop_goal") return 3;

  return 0;
}

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

function getPlayerTeamIds(player) {
  if (!player) return [];

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

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

  return teamIds.filter(Boolean);
}

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

function getPlayerNameFromRating(rating) {
  return rating.playerName || "Unknown Player";
}

function canAccessMatch(match) {
  if (!activeProfile || !match) return false;

  const role = activeProfile.role;
  const assignedTeamIds = activeProfile.assignedTeamIds || [];

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

  if (role === "coach" || role === "biokineticist" || role === "player") {
    return assignedTeamIds.includes(match.teamId);
  }

  return false;
}

function sortEvents() {
  eventsCache.sort((a, b) => Number(a.minute || 0) - Number(b.minute || 0));
}

function sortRatings() {
  ratingsCache.sort((a, b) => {
    return getPlayerNameFromRating(a).localeCompare(getPlayerNameFromRating(b));
  });
}

function setButtonLoading(button, isLoading, loadingText, defaultText) {
  if (!button) return;

  button.disabled = isLoading;
  button.textContent = isLoading ? loadingText : defaultText;
}

async function loadMatch() {
  const matchSnap = await getDoc(doc(db, "matches", matchId));

  if (!matchSnap.exists()) {
    if (reportTitle) reportTitle.textContent = "Match not found";
    return false;
  }

  currentMatch = { id: matchSnap.id, ...matchSnap.data() };

  if (currentMatch.organisationId !== activeProfile.organisationId) {
    showToast("This match does not belong to your organisation.", "error");
    window.location.href = "matches.html";
    return false;
  }

  if (!canAccessMatch(currentMatch)) {
    showToast("You do not have access to this post-match report.", "error");
    window.location.href = "matches.html";
    return false;
  }

  if (currentMatch.teamId) {
    const teamSnap = await getDoc(doc(db, "teams", currentMatch.teamId));

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

  if (reportTitle) {
    reportTitle.textContent = `${currentTeam?.name || "Team"} vs ${currentMatch.opponent || "Opponent"}`;
  }

  if (reportMeta) {
    reportMeta.textContent = `${currentMatch.date || "No date"} • ${currentMatch.venue || "No venue"} • ${currentMatch.type || "match"}`;
  }

  if (reportHomeTeam) reportHomeTeam.textContent = currentTeam?.name || "Team";
  if (reportAwayTeam) reportAwayTeam.textContent = currentMatch.opponent || "Opponent";

  if (postMatchNotes) {
    postMatchNotes.value = currentMatch.postMatchNotes || "";
  }

  return true;
}

async function loadReportData() {
  const eventsQuery = query(
    collection(db, "matchEvents"),
    where("matchId", "==", matchId),
    where("organisationId", "==", activeProfile.organisationId)
  );

  const selectionQuery = query(
    collection(db, "matchSelections"),
    where("matchId", "==", matchId),
    where("organisationId", "==", activeProfile.organisationId)
  );

  const playersQuery = query(
    collection(db, "players"),
    where("organisationId", "==", activeProfile.organisationId)
  );

  const ratingsQuery = query(
    collection(db, "playerRatings"),
    where("matchId", "==", matchId),
    where("organisationId", "==", activeProfile.organisationId)
  );

  const [
    eventsSnapshot,
    selectionSnapshot,
    playersSnapshot,
    ratingsSnapshot
  ] = await Promise.all([
    getDocs(eventsQuery),
    getDocs(selectionQuery),
    getDocs(playersQuery),
    getDocs(ratingsQuery)
  ]);

  eventsCache = eventsSnapshot.docs.map((docSnap) => ({
    id: docSnap.id,
    ...docSnap.data()
  }));

  sortEvents();

  const selections = selectionSnapshot.docs.map((docSnap) => ({
    id: docSnap.id,
    ...docSnap.data()
  }));

  selections.sort((a, b) => getDateValue(b) - getDateValue(a));
  latestSelection = selections[0] || null;

  playersCache = playersSnapshot.docs
    .map((docSnap) => ({
      id: docSnap.id,
      ...docSnap.data()
    }))
    .filter((player) => {
      return getPlayerTeamIds(player).includes(currentMatch.teamId);
    });

  playersCache.sort((a, b) => {
    return getPlayerName(a).toLowerCase().localeCompare(getPlayerName(b).toLowerCase());
  });

  ratingsCache = ratingsSnapshot.docs.map((docSnap) => ({
    id: docSnap.id,
    ...docSnap.data()
  }));

  sortRatings();
}

function renderScoreStats() {
  let home = 0;
  let away = 0;

  eventsCache.forEach((event) => {
    const points = getEventPoints(event);

    if (event.team === "home") home += points;
    if (event.team === "away") away += points;
  });

  if (reportHomeScore) reportHomeScore.textContent = currentMatch.homeScore ?? home;
  if (reportAwayScore) reportAwayScore.textContent = currentMatch.awayScore ?? away;

  const tries = eventsCache.filter((event) => {
    return event.team === "home" && event.type === "try";
  }).length;

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

  if (reportTries) reportTries.textContent = tries;
  if (reportCards) reportCards.textContent = cards;
}

function renderTeamMatchAnalytics() {
  const stats = currentMatch?.teamStats || {};

  const scrumsWon = Number(stats.scrumsWon || 0);
  const scrumsLost = Number(stats.scrumsLost || 0);

  const lineoutsWon = Number(stats.lineoutsWon || 0);
  const lineoutsLost = Number(stats.lineoutsLost || 0);

  const ruckFor = Number(stats.ruckTurnoversFor || 0);
  const ruckAgainst = Number(stats.ruckTurnoversAgainst || 0);

  const tacklesMade = Number(stats.tacklesMade || 0);
  const tacklesMissed = Number(stats.tacklesMissed || 0);

  if (reportScrumSuccess) reportScrumSuccess.textContent = getPercentage(scrumsWon, scrumsLost);
  if (reportScrumsWon) reportScrumsWon.textContent = scrumsWon;
  if (reportScrumsLost) reportScrumsLost.textContent = scrumsLost;

  if (reportLineoutSuccess) reportLineoutSuccess.textContent = getPercentage(lineoutsWon, lineoutsLost);
  if (reportLineoutsWon) reportLineoutsWon.textContent = lineoutsWon;
  if (reportLineoutsLost) reportLineoutsLost.textContent = lineoutsLost;

  if (reportRuckTurnoverBalance) reportRuckTurnoverBalance.textContent = ruckFor - ruckAgainst;
  if (reportRuckTurnoversFor) reportRuckTurnoversFor.textContent = ruckFor;
  if (reportRuckTurnoversAgainst) reportRuckTurnoversAgainst.textContent = ruckAgainst;

  if (reportTackleCompletion) reportTackleCompletion.textContent = getPercentage(tacklesMade, tacklesMissed);
  if (reportTacklesMade) reportTacklesMade.textContent = tacklesMade;
  if (reportTacklesMissed) reportTacklesMissed.textContent = tacklesMissed;
}

function renderSquadList(container, players, emptyMessage, fallbackStartNumber) {
  if (!container) return;

  container.innerHTML = "";

  if (!players?.length) {
    container.innerHTML = `<div class="list-item">${emptyMessage}</div>`;
    return;
  }

  players.forEach((player, index) => {
    const squadNumber = index + fallbackStartNumber;
    const role = player.selectedRole || player.position || "No position";

    const item = document.createElement("div");
    item.className = "squad-player-card";

    item.innerHTML = `
      <div>
        <strong>${squadNumber}. ${player.name || "Unknown Player"}</strong>
        <span>${role}</span>
      </div>
    `;

    container.appendChild(item);
  });
}

function renderSquad() {
  if (!latestSelection) {
    renderEmptySquad();
    return;
  }

  renderSquadList(
    reportStartingSquad,
    latestSelection.startingSquad || [],
    "No starting squad saved.",
    1
  );

  renderSquadList(
    reportBenchSquad,
    latestSelection.benchSquad || [],
    "No bench saved.",
    16
  );
}

function renderEmptySquad() {
  if (reportStartingSquad) {
    reportStartingSquad.innerHTML = `<div class="list-item">No starting squad saved.</div>`;
  }

  if (reportBenchSquad) {
    reportBenchSquad.innerHTML = `<div class="list-item">No bench saved.</div>`;
  }
}

function renderTimeline() {
  if (!reportTimeline) return;

  reportTimeline.innerHTML = "";

  if (!eventsCache.length) {
    reportTimeline.innerHTML = `<div class="list-item">No match events recorded.</div>`;
    return;
  }

  eventsCache.forEach((event) => {
    const item = document.createElement("div");
    item.className = "timeline-event elite-timeline-event";

    item.innerHTML = `
      <div class="timeline-minute">${event.minute}'</div>

      <div class="timeline-content">
        <h3>
          ${String(event.type || "").replace("_", " ").toUpperCase()}
          ${
            event.type === "conversion"
              ? ` • ${event.conversionResult === "missed" ? "MISSED" : "SUCCESSFUL"}`
              : ""
          }
        </h3>

        <p>
          ${event.team === "home" ? currentTeam?.name || "Team" : currentMatch.opponent || "Opponent"}
          ${event.playerName ? " • " + event.playerName : ""}
          ${event.notes ? " • " + event.notes : ""}
        </p>
      </div>
    `;

    reportTimeline.appendChild(item);
  });
}

function renderRatingPlayerDropdown() {
  if (!ratingPlayer) return;

  ratingPlayer.innerHTML = `<option value="">Select player</option>`;

  if (latestSelection) {
    const startingSquad = latestSelection.startingSquad || [];
    const benchSquad = latestSelection.benchSquad || [];

    if (startingSquad.length) {
      const group = document.createElement("optgroup");
      group.label = "Starting XV";

      startingSquad.forEach((player) => {
        const option = document.createElement("option");
        option.value = player.playerId;
        option.textContent = `${player.name || "Unknown Player"} — ${player.selectedRole || player.position || "No role"}`;
        group.appendChild(option);
      });

      ratingPlayer.appendChild(group);
    }

    if (benchSquad.length) {
      const group = document.createElement("optgroup");
      group.label = "Bench";

      benchSquad.forEach((player) => {
        const option = document.createElement("option");
        option.value = player.playerId;
        option.textContent = `${player.name || "Unknown Player"} — ${player.selectedRole || player.position || "No role"}`;
        group.appendChild(option);
      });

      ratingPlayer.appendChild(group);
    }

    if (startingSquad.length || benchSquad.length) {
      return;
    }
  }

  playersCache.forEach((player) => {
    const option = document.createElement("option");
    option.value = player.id;
    option.textContent = getPlayerName(player);
    ratingPlayer.appendChild(option);
  });
}

function renderPlayerRatings() {
  if (!playerRatingsList) return;

  playerRatingsList.innerHTML = "";

  if (!ratingsCache.length) {
    playerRatingsList.innerHTML = `<div class="list-item">No player ratings saved yet.</div>`;
    return;
  }

  ratingsCache.forEach((rating) => {
    const item = document.createElement("div");
    item.className = "list-item elite-readiness-row";

    item.innerHTML = `
      <div>
        <h3>${rating.playerName || "Unknown Player"}</h3>
        <p>${rating.comment || "No comment"}</p>
      </div>

      <div class="report-metrics">
        <span>${rating.rating}/10</span>

        <button class="btn-secondary edit-rating-btn" data-id="${rating.id}" type="button">
          Edit
        </button>

        <button class="btn-danger delete-rating-btn" data-id="${rating.id}" type="button">
          Delete
        </button>
      </div>
    `;

    playerRatingsList.appendChild(item);
  });
}

function renderAverageRating() {
  if (!reportAverageRating) return;

  if (!ratingsCache.length) {
    reportAverageRating.textContent = "0";
    return;
  }

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

  reportAverageRating.textContent = (total / ratingsCache.length).toFixed(1);
}

function renderBestRatedPlayer() {
  if (!reportBestRating || !reportBestPlayer) return;

  if (!ratingsCache.length) {
    reportBestRating.textContent = "-";
    reportBestPlayer.textContent = "Top performer";
    return;
  }

  const bestRating = [...ratingsCache].sort((a, b) => {
    return Number(b.rating || 0) - Number(a.rating || 0);
  })[0];

  reportBestRating.textContent = `${bestRating.rating}/10`;
  reportBestPlayer.textContent = bestRating.playerName || "Top performer";
}

function renderMatchResult() {
  if (!reportResult) return;

  const home = Number(reportHomeScore?.textContent || currentMatch.homeScore || 0);
  const away = Number(reportAwayScore?.textContent || currentMatch.awayScore || 0);

  let result = currentMatch.result || "pending";

  if (!result || result === "pending") {
    if (home > away) result = "win";
    if (home < away) result = "loss";
    if (home === away && currentMatch.status === "Full Time") result = "draw";
  }

  reportResult.textContent = String(result || "pending").toUpperCase();
}

function renderPlayersOfTheMatch() {
  const forwards = [
    "Loosehead Prop",
    "Hooker",
    "Tighthead Prop",
    "Lock",
    "Flanker",
    "Number Eight",
    "Number 8"
  ];

  const backs = [
    "Scrumhalf",
    "Flyhalf",
    "Wing",
    "Inside Centre",
    "Outside Centre",
    "Centre",
    "Fullback"
  ];

  let bestForward = null;
  let bestBack = null;

  ratingsCache.forEach((rating) => {
    const squadPlayer =
      latestSelection?.startingSquad?.find((player) => player.playerId === rating.playerId) ||
      latestSelection?.benchSquad?.find((player) => player.playerId === rating.playerId);

    const role = squadPlayer?.selectedRole || squadPlayer?.position || "";

    if (forwards.includes(role)) {
      if (!bestForward || Number(rating.rating || 0) > Number(bestForward.rating || 0)) {
        bestForward = { ...rating, role };
      }
    }

    if (backs.includes(role)) {
      if (!bestBack || Number(rating.rating || 0) > Number(bestBack.rating || 0)) {
        bestBack = { ...rating, role };
      }
    }
  });

  if (forwardOfMatchName) forwardOfMatchName.textContent = bestForward?.playerName || "No forward ratings";
  if (forwardOfMatchPosition) forwardOfMatchPosition.textContent = bestForward?.role || "Forward performance will appear here.";
  if (forwardOfMatchRating) forwardOfMatchRating.textContent = bestForward ? `${bestForward.rating}/10` : "-";

  if (backOfMatchName) backOfMatchName.textContent = bestBack?.playerName || "No backline ratings";
  if (backOfMatchPosition) backOfMatchPosition.textContent = bestBack?.role || "Backline performance will appear here.";
  if (backOfMatchRating) backOfMatchRating.textContent = bestBack ? `${bestBack.rating}/10` : "-";
}

function renderMatchInsights() {
  if (!matchInsightsGrid) return;

  const homeTries = eventsCache.filter((event) => {
    return event.team === "home" && event.type === "try";
  }).length;

  const conversions = eventsCache.filter((event) => {
    return event.team === "home" && event.type === "conversion";
  });

  const successfulConversions = conversions.filter((event) => {
    return event.conversionResult === "successful";
  }).length;

  const conversionRate = conversions.length
    ? Math.round((successfulConversions / conversions.length) * 100)
    : 0;

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

  const topRated = [...ratingsCache].sort((a, b) => {
    return Number(b.rating || 0) - Number(a.rating || 0);
  })[0];

  const insights = [
    {
      title: "Finishing",
      text: `${homeTries} tries scored. ${homeTries >= 3 ? "Strong attacking output." : "Attack conversion can improve."}`
    },
    {
      title: "Goal Kicking",
      text: conversions.length
        ? `${conversionRate}% conversion success from ${conversions.length} attempt(s).`
        : "No conversion attempts recorded."
    },
    {
      title: "Discipline",
      text: cards
        ? `${cards} card event(s) recorded. Discipline review recommended.`
        : "No card events recorded."
    },
    {
      title: "Impact Player",
      text: topRated
        ? `${topRated.playerName} was the highest rated player with ${topRated.rating}/10.`
        : "No player ratings captured yet."
    }
  ];

  matchInsightsGrid.innerHTML = "";

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

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

    matchInsightsGrid.appendChild(item);
  });
}

function renderCoachSummary() {
  if (!coachSummary) return;

  const homeScore = Number(reportHomeScore?.textContent || 0);
  const awayScore = Number(reportAwayScore?.textContent || 0);
  const tries = eventsCache.filter((event) => event.team === "home" && event.type === "try").length;
  const cards = eventsCache.filter((event) => event.type === "yellow_card" || event.type === "red_card").length;

  let resultText = "The match outcome is still pending.";

  if (homeScore > awayScore) {
    resultText = "The team secured a positive result.";
  }

  if (homeScore < awayScore) {
    resultText = "The team will need to review key performance areas after the loss.";
  }

  if (homeScore === awayScore && currentMatch.status === "Full Time") {
    resultText = "The match ended level.";
  }

  coachSummary.textContent =
    `${resultText} The team scored ${tries} try/tries and recorded ${cards} card event(s). ` +
    `Player ratings and match events should be reviewed to identify selection, tactical and training focus areas for the next fixture.`;
}

function renderMatchGrade() {
  if (!reportMatchGrade || !reportMatchGradeText) return;

  const homeScore = Number(reportHomeScore?.textContent || 0);
  const awayScore = Number(reportAwayScore?.textContent || 0);
  const tries = eventsCache.filter((event) => event.team === "home" && event.type === "try").length;
  const cards = eventsCache.filter((event) => event.type === "yellow_card" || event.type === "red_card").length;

  const averageRating = ratingsCache.length
    ? ratingsCache.reduce((sum, rating) => sum + Number(rating.rating || 0), 0) / ratingsCache.length
    : 0;

  let grade = "C";
  let text = "Solid performance with clear improvement areas.";

  if (homeScore > awayScore && tries >= 4 && averageRating >= 8 && cards === 0) {
    grade = "A";
    text = "Excellent team performance across score, attack, discipline and player ratings.";
  } else if (homeScore >= awayScore && averageRating >= 7) {
    grade = "B";
    text = "Good performance with positive match control and player contribution.";
  } else if (homeScore < awayScore || averageRating < 6 || cards >= 2) {
    grade = "C";
    text = "Performance review required. Focus on execution, discipline and key player roles.";
  }

  reportMatchGrade.textContent = grade;
  reportMatchGradeText.textContent = text;
}

function renderReportStatus() {
  if (!reportStatus || !reportStatusText) return;

  const isComplete = currentMatch.postMatchReportStatus === "complete";

  reportStatus.textContent = isComplete ? "Complete" : "Draft";
  reportStatusText.textContent = isComplete
    ? "Post-match report has been completed"
    : "Post-match report not completed yet";
}

function applyReportLockState() {
  const isComplete = currentMatch.postMatchReportStatus === "complete";
  const isDirector = activeProfile?.role === "director";

  if (playerRatingForm) {
    playerRatingForm.querySelectorAll("input, select, button").forEach((field) => {
      field.disabled = isComplete;
    });
  }

  if (postMatchNotes) {
    postMatchNotes.disabled = isComplete;
  }

  if (postMatchNotesForm) {
    postMatchNotesForm.querySelectorAll("button").forEach((button) => {
      button.disabled = isComplete;
    });
  }

  if (saveReportStatusBtn) {
    saveReportStatusBtn.disabled = isComplete;
    saveReportStatusBtn.textContent = isComplete ? "Report Complete" : "Mark Report Complete";
  }

  if (unlockReportBtn) {
    unlockReportBtn.classList.toggle("hidden", !(isComplete && isDirector));
  }
}

function renderPage() {
  renderScoreStats();
  renderTeamMatchAnalytics();
  renderSquad();
  renderTimeline();
  renderRatingPlayerDropdown();
  renderPlayerRatings();
  renderAverageRating();
  renderBestRatedPlayer();
  renderMatchResult();
  renderPlayersOfTheMatch();
  renderMatchInsights();
  renderCoachSummary();
  renderMatchGrade();
  renderReportStatus();
  applyReportLockState();
}

printPostMatchBtn?.addEventListener("click", generatePDF);

async function generatePDF() {
  if (printPostMatchBtn) {
    printPostMatchBtn.disabled = true;
    printPostMatchBtn.textContent = "Building PDF...";
  }
  showLoader("Building PDF report...");

  try {
    if (!window.jspdf) {
      await new Promise((resolve, reject) => {
        const s = document.createElement("script");
        s.src = "https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js";
        s.onload = resolve; s.onerror = reject;
        document.head.appendChild(s);
      });
    }

    const { jsPDF } = window.jspdf;
    const pdf = new jsPDF({ orientation: "portrait", unit: "mm", format: "a4" });

    const PW = 210, PH = 297, ML = 16, MR = 16, CW = PW - ML - MR;

    // Colours — white background, professional print
    const BLACK  = [15, 20, 30];
    const DARK   = [40, 50, 70];
    const BODY   = [70, 80, 100];
    const MUTED  = [140, 150, 165];
    const BORDER = [210, 215, 225];
    const BGLITE = [248, 250, 252];
    const BGMID  = [237, 241, 247];
    const BGHEAD = [220, 228, 240];
    const ACCENT = [30, 80, 180];
    const GREEN  = [20, 120, 60];
    const GREENL = [218, 242, 228];
    const AMBER  = [150, 90, 0];
    const AMBERL = [255, 244, 210];
    const RED    = [180, 35, 35];
    const REDL   = [255, 228, 228];
    const WHITE  = [255, 255, 255];

    function setF(style, size, color) {
      pdf.setFont("helvetica", style);
      pdf.setFontSize(size);
      pdf.setTextColor(...color);
    }
    function t(text, x, y, opts) { pdf.text(String(text ?? ""), x, y, opts || {}); }
    function box(x, y, w, h, fill, stroke, r) {
      if (fill)   pdf.setFillColor(...fill);
      if (stroke) { pdf.setDrawColor(...stroke); pdf.setLineWidth(0.3); }
      const m = fill && stroke ? "FD" : fill ? "F" : "S";
      r ? pdf.roundedRect(x, y, w, h, r, r, m) : pdf.rect(x, y, w, h, m);
    }
    function line(y, x1, x2, col, lw) {
      pdf.setDrawColor(...(col||BORDER)); pdf.setLineWidth(lw||0.3);
      pdf.line(x1||ML, y, x2||(PW-MR), y);
    }
    function secHead(lbl, x, y) {
      setF("bold", 8, ACCENT); t(lbl.toUpperCase(), x, y);
      line(y+2, x, PW-MR, ACCENT, 0.5);
      return y + 7;
    }
    function tHead(cols, widths, x, y, rh) {
      rh = rh || 7;
      const tw = widths.reduce((a,b)=>a+b,0);
      box(x, y, tw, rh, BGHEAD, BORDER, 2);
      let cx = x;
      cols.forEach((c,i) => {
        setF("bold", 7.5, ACCENT);
        t(String(c).toUpperCase(), cx+3, y+rh/2+1.5, {baseline:"middle"});
        cx += widths[i];
      });
      return y + rh;
    }
    function tRow(cols, widths, x, y, rh, alt, colorMap) {
      rh = rh || 7.5;
      const tw2 = widths.reduce((a,b)=>a+b,0);
      box(x, y, tw2, rh, alt ? BGLITE : WHITE, BORDER, 1.5);
      let cx = x;
      cols.forEach((c,i) => {
        const col = (colorMap && colorMap[i]) || DARK;
        const bold = colorMap && colorMap[i];
        setF(bold ? "bold" : "normal", 8, col);
        const lines = pdf.splitTextToSize(String(c ?? ""), widths[i]-6);
        t(lines[0]||"", cx+3, y+rh/2+1.5, {baseline:"middle"});
        cx += widths[i];
      });
      return y + rh;
    }

    async function loadLogo() {
      try {
        const res = await fetch("assets/trytrack-logo.png");
        const blob = await res.blob();
        return await new Promise(r => { const fr=new FileReader(); fr.onload=()=>r(fr.result); fr.readAsDataURL(blob); });
      } catch { return null; }
    }

    function pageHeader(pageNum, logo, title, sub) {
      box(0, 0, PW, 22, WHITE, null);
      box(0, 0, 4, 22, ACCENT, null);
      if (logo) pdf.addImage(logo, "PNG", 7, 3, 40, 13);
      else { setF("bold", 12, ACCENT); t("TryTrack", 8, 12); }
      setF("bold", 9.5, BLACK); t(title, PW-MR, 9, {align:"right"});
      setF("normal", 7.5, MUTED); t(sub, PW-MR, 15, {align:"right"});
      pdf.setDrawColor(...BORDER); pdf.setLineWidth(0.4); pdf.line(0, 22, PW, 22);
      setF("normal", 7, MUTED); t("Page "+pageNum+" of 4", PW/2, PH-6, {align:"center"});
      line(PH-9, ML, PW-MR, BORDER, 0.2);
      setF("normal", 6.5, MUTED); t("Confidential · TryTrack Post-Match Report · www.trytrack.co.za", PW/2, PH-4, {align:"center"});
    }

    // Collect data from the live DOM
    const teamName   = document.getElementById("reportHomeTeam")?.textContent?.trim()  || "Team";
    const opponent   = document.getElementById("reportAwayTeam")?.textContent?.trim()  || "Opponent";
    const homeScore  = document.getElementById("reportHomeScore")?.textContent?.trim() || "0";
    const awayScore  = document.getElementById("reportAwayScore")?.textContent?.trim() || "0";
    const tries_     = document.getElementById("reportTries")?.textContent?.trim()     || "0";
    const cards_     = document.getElementById("reportCards")?.textContent?.trim()     || "0";
    const avgRat     = document.getElementById("reportAverageRating")?.textContent?.trim() || "0";
    const grade      = document.getElementById("reportMatchGrade")?.textContent?.trim()    || "—";
    const gradeText  = document.getElementById("reportMatchGradeText")?.textContent?.trim()|| "";
    const result     = document.getElementById("reportResult")?.textContent?.trim()     || "—";
    const status     = document.getElementById("reportStatus")?.textContent?.trim()     || "Draft";
    const coachTxt   = document.getElementById("coachSummary")?.textContent?.trim()    || "";
    const bestRat    = document.getElementById("reportBestRating")?.textContent?.trim() || "—";
    const bestPlayer = document.getElementById("reportBestPlayer")?.textContent?.trim() || "—";
    const scrumPct   = document.getElementById("reportScrumSuccess")?.textContent?.trim()   || "0%";
    const lineoutPct = document.getElementById("reportLineoutSuccess")?.textContent?.trim() || "0%";
    const ruckBal    = document.getElementById("reportRuckTurnoverBalance")?.textContent?.trim() || "0";
    const tacklePct  = document.getElementById("reportTackleCompletion")?.textContent?.trim()    || "0%";
    const ts         = currentMatch?.teamStats || {};
    const fwdName    = document.getElementById("forwardOfMatchName")?.textContent?.trim()   || "—";
    const fwdPos     = document.getElementById("forwardOfMatchPosition")?.textContent?.trim()|| "";
    const fwdRat     = document.getElementById("forwardOfMatchRating")?.textContent?.trim() || "—";
    const bkName     = document.getElementById("backOfMatchName")?.textContent?.trim()      || "—";
    const bkPos      = document.getElementById("backOfMatchPosition")?.textContent?.trim()  || "";
    const bkRat      = document.getElementById("backOfMatchRating")?.textContent?.trim()    || "—";
    const matchDate  = currentMatch?.date  || "—";
    const venue      = currentMatch?.venue || "—";
    const matchType  = currentMatch?.type  || "—";
    const titleStr   = teamName + " vs " + opponent;
    const subStr     = matchDate + " · " + venue + " · " + matchType;

    const hs = Number(homeScore), as_ = Number(awayScore);
    const resBg = hs > as_ ? GREENL : hs < as_ ? REDL : AMBERL;
    const resFg = hs > as_ ? GREEN  : hs < as_ ? RED  : AMBER;
    const resStr = hs > as_ ? "WIN" : hs < as_ ? "LOSS" : result.toUpperCase();

    const logo = await loadLogo();

    // ═══ PAGE 1 — Overview ═══════════════════════════════════
    box(0,0,PW,PH,WHITE);
    pageHeader(1, logo, titleStr, subStr);
    let y = 28;

    // Scoreboard
    box(ML, y, CW, 34, BGLITE, BORDER, 2);
    box(ML, y, CW, 1.5, ACCENT, null);
    setF("bold",7,MUTED); t("YOUR TEAM", ML+CW*0.25, y+7, {align:"center"});
    setF("bold",30,BLACK); t(homeScore, ML+CW*0.25, y+25, {align:"center"});
    setF("bold",9,DARK);   t(teamName,  ML+CW*0.25, y+31, {align:"center"});
    setF("bold",9,MUTED);  t("VS", ML+CW*0.5, y+17, {align:"center"});
    // Result chip
    const rw = 18; const rx = ML+CW*0.5-rw/2;
    box(rx, y+20, rw, 7, resBg, null, 1.5);
    setF("bold",7,resFg); t(resStr, ML+CW*0.5, y+25, {align:"center"});
    setF("bold",7,MUTED); t("OPPONENT", ML+CW*0.75, y+7, {align:"center"});
    setF("bold",30,BLACK); t(awayScore, ML+CW*0.75, y+25, {align:"center"});
    setF("bold",9,DARK);   t(opponent,  ML+CW*0.75, y+31, {align:"center"});
    y += 40;

    // Stat boxes
    const bw = (CW-9)/4;
    [{l:"Tries",v:tries_,c:GREEN},{l:"Cards",v:cards_,c:Number(cards_)>0?AMBER:DARK},{l:"Avg Rating",v:avgRat,c:ACCENT},{l:"Match Grade",v:grade,c:DARK}]
    .forEach((s,i) => {
      box(ML+i*(bw+3), y, bw, 20, BGLITE, BORDER, 2);
      box(ML+i*(bw+3), y, bw, 1.2, ACCENT, null);
      setF("bold",7,MUTED); t(s.l.toUpperCase(), ML+i*(bw+3)+bw/2, y+7, {align:"center"});
      setF("bold",18,s.c);  t(String(s.v), ML+i*(bw+3)+bw/2, y+16, {align:"center"});
    });
    y += 26;

    // Match details table
    y = secHead("Match Details", ML, y);
    const dW = [42, CW-42];
    y = tHead(["Field","Detail"], dW, ML, y, 7);
    [["Date",matchDate],["Venue",venue],["Match Type",matchType],["Grade",gradeText],["Best Rated",bestPlayer+" — "+bestRat],["Report Status",status]]
    .forEach((r,i)=>{ y = tRow(r, dW, ML, y, 7.5, i%2===0); });
    y += 6;

    // Coach summary
    y = secHead("Coach Summary", ML, y);
    const csLines = pdf.splitTextToSize(coachTxt||"No summary.", CW-10);
    const csH = Math.min(csLines.length*5+10, 28);
    box(ML,y,CW,csH,BGLITE,BORDER,2);
    setF("normal",8.5,BODY); pdf.text(csLines.slice(0,4), ML+5, y+6);
    y += csH+6;

    // Insights
    const insights = [];
    document.querySelectorAll("#matchInsightsGrid .insight-card").forEach(c=>{
      insights.push({title:c.querySelector("h3")?.textContent||"",text:c.querySelector("p")?.textContent||""});
    });
    if (insights.length) {
      y = secHead("Match Insights", ML, y);
      const iW = (CW-4)/2;
      insights.slice(0,4).forEach((ins,i)=>{
        const ix=ML+(i%2)*(iW+4), iy=y+Math.floor(i/2)*16;
        box(ix,iy,iW,14,BGLITE,BORDER,2); box(ix,iy,2.5,14,ACCENT,null);
        setF("bold",8,ACCENT); t(ins.title, ix+6, iy+6);
        setF("normal",7.5,BODY); t(pdf.splitTextToSize(ins.text,iW-10)[0]||"", ix+6, iy+11);
      });
    }

    // ═══ PAGE 2 — Analytics, POTM & Timeline ═════════════════
    pdf.addPage(); box(0,0,PW,PH,WHITE);
    pageHeader(2, logo, titleStr, subStr);
    y = 28;

    // Set piece table
    y = secHead("Set Piece, Breakdown & Defence", ML, y);
    const spW = [58,34,28,CW-58-34-28];
    y = tHead(["Metric","Success %","For","Against/Missed"], spW, ML, y, 7);
    [[" Scrum Success",scrumPct,String(ts.scrumsWon||0),String(ts.scrumsLost||0)],
     ["Lineout Success",lineoutPct,String(ts.lineoutsWon||0),String(ts.lineoutsLost||0)],
     ["Ruck Turnover Balance",ruckBal,String(ts.ruckTurnoversFor||0),String(ts.ruckTurnoversAgainst||0)],
     ["Tackle Completion",tacklePct,String(ts.tacklesMade||0),String(ts.tacklesMissed||0)],
    ].forEach((row,i)=>{
      const pct=parseFloat(row[1])||0;
      const vc = pct>=80?GREEN : pct>=60?AMBER : pct>0?RED : DARK;
      y = tRow(row, spW, ML, y, 8, i%2===0, {1:vc});
    });
    y += 8;

    // Progress bars
    y = secHead("Performance Indicators", ML, y);
    [{l:"Scrum Success",v:scrumPct,c:ACCENT},{l:"Lineout Success",v:lineoutPct,c:GREEN},{l:"Tackle Completion",v:tacklePct,c:AMBER}]
    .forEach(bar=>{
      const pct=Math.min(parseFloat(bar.v)||0,100), bw2=CW-52;
      setF("normal",8,BODY); t(bar.l, ML, y+4);
      box(ML+50,y,bw2,5.5,BGMID,BORDER,1.5);
      if(pct>0) box(ML+50,y,Math.max(bw2*pct/100,3),5.5,bar.c,null,1.5);
      setF("bold",7.5,DARK); t(bar.v, ML+50+bw2+4, y+4);
      y+=10;
    });
    y+=6;

    // POTM
    y = secHead("Players of the Match", ML, y);
    const potmW=(CW-6)/2;
    [[fwdName,fwdPos,fwdRat,"FORWARD OF THE MATCH",ACCENT,GREENL,GREEN],
     [bkName, bkPos, bkRat, "BACKLINE POTM",        GREEN, BGLITE,ACCENT]]
    .forEach(([name,pos,rat,badge,fg,bg_,tc],idx)=>{
      const px=ML+idx*(potmW+6);
      box(px,y,potmW,36,WHITE,BORDER,2); box(px,y,potmW,1.5,fg,null);
      setF("bold",7,fg); t(badge, px+5, y+8);
      setF("bold",12,BLACK); t(pdf.splitTextToSize(name,potmW-10)[0]||"—", px+5, y+17);
      setF("normal",8,MUTED); t(pos, px+5, y+24);
      line(y+27,px+4,px+potmW-4,BORDER,0.3);
      setF("bold",7,MUTED); t("RATING", px+5, y+33);
      setF("bold",12,fg); t(String(rat), px+potmW-5, y+33, {align:"right"});
    });
    y+=42;

    // Timeline
    y = secHead("Match Timeline", ML, y);
    const tlW=[13,42,32,42,CW-13-42-32-42];
    y = tHead(["Min","Team","Event","Player","Notes"], tlW, ML, y, 7);
    const maxTL = Math.floor((PH-y-14)/7.5);
    eventsCache.slice(0,maxTL).forEach((ev,i)=>{
      if(y>PH-16) return;
      const tn=ev.team==="home"?(currentTeam?.name||"Team"):(currentMatch?.opponent||"Opponent");
      const et=String(ev.type||"").replace(/_/g," ")+(ev.type==="conversion"?(ev.conversionResult==="missed"?" (missed)":" (made)"):"");
      y=tRow([String(ev.minute||""),tn,et.charAt(0).toUpperCase()+et.slice(1),ev.playerName||"—",ev.notes||""],tlW,ML,y,7.5,i%2===0);
    });

    // ═══ PAGE 3 — Player Ratings ══════════════════════════════
    pdf.addPage(); box(0,0,PW,PH,WHITE);
    pageHeader(3, logo, titleStr, subStr);
    y = 28;
    y = secHead("Player Performance Ratings", ML, y);

    if(!ratingsCache.length){
      setF("normal",9,MUTED); t("No player ratings submitted for this match.", ML, y+6); y+=14;
    } else {
      const rW=[10,68,22,CW-10-68-22];
      y = tHead(["#","Player","Rating","Comment"], rW, ML, y, 7);
      [...ratingsCache].sort((a,b)=>Number(b.rating||0)-Number(a.rating||0))
      .forEach((rating,i)=>{
        if(y>PH-16) return;
        const r=Number(rating.rating||0);
        const rc=r>=8?GREEN:r>=6?AMBER:RED;
        const rbg=r>=8?GREENL:r>=6?AMBERL:REDL;
        // row bg
        box(ML,y,CW,7.5,i%2===0?BGLITE:WHITE,BORDER,1.5);
        setF("normal",8,MUTED); t(String(i+1), ML+3, y+5);
        setF("normal",8,DARK);  t(rating.playerName||"Unknown", ML+rW[0]+3, y+5);
        // Rating chip
        box(ML+rW[0]+rW[1]+2,y+1.2,rW[2]-4,5,rbg,null,1.5);
        setF("bold",8,rc); t(r+"/10", ML+rW[0]+rW[1]+rW[2]/2, y+5, {align:"center"});
        // Comment
        setF("normal",7.5,BODY); t(rating.comment||"—", ML+rW[0]+rW[1]+rW[2]+3, y+5);
        y+=7.5;
      });
    }

    // Overflow timeline
    if(eventsCache.length>maxTL && y<PH-40){
      y+=8; y=secHead("Match Timeline (continued)", ML, y);
      y=tHead(["Min","Team","Event","Player","Notes"], tlW, ML, y, 7);
      eventsCache.slice(maxTL).forEach((ev,i)=>{
        if(y>PH-16) return;
        const tn=ev.team==="home"?(currentTeam?.name||"Team"):(currentMatch?.opponent||"Opponent");
        const et=String(ev.type||"").replace(/_/g," ");
        y=tRow([String(ev.minute||""),tn,et.charAt(0).toUpperCase()+et.slice(1),ev.playerName||"—",ev.notes||""],tlW,ML,y,7.5,i%2===0);
      });
    }

    // ═══ PAGE 4 — Squad & Coach Notes ════════════════════════
    pdf.addPage(); box(0,0,PW,PH,WHITE);
    pageHeader(4, logo, titleStr, subStr);
    y = 28;
    y = secHead("Selected Squad", ML, y);

    const starting=latestSelection?.startingSquad||[];
    const bench=latestSelection?.benchSquad||[];
    if(!starting.length&&!bench.length){
      setF("normal",9,MUTED); t("No squad selection saved for this match.", ML, y+6); y+=14;
    } else {
      const hW=(CW-6)/2;
      // Headers
      [[" STARTING XV",ML],[" BENCH",ML+hW+6]].forEach(([lbl,x])=>{
        box(x,y,hW,7,BGHEAD,BORDER,2);
        setF("bold",8,ACCENT); t(lbl,x+3,y+5);
      });
      y+=8;
      const maxR=Math.max(starting.length,bench.length);
      for(let i=0;i<maxR;i++){
        if(y>PH-30) break;
        const sp=starting[i], bp=bench[i], bg=i%2===0?BGLITE:WHITE;
        if(sp!==undefined){
          box(ML,y,hW,7.5,bg,BORDER,1.5);
          setF("bold",8,ACCENT);  t(String(i+1)+".", ML+3, y+5.2);
          setF("normal",8,DARK);  t(sp.name||"—", ML+12, y+5.2);
          setF("normal",7,MUTED); t(sp.selectedRole||sp.position||"", ML+hW-3, y+5.2, {align:"right"});
        }
        if(bp!==undefined){
          box(ML+hW+6,y,hW,7.5,bg,BORDER,1.5);
          setF("bold",8,ACCENT);  t(String(i+16)+".", ML+hW+9, y+5.2);
          setF("normal",8,DARK);  t(bp.name||"—", ML+hW+18, y+5.2);
          setF("normal",7,MUTED); t(bp.selectedRole||bp.position||"", PW-MR-3, y+5.2, {align:"right"});
        }
        y+=7.5;
      }
      y+=8;
    }

    // Coach notes
    y = secHead("Coach Notes", ML, y);
    const notes=document.getElementById("postMatchNotes")?.value?.trim()||currentMatch?.postMatchNotes||"No coach notes recorded.";
    const nLines=pdf.splitTextToSize(notes,CW-10);
    const nH=Math.max(nLines.length*5.5+10,24);
    box(ML,y,CW,nH,BGLITE,BORDER,2);
    setF("normal",8.5,BODY); pdf.text(nLines,ML+5,y+7);
    y+=nH+8;

    // Footer
    line(y,ML,PW-MR,BORDER,0.3);
    setF("normal",7.5,MUTED); t("Report generated by TryTrack on "+new Date().toLocaleDateString("en-ZA",{year:"numeric",month:"long",day:"numeric"}), ML, y+5);
    setF("bold",7.5,ACCENT); t("www.trytrack.co.za", PW-MR, y+5, {align:"right"});

    // Save
    const fn="TryTrack-PostMatch-"+(teamName+"-vs-"+opponent+"-"+matchDate).replace(/[^a-zA-Z0-9-]/g,"-")+".pdf";
    pdf.save(fn);
    showToast("PDF downloaded successfully.", "success");

  } catch(err) {
    console.error("PDF error:", err);
    showToast("Could not generate PDF: "+err.message, "error");
  } finally {
    hideLoader();
    if(printPostMatchBtn){ printPostMatchBtn.disabled=false; printPostMatchBtn.textContent="Save as PDF"; }
  }
}

postMatchNotesForm?.addEventListener("submit", async function (event) {
  event.preventDefault();

  try {
    const notes = postMatchNotes?.value.trim() || "";

    await updateDoc(doc(db, "matches", matchId), {
      postMatchNotes: notes,
      postMatchNotesUpdatedAt: serverTimestamp()
    });

    currentMatch.postMatchNotes = notes;

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

function exportPostMatchCSV() {
  let csvContent = "";

  csvContent += "POST MATCH SUMMARY\n";
  csvContent += `"Team","${currentTeam?.name || "Team"}"\n`;
  csvContent += `"Opponent","${currentMatch?.opponent || "Opponent"}"\n`;
  csvContent += `"Date","${currentMatch?.date || ""}"\n`;
  csvContent += `"Home Score","${reportHomeScore?.textContent || "0"}"\n`;
  csvContent += `"Away Score","${reportAwayScore?.textContent || "0"}"\n`;
  csvContent += `"Result","${reportResult?.textContent || "-"}"\n`;
  csvContent += `"Match Grade","${reportMatchGrade?.textContent || "-"}"\n`;
  csvContent += `"Grade Summary","${String(reportMatchGradeText?.textContent || "").replace(/"/g, '""')}"\n`;
  csvContent += `"Coach Summary","${String(coachSummary?.textContent || "").replace(/"/g, '""')}"\n\n`;
  
  const teamStats = currentMatch?.teamStats || {};

  csvContent += "TEAM MATCH ANALYTICS\n";
  csvContent += `"Scrums Won","${teamStats.scrumsWon || 0}"\n`;
  csvContent += `"Scrums Lost","${teamStats.scrumsLost || 0}"\n`;
  csvContent += `"Lineouts Won","${teamStats.lineoutsWon || 0}"\n`;
  csvContent += `"Lineouts Lost","${teamStats.lineoutsLost || 0}"\n`;
  csvContent += `"Ruck Turnovers For","${teamStats.ruckTurnoversFor || 0}"\n`;
  csvContent += `"Ruck Turnovers Against","${teamStats.ruckTurnoversAgainst || 0}"\n`;
  csvContent += `"Tackles Made","${teamStats.tacklesMade || 0}"\n`;
  csvContent += `"Tackles Missed","${teamStats.tacklesMissed || 0}"\n\n`;

  csvContent += "MATCH EVENTS\n";
  csvContent += "Minute,Team,Event Type,Conversion Result,Points,Player,Notes\n";

  eventsCache.forEach((event) => {
    const row = [
      `"${event.minute || ""}"`,
      `"${event.team === "home" ? currentTeam?.name || "Team" : currentMatch.opponent || "Opponent"}"`,
      `"${event.type || ""}"`,
      `"${event.conversionResult || ""}"`,
      `"${getEventPoints(event)}"`,
      `"${event.playerName || ""}"`,
      `"${String(event.notes || "").replace(/"/g, '""')}"`
    ];

    csvContent += row.join(",") + "\n";
  });

  csvContent += "\nPLAYER RATINGS\n";
  csvContent += "Player,Rating,Comment\n";

  ratingsCache.forEach((rating) => {
    const row = [
      `"${rating.playerName || ""}"`,
      `"${rating.rating || ""}"`,
      `"${String(rating.comment || "").replace(/"/g, '""')}"`
    ];

    csvContent += row.join(",") + "\n";
  });

  csvContent += "\nPLAYERS OF THE MATCH\n";
  csvContent += "Category,Player,Position,Rating\n";
  csvContent += `"Forward of the Match","${forwardOfMatchName?.textContent || ""}","${forwardOfMatchPosition?.textContent || ""}","${forwardOfMatchRating?.textContent || ""}"\n`;
  csvContent += `"Backline Player of the Match","${backOfMatchName?.textContent || ""}","${backOfMatchPosition?.textContent || ""}","${backOfMatchRating?.textContent || ""}"\n`;

  const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
  const link = document.createElement("a");
  const url = URL.createObjectURL(blob);

  link.setAttribute("href", url);
  link.setAttribute(
    "download",
    `post-match-report-${currentMatch?.date || "report"}.csv`
  );

  link.style.visibility = "hidden";

  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);

  URL.revokeObjectURL(url);
}

exportPostMatchCsvBtn?.addEventListener("click", exportPostMatchCSV);

saveReportStatusBtn?.addEventListener("click", async function () {
  setButtonLoading(saveReportStatusBtn, true, "Completing...", "Mark Report Complete");

  try {
    await updateDoc(doc(db, "matches", matchId), {
      postMatchReportStatus: "complete",
      postMatchReportCompletedAt: serverTimestamp(),
      postMatchReportCompletedBy: activeProfile.uid,
      updatedAt: serverTimestamp()
    });

    currentMatch.postMatchReportStatus = "complete";

    renderReportStatus();
    applyReportLockState();

    showToast("Post-match report marked as complete.", "success");
  } catch (error) {
    console.error("Error completing report:", error);
    showToast("Could not complete report: " + error.message, "error");
  } finally {
    if (currentMatch?.postMatchReportStatus !== "complete") {
      setButtonLoading(saveReportStatusBtn, false, "Completing...", "Mark Report Complete");
    }
  }
});

unlockReportBtn?.addEventListener("click", async function () {
  const confirmed = confirm("Are you sure you want to unlock this completed report?");
  if (!confirmed) return;

  setButtonLoading(unlockReportBtn, true, "Unlocking...", "Unlock Report");

  try {
    await updateDoc(doc(db, "matches", matchId), {
      postMatchReportStatus: "draft",
      postMatchReportUnlockedAt: serverTimestamp(),
      postMatchReportUnlockedBy: activeProfile.uid,
      updatedAt: serverTimestamp()
    });

    currentMatch.postMatchReportStatus = "draft";

    renderReportStatus();
    applyReportLockState();

    showToast("Post-match report unlocked.", "success");
  } catch (error) {
    console.error("Error unlocking report:", error);
    showToast("Could not unlock report: " + error.message, "error");
  } finally {
    setButtonLoading(unlockReportBtn, false, "Unlocking...", "Unlock Report");
  }
});

playerRatingForm?.addEventListener("submit", async function (event) {
  event.preventDefault();

  const playerId = ratingPlayer?.value || "";

  const selectedPlayer =
    playersCache.find((player) => player.id === playerId) ||
    {
      id: playerId,
      firstName: ratingPlayer?.options[ratingPlayer.selectedIndex]?.textContent || "",
      lastName: ""
    };

  if (!playerId) {
    showToast("Please select a player.", "warning");
    return;
  }

  const ratingValue = Number(ratingScore?.value || 0);

  if (ratingValue < 1 || ratingValue > 10) {
    showToast("Rating must be between 1 and 10.", "warning");
    return;
  }

  const ratingData = {
    matchId,
    teamId: currentMatch.teamId,
    teamIds: getPlayerTeamIds(selectedPlayer),
    teamName: currentTeam?.name || "",
    teamNames: selectedPlayer.teamNames || [],
    playerId: selectedPlayer.id,
    playerName: getPlayerName(selectedPlayer),
    rating: ratingValue,
    comment: ratingComment?.value.trim() || "",
    organisationId: activeProfile.organisationId,
    updatedAt: serverTimestamp()
  };

  setButtonLoading(
    ratingSubmitButton,
    true,
    editingRatingId ? "Updating..." : "Saving...",
    editingRatingId ? "Update Rating" : "Save Rating"
  );

  try {
    if (editingRatingId) {
      await updateDoc(doc(db, "playerRatings", editingRatingId), ratingData);

      ratingsCache = ratingsCache.map((rating) =>
        rating.id === editingRatingId
          ? {
              ...rating,
              ...ratingData,
              updatedAt: new Date()
            }
          : rating
      );

      showToast("Player rating updated successfully.", "success");
    } else {
      const ratingRef = await addDoc(collection(db, "playerRatings"), {
        ...ratingData,
        createdBy: activeProfile.uid,
        createdAt: serverTimestamp()
      });

      ratingsCache.push({
        id: ratingRef.id,
        ...ratingData,
        createdBy: activeProfile.uid,
        createdAt: new Date()
      });

      showToast("Player rating saved successfully.", "success");
    }

    editingRatingId = null;
    playerRatingForm.reset();

    if (ratingSubmitButton) {
      ratingSubmitButton.textContent = "Save Rating";
    }

    sortRatings();
    renderPlayerRatings();
    renderAverageRating();
    renderBestRatedPlayer();
    renderPlayersOfTheMatch();
    renderMatchInsights();
    renderCoachSummary();
    renderMatchGrade();
  } catch (error) {
    console.error("Error saving player rating:", error);
    showToast("Could not save player rating: " + error.message, "error");
  } finally {
    setButtonLoading(ratingSubmitButton, false, "Saving...", "Save Rating");
  }
});

playerRatingsList?.addEventListener("click", async function (event) {
  const editBtn = event.target.closest(".edit-rating-btn");
  const deleteBtn = event.target.closest(".delete-rating-btn");

  if (editBtn) {
    const ratingId = editBtn.dataset.id;
    const rating = ratingsCache.find((item) => item.id === ratingId);

    if (!rating) return;

    editingRatingId = rating.id;

    if (ratingPlayer) ratingPlayer.value = rating.playerId || "";
    if (ratingScore) ratingScore.value = rating.rating || "";
    if (ratingComment) ratingComment.value = rating.comment || "";
    if (ratingSubmitButton) ratingSubmitButton.textContent = "Update Rating";

    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  if (deleteBtn) {
    const ratingId = deleteBtn.dataset.id;

    const confirmed = confirm("Are you sure you want to delete this player rating?");
    if (!confirmed) return;

    setButtonLoading(deleteBtn, true, "Deleting...", "Delete");

    try {
      await deleteDoc(doc(db, "playerRatings", ratingId));

      ratingsCache = ratingsCache.filter((rating) => rating.id !== ratingId);

      renderPlayerRatings();
      renderAverageRating();
      renderBestRatedPlayer();
      renderPlayersOfTheMatch();
      renderMatchInsights();
      renderCoachSummary();
      renderMatchGrade();

      showToast("Player rating deleted.", "success");
    } catch (error) {
      console.error("Error deleting player rating:", error);
      showToast("Could not delete rating: " + error.message, "error");
    } finally {
      setButtonLoading(deleteBtn, false, "Deleting...", "Delete");
    }
  }
});

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

  if (!matchId) {
    if (reportTitle) reportTitle.textContent = "Invalid Match";
    return;
  }

  showLoader("Loading post-match report...");

  if (reportTimeline) {
    reportTimeline.innerHTML = `<div class="list-item">Loading post-match report...</div>`;
  }

  try {
    const loaded = await loadMatch();

    if (!loaded || !currentMatch) return;

    await loadReportData();
    renderPage();
  } catch (error) {
    console.error("Post-match report error:", error);

    if (reportTitle) {
      reportTitle.textContent = "Could not load post-match report";
    }

    if (reportTimeline) {
      reportTimeline.innerHTML = `<div class="list-item">Error: ${error.message}</div>`;
    }

    showToast("Could not load post-match report: " + error.message, "error");
  } finally {
    hideLoader();
  }
});