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 {
  collection,
  getDocs,
  query,
  where
} from "https://www.gstatic.com/firebasejs/10.12.2/firebase-firestore.js";

const injuryRiskList = document.getElementById("injuryRiskList");
const injuryTeamFilter = document.getElementById("injuryTeamFilter");

const injuryTotalPlayers = document.getElementById("injuryTotalPlayers");
const injuryClearPlayers = document.getElementById("injuryClearPlayers");
const injuryMonitorPlayers = document.getElementById("injuryMonitorPlayers");
const injuryRiskPlayers = document.getElementById("injuryRiskPlayers");

const exportInjuryRiskBtn = document.getElementById("exportInjuryRiskBtn");
const printInjuryRiskBtn = document.getElementById("printInjuryRiskBtn");

let activeProfile = null;
let players = [];
let teams = [];
let injuries = [];

function canAccessTeam(teamId) {
  const role = activeProfile?.role;
  const assignedTeamIds = activeProfile?.assignedTeamIds || [];

  if (role === "director") return true;
  if (role === "coach" || role === "biokineticist") return assignedTeamIds.includes(teamId);

  return false;
}

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

  const snapshot = await getDocs(q);

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

async function loadInjuryRiskReport() {
  showLoader("Loading injury risk report...");

  if (injuryRiskList) {
    injuryRiskList.innerHTML = `<div class="app-card">Loading injury risk report...</div>`;
  }

  try {
    const [playersRecords, teamsRecords, injuryRecords] = await Promise.all([
      getRecords("players"),
      getRecords("teams"),
      getRecords("injuries")
    ]);

    teams = teamsRecords.filter((team) => canAccessTeam(team.id));
    players = playersRecords.filter((player) => canAccessTeam(player.teamId));

    const accessiblePlayerIds = new Set(players.map((player) => player.id));

    injuries = injuryRecords.filter((injury) => {
      return accessiblePlayerIds.has(injury.playerId);
    });

    populateTeamFilter();
    renderInjuryRiskReport();
  } catch (error) {
    console.error("Injury risk report error:", error);

    if (injuryRiskList) {
      injuryRiskList.innerHTML = `
        <div class="app-card">
          <strong>Could not load injury risk report.</strong>
          <p>${error.message}</p>
        </div>
      `;
    }

    showToast("Could not load injury risk report: " + error.message, "error");
  } finally {
    hideLoader();
  }
}

function populateTeamFilter() {
  injuryTeamFilter.innerHTML = `<option value="all">All Teams</option>`;

  teams.forEach((team) => {
    const option = document.createElement("option");
    option.value = team.id;
    option.textContent = `${team.name || "Unnamed Team"} • ${team.ageGroup || "No age group"}`;
    injuryTeamFilter.appendChild(option);
  });
}

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

function buildActiveInjuryMap() {
  const map = new Map();

  injuries.forEach((injury) => {
    if (!injury.playerId || !isActiveInjury(injury)) return;

    const existing = map.get(injury.playerId);

    if (!existing || getSeverityWeight(injury.severity) > getSeverityWeight(existing.severity)) {
      map.set(injury.playerId, injury);
    }
  });

  return map;
}

function getInjuryRows(filteredPlayers) {
  const activeInjuryMap = buildActiveInjuryMap();

  return filteredPlayers.map((player) => {
    const activeInjury = activeInjuryMap.get(player.id);
    const status = getInjuryRiskStatus(activeInjury);

    return {
      player,
      activeInjury,
      status
    };
  });
}

function renderInjuryRiskReport() {
  const selectedTeam = injuryTeamFilter.value || "all";

  const filteredPlayers =
    selectedTeam === "all"
      ? players
      : players.filter((player) => player.teamId === selectedTeam);

  injuryRiskList.innerHTML = "";

  if (!filteredPlayers.length) {
    injuryRiskList.innerHTML = `
      <div class="list-item">
        <strong>No players found.</strong>
        <p>No players are available for this team filter.</p>
      </div>
    `;

    updateStats(0, 0, 0, 0);
    return;
  }

  const rows = getInjuryRows(filteredPlayers).sort((a, b) => {
    return getRiskWeight(b.status.key) - getRiskWeight(a.status.key);
  });

  const clearCount = rows.filter((row) => row.status.key === "clear").length;
  const monitorCount = rows.filter((row) => row.status.key === "monitor").length;
  const riskCount = rows.filter((row) => row.status.key === "risk").length;

  rows.forEach((row) => {
    const item = document.createElement("div");
    item.className = "elite-readiness-row elite-card";

    item.innerHTML = `
      <div>
        <h3>${getPlayerName(row.player)}</h3>
        <p>${getTeamName(row.player.teamId)} • ${row.player.position || "No position"}</p>
      </div>

      <div class="report-metrics">
        <span class="report-pill ${row.status.className}">
          ${row.status.label}
        </span>

        <span>Injury: ${row.activeInjury ? "Active" : "Clear"}</span>
        <span>Type: ${row.activeInjury?.type || row.activeInjury?.injuryType || "-"}</span>
        <span>Severity: ${row.activeInjury?.severity || "-"}</span>
        <span>Return / Notes: ${row.activeInjury?.returnToPlay || row.activeInjury?.notes || "-"}</span>
      </div>
    `;

    injuryRiskList.appendChild(item);
  });

  updateStats(rows.length, clearCount, monitorCount, riskCount);
}

function getSeverityWeight(severity) {
  const value = String(severity || "").toLowerCase();

  if (value.includes("serious") || value.includes("high") || value.includes("severe") || value.includes("major")) {
    return 3;
  }

  if (value.includes("moderate") || value.includes("medium")) {
    return 2;
  }

  if (value.includes("minor") || value.includes("low")) {
    return 1;
  }

  return 1;
}

function getRiskWeight(key) {
  if (key === "risk") return 3;
  if (key === "monitor") return 2;
  return 1;
}

function getInjuryRiskStatus(injury) {
  if (!injury) {
    return {
      key: "clear",
      label: "Clear",
      className: "readiness-ready"
    };
  }

  const severityWeight = getSeverityWeight(injury.severity);

  if (severityWeight >= 3) {
    return {
      key: "risk",
      label: "High Risk",
      className: "readiness-danger"
    };
  }

  return {
    key: "monitor",
    label: "Monitor",
    className: "readiness-monitor"
  };
}

function updateStats(total, clear, monitor, risk) {
  injuryTotalPlayers.textContent = total;
  injuryClearPlayers.textContent = clear;
  injuryMonitorPlayers.textContent = monitor;
  injuryRiskPlayers.textContent = risk;
}

function getPlayerName(player) {
  const firstName = player.firstName || "";
  const lastName = player.lastName || "";

  return (
    player.name ||
    player.fullName ||
    player.displayName ||
    `${firstName} ${lastName}`.trim() ||
    "Unnamed Player"
  );
}

function getTeamName(teamId) {
  const team = teams.find((item) => item.id === teamId);
  return team ? team.name : "No Team";
}

function exportInjuryRiskCsv() {
  const selectedTeam = injuryTeamFilter.value || "all";

  const filteredPlayers =
    selectedTeam === "all"
      ? players
      : players.filter((player) => player.teamId === selectedTeam);

  const rows = getInjuryRows(filteredPlayers);

  const csvRows = [
    ["Player", "Team", "Injury Status", "Type", "Severity", "Return / Notes", "Risk Status"]
  ];

  rows.forEach((row) => {
    csvRows.push([
      getPlayerName(row.player),
      getTeamName(row.player.teamId),
      row.activeInjury ? "Active" : "Clear",
      row.activeInjury?.type || row.activeInjury?.injuryType || "-",
      row.activeInjury?.severity || "-",
      row.activeInjury?.returnToPlay || row.activeInjury?.notes || "-",
      row.status.label
    ]);
  });

  const csvContent = csvRows
    .map((row) =>
      row.map((value) => `"${String(value).replace(/"/g, '""')}"`).join(",")
    )
    .join("\n");

  const blob = new Blob([csvContent], {
    type: "text/csv;charset=utf-8;"
  });

  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");

  link.href = url;
  link.download = "trytrack-injury-risk-report.csv";
  link.click();

  URL.revokeObjectURL(url);
}

injuryTeamFilter?.addEventListener("change", renderInjuryRiskReport);

exportInjuryRiskBtn?.addEventListener("click", exportInjuryRiskCsv);

printInjuryRiskBtn?.addEventListener("click", () => {
  window.print();
});

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