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 wellnessReportList = document.getElementById("wellnessReportList");
const wellnessTeamFilter = document.getElementById("wellnessTeamFilter");

const wellnessTotalPlayers = document.getElementById("wellnessTotalPlayers");
const wellnessReadyPlayers = document.getElementById("wellnessReadyPlayers");
const wellnessMonitorPlayers = document.getElementById("wellnessMonitorPlayers");
const wellnessRiskPlayers = document.getElementById("wellnessRiskPlayers");

const exportCsvBtn = document.getElementById("exportCsvBtn");
const printReportBtn = document.getElementById("printReportBtn");

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

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()
  }));
}

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

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

  wellnessEntries.forEach((entry) => {
    if (!entry.playerId) return;

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

    if (!existing || getDateValue(entry) > getDateValue(existing)) {
      map.set(entry.playerId, entry);
    }
  });

  return map;
}

async function loadWellnessReport() {
  showLoader("Loading wellness report...");

  wellnessReportList.innerHTML = `
    <div class="app-card">Loading wellness report...</div>
  `;

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

    teams = teamsRecords.filter((team) => canAccessTeam(team.id));

    players = playersRecords.filter((player) => {
      return canAccessTeam(player.teamId);
    });

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

    wellnessEntries = wellnessRecords.filter((entry) => {
      return accessiblePlayerIds.has(entry.playerId);
    });

    populateTeamFilter();
    renderWellnessReport();
  } catch (error) {
    console.error("Wellness report error:", error);

    wellnessReportList.innerHTML = `
      <div class="app-card">
        Could not load wellness report: ${error.message}
      </div>
    `;

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

function populateTeamFilter() {
  wellnessTeamFilter.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"}`;

    wellnessTeamFilter.appendChild(option);
  });
}

function renderWellnessReport() {
  const selectedTeam = wellnessTeamFilter.value || "all";

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

  wellnessReportList.innerHTML = "";

  let readyCount = 0;
  let monitorCount = 0;
  let riskCount = 0;

  if (!filteredPlayers.length) {
    wellnessReportList.innerHTML = `
      <div class="app-card">
        No players found for this team.
      </div>
    `;

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

  const latestWellnessByPlayer = getLatestWellnessByPlayer();

  const rows = filteredPlayers.map((player) => {
    const latestWellness = latestWellnessByPlayer.get(player.id);
    const score = calculateWellnessScore(latestWellness);
    const status = getWellnessStatus(score);

    return {
      player,
      latestWellness,
      score,
      status
    };
  });

  rows.sort((a, b) => {
    return getStatusWeight(b.status.key) - getStatusWeight(a.status.key);
  });

  rows.forEach((row) => {
    const { player, latestWellness, score, status } = row;

    if (status.key === "ready") readyCount++;
    if (status.key === "monitor") monitorCount++;
    if (status.key === "risk") riskCount++;

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

    item.innerHTML = `
      <div>
        <h3>${getPlayerName(player)}</h3>

        <p>
          ${getTeamName(player.teamId)}
          <span class="record-separator">&bull;</span>
          ${player.position || "No position"}
          <span class="record-separator">&bull;</span>
          ${latestWellness?.createdDate || "No wellness date"}
        </p>
      </div>

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

        <span>Score: ${score}%</span>
        <span>Sleep: ${latestWellness?.sleep ?? "-"}</span>
        <span>Fatigue: ${latestWellness?.fatigue ?? "-"}</span>
        <span>Mood: ${latestWellness?.mood ?? "-"}</span>
        <span>Stress: ${latestWellness?.stress ?? "-"}</span>
        <span>Soreness: ${latestWellness?.soreness ?? "-"}</span>
      </div>
    `;

    wellnessReportList.appendChild(item);
  });

  updateStats(filteredPlayers.length, readyCount, monitorCount, riskCount);
}

function updateStats(total, ready, monitor, risk) {
  wellnessTotalPlayers.textContent = total;
  wellnessReadyPlayers.textContent = ready;
  wellnessMonitorPlayers.textContent = monitor;
  wellnessRiskPlayers.textContent = risk;
}

function calculateWellnessScore(entry) {
  if (!entry) return 0;

  const sleep = Number(entry.sleep || 0);
  const fatigue = Math.max(0, 6 - Number(entry.fatigue || 0));
  const soreness = Math.max(0, 6 - Number(entry.soreness || 0));

  const total = sleep + fatigue + soreness;

  return Math.round((total / 15) * 100);
}

function getWellnessStatus(score) {
  if (score >= 75) {
    return {
      key: "ready",
      label: "Ready",
      className: "readiness-ready"
    };
  }

  if (score >= 50) {
    return {
      key: "monitor",
      label: "Monitor",
      className: "readiness-monitor"
    };
  }

  return {
    key: "risk",
    label: "At Risk",
    className: "readiness-danger"
  };
}

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

function getPlayerName(player) {
  if (player.name) return player.name;
  if (player.fullName) return player.fullName;
  if (player.displayName) return player.displayName;

  const firstName = player.firstName || "";
  const lastName = player.lastName || "";

  const combinedName = `${firstName} ${lastName}`.trim();

  return combinedName || "Unnamed Player";
}

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

function exportWellnessCsv() {
  const selectedTeam = wellnessTeamFilter.value || "all";

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

  const latestWellnessByPlayer = getLatestWellnessByPlayer();

  const rows = [
    [
      "Player",
      "Team",
      "Wellness Score",
      "Status",
      "Sleep",
      "Fatigue",
      "Mood",
      "Stress",
      "Soreness"
    ]
  ];

  filteredPlayers.forEach((player) => {
    const latestWellness = latestWellnessByPlayer.get(player.id);

    const score = calculateWellnessScore(latestWellness);
    const status = getWellnessStatus(score);

    rows.push([
      getPlayerName(player),
      getTeamName(player.teamId),
      `${score}%`,
      status.label,
      latestWellness?.sleep ?? "-",
      latestWellness?.fatigue ?? "-",
      latestWellness?.mood ?? "-",
      latestWellness?.stress ?? "-",
      latestWellness?.soreness ?? "-"
    ]);
  });

  const csvContent = rows
    .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-wellness-report.csv";
  link.click();

  URL.revokeObjectURL(url);
}

wellnessTeamFilter?.addEventListener("change", renderWellnessReport);
exportCsvBtn?.addEventListener("click", exportWellnessCsv);
printReportBtn?.addEventListener("click", () => {
  window.print();
});

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