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

const trainingForm = document.getElementById("trainingForm");
const trainingFormTitle = document.getElementById("trainingFormTitle");
const trainingTeam = document.getElementById("trainingTeam");
const trainingDate = document.getElementById("trainingDate");
const trainingTime = document.getElementById("trainingTime");
const trainingType = document.getElementById("trainingType");
const trainingDuration = document.getElementById("trainingDuration");
const trainingIntensity = document.getElementById("trainingIntensity");
const trainingLoad = document.getElementById("trainingLoad");
const trainingLocation = document.getElementById("trainingLocation");
const trainingFocus = document.getElementById("trainingFocus");
const trainingNotes = document.getElementById("trainingNotes");
const trainingList = document.getElementById("trainingList");
const trainingTeamFilter = document.getElementById("trainingTeamFilter");
const cancelTrainingEditBtn = document.getElementById("cancelTrainingEditBtn");

const trainingTotalSessions = document.getElementById("trainingTotalSessions");
const trainingAverageLoad = document.getElementById("trainingAverageLoad");
const trainingHighLoadSessions = document.getElementById("trainingHighLoadSessions");
const trainingOverloadSessions = document.getElementById("trainingOverloadSessions");

let activeProfile = null;
let teamsCache = [];
let sessionsCache = [];
let editingSessionId = null;

const submitButton = trainingForm?.querySelector("button[type='submit']");

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

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

function formatSessionType(type) {
  return String(type || "training")
    .replace("_", " ")
    .replace(/\b\w/g, (char) => char.toUpperCase());
}

function calculateTrainingLoad() {
  const duration = Number(trainingDuration.value || 0);
  const intensity = Number(trainingIntensity.value || 0);
  const load = duration * intensity;

  trainingLoad.value = load || "";
}

function getLoadStatus(load) {
  if (load >= 500) {
    return {
      label: "Overload Risk",
      className: "readiness-danger"
    };
  }

  if (load >= 350) {
    return {
      label: "High Load",
      className: "readiness-monitor"
    };
  }

  if (load >= 180) {
    return {
      label: "Optimal",
      className: "readiness-ready"
    };
  }

  return {
    label: "Low Load",
    className: "readiness-monitor"
  };
}

function resetFormMode() {
  editingSessionId = null;
  trainingForm.reset();

  trainingFormTitle.textContent = "Add Training Session";
  submitButton.textContent = "Save Training Session";
  cancelTrainingEditBtn.classList.add("hidden");
}

function resetSubmitButton() {
  if (!submitButton) return;

  submitButton.disabled = false;
  submitButton.textContent = editingSessionId
    ? "Update Training Session"
    : "Save Training Session";
}

function sortSessionsCache() {
  sessionsCache.sort((a, b) => {
    return new Date(b.date || "1900-01-01") - new Date(a.date || "1900-01-01");
  });
}

async function loadPageData() {
  const teamsQuery = query(
    collection(db, "teams"),
    where("organisationId", "==", activeProfile.organisationId)
  );

  const sessionsQuery = query(
    collection(db, "trainingSessions"),
    where("organisationId", "==", activeProfile.organisationId)
  );

  const [teamsSnapshot, sessionsSnapshot] = await Promise.all([
    getDocs(teamsQuery),
    getDocs(sessionsQuery)
  ]);

  teamsCache = teamsSnapshot.docs
    .map((docSnap) => ({
      id: docSnap.id,
      ...docSnap.data()
    }))
    .filter((team) => canAccessTeam(team.id));

  sessionsCache = sessionsSnapshot.docs
    .map((docSnap) => ({
      id: docSnap.id,
      ...docSnap.data()
    }))
    .filter((session) => canAccessTeam(session.teamId));

  sortSessionsCache();
}

async function createTrainingLoadNotification(sessionId, sessionData) {
  const load = Number(sessionData.sessionLoad || 0);
  const notificationRef = doc(db, "notifications", `training-load-${sessionId}`);

  if (load < 350) {
    await deleteDoc(notificationRef).catch(() => {});
    return;
  }

  const isOverload = load >= 500;

  await setDoc(notificationRef, {
    sourceId: sessionId,
    sourceCollection: "trainingSessions",
    type: "load",
    severity: isOverload ? "high" : "monitor",
    title: `${sessionData.teamName || "Team"} ${isOverload ? "overload risk" : "high training load"}`,
    message: `Training session load is ${load}. Duration: ${sessionData.durationMinutes || 0} min, intensity: ${sessionData.intensity || "-"}.`,
    link: `training-attendance.html?id=${sessionId}`,
    teamId: sessionData.teamId || "",
    teamName: sessionData.teamName || "",
    playerId: "",
    playerName: "",
    organisationId: activeProfile.organisationId,
    readBy: {},
    createdAt: serverTimestamp(),
    updatedAt: serverTimestamp()
  });
}

async function createTrainingSessionNotification(
  sessionId,
  sessionData
) {
  const notificationRef = doc(
    db,
    "notifications",
    `training-session-${sessionId}`
  );

  await setDoc(notificationRef, {
    sourceId: sessionId,
    sourceCollection: "trainingSessions",

    type: "training",
    severity: "info",

    title: editingSessionId ? "Training Session Updated" : "Training Session Scheduled",

    message: `${sessionData.teamName || "Team"} training ${editingSessionId ? "updated" : "scheduled"} for ${sessionData.date || "No date"} at ${sessionData.time || "No time"}${sessionData.location ? " at " + sessionData.location : ""}.`,

    link: `training-attendance.html?id=${sessionId}`,

    teamId: sessionData.teamId || "",
    teamName: sessionData.teamName || "",

    organisationId: activeProfile.organisationId,

    readBy: {},

    createdAt: serverTimestamp(),
    updatedAt: serverTimestamp()
  });
}

async function createTrainingReminderNotifications(sessionId, sessionData) {
  if (!sessionData.date) return;

  const sessionDateValue = new Date(sessionData.date);
  const today = new Date();

  today.setHours(0, 0, 0, 0);
  sessionDateValue.setHours(0, 0, 0, 0);

  const daysUntil = Math.ceil(
    (sessionDateValue - today) / (1000 * 60 * 60 * 24)
  );

  const tomorrowRef = doc(db, "notifications", `training-reminder-tomorrow-${sessionId}`);
  const todayRef = doc(db, "notifications", `training-reminder-today-${sessionId}`);

  if (daysUntil === 1) {
    await setDoc(tomorrowRef, {
      sourceId: sessionId,
      sourceCollection: "trainingSessions",
      type: "training",
      severity: "monitor",
      title: "Training Tomorrow",
      message: `${sessionData.teamName || "Team"} training is scheduled tomorrow at ${sessionData.time || "No time"}${sessionData.location ? " at " + sessionData.location : ""}.`,
      link: `training-attendance.html?id=${sessionId}`,
      teamId: sessionData.teamId || "",
      teamName: sessionData.teamName || "",
      playerId: "",
      playerName: "",
      organisationId: activeProfile.organisationId,
      readBy: {},
      createdAt: serverTimestamp(),
      updatedAt: serverTimestamp()
    });
  } else {
    await deleteDoc(tomorrowRef).catch(() => {});
  }

  if (daysUntil === 0) {
    await setDoc(todayRef, {
      sourceId: sessionId,
      sourceCollection: "trainingSessions",
      type: "training",
      severity: "monitor",
      title: "Training Today",
      message: `${sessionData.teamName || "Team"} training is today at ${sessionData.time || "No time"}${sessionData.location ? " at " + sessionData.location : ""}.`,
      link: `training-attendance.html?id=${sessionId}`,
      teamId: sessionData.teamId || "",
      teamName: sessionData.teamName || "",
      playerId: "",
      playerName: "",
      organisationId: activeProfile.organisationId,
      readBy: {},
      createdAt: serverTimestamp(),
      updatedAt: serverTimestamp()
    });
  } else {
    await deleteDoc(todayRef).catch(() => {});
  }
}

function renderTeamDropdowns() {
  trainingTeam.innerHTML = `<option value="">Select team</option>`;
  trainingTeamFilter.innerHTML = `<option value="all">All Teams</option>`;

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

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

function getFilteredSessions() {
  const selectedTeam = trainingTeamFilter.value || "all";

  return sessionsCache.filter((session) => {
    return selectedTeam === "all" || session.teamId === selectedTeam;
  });
}

function renderTrainingStats() {
  const filteredSessions = getFilteredSessions();
  const totalSessions = filteredSessions.length;

  const totalLoad = filteredSessions.reduce((sum, session) => {
    return sum + Number(session.sessionLoad || 0);
  }, 0);

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

  const highLoadSessions = filteredSessions.filter((session) => {
    return Number(session.sessionLoad || 0) >= 350;
  }).length;

  const overloadSessions = filteredSessions.filter((session) => {
    return Number(session.sessionLoad || 0) >= 500;
  }).length;

  trainingTotalSessions.textContent = totalSessions;
  trainingAverageLoad.textContent = averageLoad;
  trainingHighLoadSessions.textContent = highLoadSessions;
  trainingOverloadSessions.textContent = overloadSessions;
}

function renderTrainingSessions() {
  const filteredSessions = getFilteredSessions();

  renderTrainingStats();

  trainingList.innerHTML = "";

  if (!filteredSessions.length) {
    trainingList.innerHTML = `
      <div class="app-card">
        No training sessions found.
      </div>
    `;
    return;
  }

  filteredSessions.forEach((session) => {
    const load = Number(session.sessionLoad || 0);
    const loadStatus = getLoadStatus(load);

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

    item.innerHTML = `
      <div class="elite-match-header">
        <div>
          <span class="section-eyebrow">${formatSessionType(session.type)}</span>

          <h3>
            ${getTeamName(session.teamId)}
            <span>${session.date || "No date"}</span>
          </h3>

          <p>
            ${session.focus || "No focus added"}
          </p>
        </div>

        <div class="elite-match-score">
          <strong>${load}</strong>
        </div>
      </div>

      <div class="elite-match-meta-grid">
        <div>
          <span>Time</span>
          <strong>${session.time || "No time"}</strong>
        </div>

        <div>
          <span>Duration</span>
          <strong>${session.durationMinutes || 0} min</strong>
        </div>

        <div>
          <span>Intensity</span>
          <strong>${session.intensity || "-"}</strong>
        </div>
      </div>

      <div class="elite-match-footer">
        <span class="report-pill ${loadStatus.className}">
          ${loadStatus.label}
        </span>

        <div class="record-actions">
          <a href="training-attendance.html?id=${session.id}" class="btn-primary">
            Attendance
          </a>

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

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

      <div class="team-sheet-notes" style="margin-top: 18px;">
        <strong>Location:</strong> ${session.location || "No location"}
        <br />
        <strong>Notes:</strong> ${session.notes || "No notes added"}
      </div>
    `;

    trainingList.appendChild(item);
  });
}

trainingDuration.addEventListener("input", calculateTrainingLoad);
trainingIntensity.addEventListener("change", calculateTrainingLoad);

trainingForm.addEventListener("submit", async function (event) {
  event.preventDefault();
  
  submitButton.disabled = true;
  submitButton.textContent = editingSessionId ? "Updating..." : "Saving...";

  const teamId = trainingTeam.value;

  if (!teamId) {
    showToast("Please select a team.", "warning");
    resetSubmitButton();
    return;
  }

  if (!canAccessTeam(teamId)) {
    showToast("You do not have access to this team.", "error");
    resetSubmitButton();
    return;
  }

  calculateTrainingLoad();

  const sessionData = {
    teamId,
    teamName: getTeamName(teamId),
    date: trainingDate.value,
    time: trainingTime.value,
    type: trainingType.value,
    durationMinutes: Number(trainingDuration.value || 0),
    intensity: Number(trainingIntensity.value || 0),
    sessionLoad: Number(trainingLoad.value || 0),
    location: trainingLocation.value.trim(),
    focus: trainingFocus.value.trim(),
    notes: trainingNotes.value.trim(),
    organisationId: activeProfile.organisationId,
    updatedAt: serverTimestamp()
  };

  try {
    if (editingSessionId) {
      await updateDoc(doc(db, "trainingSessions", editingSessionId), sessionData);
      await createTrainingLoadNotification(editingSessionId, sessionData);
      await createTrainingSessionNotification(editingSessionId, sessionData);
      await createTrainingReminderNotifications(editingSessionId, sessionData);

      sessionsCache = sessionsCache.map((session) =>
        session.id === editingSessionId
          ? {
              ...session,
              ...sessionData,
              updatedAt: new Date()
            }
          : session
      );

      showToast("Training session updated successfully.", "success");
    } else {
      const sessionRef = await addDoc(collection(db, "trainingSessions"), {
        ...sessionData,
        createdBy: activeProfile.uid,
        createdAt: serverTimestamp()
      });

      await createTrainingLoadNotification(sessionRef.id, sessionData);
      await createTrainingSessionNotification(sessionRef.id, sessionData);
      await createTrainingReminderNotifications(sessionRef.id, sessionData);

      sessionsCache.unshift({
        id: sessionRef.id,
        ...sessionData,
        createdBy: activeProfile.uid,
        createdAt: new Date()
      });

      showToast("Training session saved successfully.", "success");
    }

    sortSessionsCache();
    resetFormMode();
    renderTrainingSessions();
  } catch (error) {
    console.error("Training session save error:", error);
    showToast("Could not save training session: " + error.message, "error");
  } finally {
    resetSubmitButton();
  }
});

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

  if (editBtn) {
    const sessionId = editBtn.dataset.id;
    const session = sessionsCache.find((item) => item.id === sessionId);

    if (!session) return;

    editingSessionId = session.id;

    trainingTeam.value = session.teamId || "";
    trainingDate.value = session.date || "";
    trainingTime.value = session.time || "";
    trainingType.value = session.type || "skills";
    trainingDuration.value = session.durationMinutes || "";
    trainingIntensity.value = session.intensity || "";
    trainingLoad.value = session.sessionLoad || "";
    trainingLocation.value = session.location || "";
    trainingFocus.value = session.focus || "";
    trainingNotes.value = session.notes || "";

    trainingFormTitle.textContent = "Edit Training Session";
    submitButton.textContent = "Update Training Session";
    cancelTrainingEditBtn.classList.remove("hidden");

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

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

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

    try {
      await deleteDoc(doc(db, "trainingSessions", sessionId));
      await deleteDoc(doc(db, "notifications", `training-session-${sessionId}`)).catch(() => {});
      await deleteDoc(doc(db, "notifications", `training-load-${sessionId}`)).catch(() => {});
      await deleteDoc(doc(db, "notifications", `training-reminder-tomorrow-${sessionId}`)).catch(() => {});
      await deleteDoc(doc(db, "notifications", `training-reminder-today-${sessionId}`)).catch(() => {});

      sessionsCache = sessionsCache.filter((session) => session.id !== sessionId);

      renderTrainingSessions();
      showToast("Training session deleted.", "success");
    } catch (error) {
      console.error("Training session delete error:", error);
      showToast("Could not delete training session: " + error.message, "error");
    }
  }
});

trainingTeamFilter.addEventListener("change", renderTrainingSessions);
cancelTrainingEditBtn.addEventListener("click", resetFormMode);

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

  showLoader("Loading training sessions...");

  trainingList.innerHTML = `
    <div class="app-card">
      Loading training sessions...
    </div>
  `;

  try {
    await loadPageData();
    renderTeamDropdowns();
    renderTrainingSessions();
  } catch (error) {
    console.error("Training session save error:", error);
    showToast("Could not load training sessions: " + error.message, "error");
  } finally {
    hideLoader();
    
    submitButton.disabled = false;
    submitButton.textContent = editingSessionId
      ? "Update Training Session"
      : "Save Training Session";
  }
});