// =========================================================
// FILE: bio-wellness.js | TYPE: Biokineticist Wellness Review
// =========================================================

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 playerFilter = document.getElementById("bioWellnessPlayerFilter");

const playersReviewed = document.getElementById("bioWellnessPlayersReviewed");
const riskCount = document.getElementById("bioWellnessRiskCount");
const averageWellness = document.getElementById("bioWellnessAverage");

const latestWellness = document.getElementById("bioLatestWellness");
const latestWellnessLabel = document.getElementById("bioLatestWellnessLabel");
const sevenDayAverage = document.getElementById("bioSevenDayAverage");
const thirtyDayAverage = document.getElementById("bioThirtyDayAverage");
const riskFlags = document.getElementById("bioRiskFlags");

const focusTitle = document.getElementById("bioWellnessFocusTitle");
const focusText = document.getElementById("bioWellnessFocusText");

const recordsList = document.getElementById("bioWellnessRecordsList");
const insightsList = document.getElementById("bioWellnessInsightsList");

let activeProfile = null;
let playersCache = [];
let wellnessCache = [];

let trendChart = null;
let breakdownChart = null;
let riskChart = null;

function setText(el, value) {
  if (el) el.textContent = value;
}

function animateRing(selector, value) {
  const ring = document.querySelector(selector);
  if (!ring) return;

  const safeValue = Math.max(0, Math.min(100, Number(value) || 0));
  ring.style.setProperty("--value", `${safeValue}%`);
}

function getPlayerName(player) {
  return (
    player.fullName ||
    player.name ||
    `${player.firstName || ""} ${player.lastName || ""}`.trim() ||
    "Unknown Player"
  );
}

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 === "biokineticist") {
    return (
      playerTeamIds.some((teamId) => assignedTeamIds.includes(teamId)) ||
      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);
  return new Date(0);
}

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 getWellnessPercent(record) {
  return Math.round((getWellnessScore(record) / 15) * 100);
}

function getRiskCount(record) {
  return (
    (Number(record.sleep || 0) <= 2 ? 1 : 0) +
    (Number(record.fatigue || 0) >= 4 ? 1 : 0) +
    (Number(record.soreness || 0) >= 4 ? 1 : 0)
  );
}

function getAveragePercent(records) {
  if (!records.length) return 0;

  const total = records.reduce((sum, record) => {
    return sum + getWellnessPercent(record);
  }, 0);

  return Math.round(total / records.length);
}

function getRecordsWithinDays(records, days) {
  const today = new Date();
  today.setHours(23, 59, 59, 999);

  const start = new Date(today);
  start.setDate(today.getDate() - days);
  start.setHours(0, 0, 0, 0);

  return records.filter((record) => {
    const date = getDateValue(record);
    return date >= start && date <= today;
  });
}

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

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 loadPageData() {
  const [players, wellness] = await Promise.all([
    getRecords("players"),
    getRecords("wellness")
  ]);

  playersCache = players
    .filter((player) => canAccessPlayer(player))
    .sort((a, b) => getPlayerName(a).localeCompare(getPlayerName(b)));

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

  wellnessCache = wellness
    .filter((record) => accessiblePlayerIds.has(record.playerId))
    .sort((a, b) => getDateValue(b) - getDateValue(a));
}

function renderPlayerFilter() {
  if (!playerFilter) return;

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

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

function renderOverallSummary() {
  const latestByPlayer = new Map();

  wellnessCache.forEach((record) => {
    if (!latestByPlayer.has(record.playerId)) {
      latestByPlayer.set(record.playerId, record);
    }
  });

  const latestRecords = Array.from(latestByPlayer.values());
  const riskRecords = latestRecords.filter((record) => getRiskCount(record) > 0);

  setText(playersReviewed, latestRecords.length);
  setText(riskCount, riskRecords.length);
  setText(averageWellness, `${getAveragePercent(latestRecords)}%`);
}

function renderEmptyState() {
  setText(latestWellness, "0%");
  setText(latestWellnessLabel, "No Data");
  setText(sevenDayAverage, "0%");
  setText(thirtyDayAverage, "0%");
  setText(riskFlags, "0");

  animateRing(".premium-wellness-ring", 0);
  animateRing(".premium-monitor-ring", 0);
  animateRing(".premium-ready-ring", 0);
  animateRing(".premium-danger-ring", 0);

  setText(focusTitle, "Select Player");
  setText(focusText, "Select a player to review wellness trends and risk signals.");

  if (recordsList) {
    recordsList.innerHTML = `<div class="list-item">Select a player to view wellness records.</div>`;
  }

  if (insightsList) {
    insightsList.innerHTML = `
      <div class="insight-item">
        <span class="insight-dot insight-warning"></span>
        <div>
          <strong>No player selected</strong>
          <p>Select a player to generate wellness review insights.</p>
        </div>
      </div>
    `;
  }

  renderCharts([]);
}

function renderSelectedPlayer(playerId) {
  if (!playerId) {
    renderEmptyState();
    return;
  }

  const player = playersCache.find((item) => item.id === playerId);
  const records = wellnessCache
    .filter((record) => record.playerId === playerId)
    .sort((a, b) => getDateValue(b) - getDateValue(a));

  if (!records.length) {
    renderEmptyState();
    setText(focusTitle, getPlayerName(player));
    setText(focusText, "No wellness records are available for this player yet.");
    return;
  }

  const latest = records[0];
  const latestPercent = getWellnessPercent(latest);
  const sevenAvg = getAveragePercent(getRecordsWithinDays(records, 7));
  const thirtyAvg = getAveragePercent(getRecordsWithinDays(records, 30));
  const latestRiskCount = getRiskCount(latest);

  setText(latestWellness, `${latestPercent}%`);
  setText(latestWellnessLabel, latestRiskCount ? "Needs Review" : "Stable");
  setText(sevenDayAverage, `${sevenAvg}%`);
  setText(thirtyDayAverage, `${thirtyAvg}%`);
  setText(riskFlags, latestRiskCount);

  animateRing(".premium-wellness-ring", latestPercent);
  animateRing(".premium-monitor-ring", sevenAvg);
  animateRing(".premium-ready-ring", thirtyAvg);
  animateRing(".premium-danger-ring", Math.round((latestRiskCount / 3) * 100));

  setText(focusTitle, getPlayerName(player));

  setText(
    focusText,
    latestRiskCount
      ? "Latest wellness indicators require review before full training or match load."
      : "Latest wellness indicators are currently stable."
  );

  renderRecords(records);
  renderInsights(records, player);
  renderCharts(records);
}

function renderRecords(records) {
  if (!recordsList) return;

  recordsList.innerHTML = "";

  records.slice(0, 12).forEach((record) => {
    const score = getWellnessScore(record);
    const percent = getWellnessPercent(record);
    const risks = getRiskCount(record);

    const item = document.createElement("article");
    item.className = "wellness-card elite-wellness-risk-card";

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

        <span class="wellness-score">
          ${score}/15 • ${percent}%
        </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>
          <span>Risk Flags</span>
          <strong>${risks}/3</strong>
        </div>
      </div>
    `;

    recordsList.appendChild(item);
  });
}

function renderInsights(records, player) {
  if (!insightsList) return;

  insightsList.innerHTML = "";

  const latest = records[0];
  const latestRiskCount = getRiskCount(latest);
  const sevenDayRecords = getRecordsWithinDays(records, 7);
  const sevenAvg = getAveragePercent(sevenDayRecords);

  const insights = [];

  if (latestRiskCount >= 2) {
    insights.push({
      type: "danger",
      title: "High Wellness Risk",
      text: "Two or more wellness indicators are currently outside the preferred range."
    });
  } else if (latestRiskCount === 1) {
    insights.push({
      type: "warning",
      title: "Monitor Recovery",
      text: "One wellness indicator requires review before increasing load."
    });
  }

  if (sevenAvg > 0 && sevenAvg < 70) {
    insights.push({
      type: "warning",
      title: "Low 7-Day Average",
      text: "The recent wellness average suggests recovery should be monitored."
    });
  }

  if (Number(latest.fatigue || 0) >= 4) {
    insights.push({
      type: "warning",
      title: "Fatigue Flag",
      text: "Fatigue is elevated on the latest check-in."
    });
  }

  if (Number(latest.soreness || 0) >= 4) {
    insights.push({
      type: "warning",
      title: "Soreness Flag",
      text: "Soreness is elevated on the latest check-in."
    });
  }

  if (!insights.length) {
    insights.push({
      type: "good",
      title: "Wellness Stable",
      text: `${getPlayerName(player)} has no major wellness alerts on the latest check-in.`
    });
  }

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

    item.innerHTML = `
      <span class="insight-dot insight-${insight.type}"></span>
      <div>
        <strong>${insight.title}</strong>
        <p>${insight.text}</p>
      </div>
    `;

    insightsList.appendChild(item);
  });
}

function renderCharts(records) {
  if (typeof Chart === "undefined") return;

  const trendCanvas = document.getElementById("bioWellnessTrendChart");
  const breakdownCanvas = document.getElementById("bioWellnessBreakdownChart");
  const riskCanvas = document.getElementById("bioWellnessRiskChart");

  destroyChart(trendChart);
  destroyChart(breakdownChart);
  destroyChart(riskChart);

  trendChart = null;
  breakdownChart = null;
  riskChart = null;

  const sorted = [...records].sort((a, b) => getDateValue(a) - getDateValue(b));
  const lastRecords = sorted.slice(-10);

  if (trendCanvas) {
    trendChart = new Chart(trendCanvas, {
      type: "line",
      data: {
        labels: lastRecords.map((record) => record.createdDate || "Check-in"),
        datasets: [{
          label: "Wellness %",
          data: lastRecords.map((record) => getWellnessPercent(record)),
          tension: 0.35,
          fill: false
        }]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        scales: {
          y: {
            min: 0,
            max: 100
          }
        }
      }
    });
  }

  if (breakdownCanvas) {
    breakdownChart = new Chart(breakdownCanvas, {
      type: "bar",
      data: {
        labels: lastRecords.map((record) => record.createdDate || "Check-in"),
        datasets: [
          {
            label: "Sleep",
            data: lastRecords.map((record) => Number(record.sleep || 0))
          },
          {
            label: "Fatigue",
            data: lastRecords.map((record) => Number(record.fatigue || 0))
          },
          {
            label: "Soreness",
            data: lastRecords.map((record) => Number(record.soreness || 0))
          }
        ]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        scales: {
          y: {
            min: 0,
            max: 5
          }
        }
      }
    });
  }

  if (riskCanvas) {
    const sleepRisk = records.filter((r) => Number(r.sleep || 0) <= 2).length;
    const fatigueRisk = records.filter((r) => Number(r.fatigue || 0) >= 4).length;
    const sorenessRisk = records.filter((r) => Number(r.soreness || 0) >= 4).length;

    riskChart = new Chart(riskCanvas, {
      type: "doughnut",
      data: {
        labels: ["Sleep Risk", "Fatigue Risk", "Soreness Risk"],
        datasets: [{
          data: [sleepRisk, fatigueRisk, sorenessRisk]
        }]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false
      }
    });
  }
}

playerFilter?.addEventListener("change", () => {
  renderSelectedPlayer(playerFilter.value);
});

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

  if (profile.role !== "biokineticist" && profile.role !== "director") {
    window.location.href = "dashboard.html";
    return;
  }

  showLoader("Loading bio wellness review...");

  try {
    await loadPageData();
    renderPlayerFilter();
    renderOverallSummary();
    renderEmptyState();
  } catch (error) {
    console.error("Bio wellness error:", error);
    showToast("Could not load bio wellness review: " + error.message, "error");

    if (recordsList) {
      recordsList.innerHTML = `
        <div class="list-item">
          <strong>Error loading wellness review.</strong>
          <p>${error.message}</p>
        </div>
      `;
    }
  } finally {
    hideLoader();
  }
});