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

const userList = document.getElementById("userList");
const inviteUserForm = document.getElementById("inviteUserForm");
const inviteFullName = document.getElementById("inviteFullName");
const inviteEmail = document.getElementById("inviteEmail");
const inviteRole = document.getElementById("inviteRole");
const pendingInvitesList = document.getElementById("pendingInvitesList");
const acceptedInvitesList = document.getElementById("acceptedInvitesList");

const inviteSubmitButton = inviteUserForm?.querySelector("button[type='submit']");

function setInviteLoading(isLoading) {
  if (!inviteSubmitButton) return;

  inviteSubmitButton.disabled = isLoading;
  inviteSubmitButton.textContent = isLoading ? "Creating Invite..." : "Create Invite";
}

let activeProfile = null;
let usersCache = [];
let teamsCache = [];
let playersCache = [];
let invitesCache = [];
let acceptedInvitesCache = [];

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

function getPlayerTeamName(player) {
  if (!player?.teamId) return "No team";

  const team = teamsCache.find((item) => item.id === player.teamId);

  if (!team) return "Unknown team";

  return team.name || team.ageGroup || "Unnamed Team";
}

function getUserName(user) {
  return user.fullName || user.email || "Unnamed User";
}

function getUserDocId(user) {
  return user.id || user.uid;
}

function formatRole(role) {
  if (role === "biokineticist") return "Biokineticist";
  return String(role || "user").charAt(0).toUpperCase() + String(role || "user").slice(1);
}

async function getOrganisationRecords(collectionName) {
  if (!activeProfile?.organisationId) {
    throw new Error("No organisation linked to this user.");
  }
  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() {
  userList.innerHTML = `<div class="app-card">Loading users...</div>`;

  if (pendingInvitesList) {
    pendingInvitesList.innerHTML = `<div class="app-card">Loading pending invites...</div>`;
  }

  if (acceptedInvitesList) {
    acceptedInvitesList.innerHTML = `<div class="app-card">Loading accepted invites...</div>`;
  }

  const [teams, players, users, invites] = await Promise.all([
    getOrganisationRecords("teams"),
    getOrganisationRecords("players"),
    getOrganisationRecords("users"),
    getOrganisationRecords("userInvites")
  ]);

  teamsCache = teams.sort((a, b) =>
    String(a.name || "").localeCompare(String(b.name || ""))
  );

  playersCache = players.sort((a, b) =>
    getPlayerName(a).toLowerCase().localeCompare(getPlayerName(b).toLowerCase())
  );

  usersCache = users.sort((a, b) =>
    getUserName(a).toLowerCase().localeCompare(
      getUserName(b).toLowerCase()
    )
  );

  invitesCache = invites
    .filter((invite) => String(invite.status || "").toLowerCase() === "pending")
    .sort((a, b) => String(a.email || "").localeCompare(String(b.email || "")));

  acceptedInvitesCache = invites
    .filter((invite) => String(invite.status || "").toLowerCase() === "accepted")
    .sort((a, b) => {
      const dateA = a.acceptedAt?.toDate ? a.acceptedAt.toDate() : new Date(0);
      const dateB = b.acceptedAt?.toDate ? b.acceptedAt.toDate() : new Date(0);
      return dateB - dateA;
    });

  renderUsers();
  renderPendingInvites();
  renderAcceptedInvites();
}

function renderAssignedTeamSummary(user) {
  const assignedTeamIds = user.assignedTeamIds || [];

  if (!assignedTeamIds.length) return "No teams assigned";

  return assignedTeamIds
    .map((teamId) => {
      const team = teamsCache.find((team) => team.id === teamId);
      return team ? team.name || "Unnamed Team" : "Unknown Team";
    })
    .join(", ");
}

function renderTeamOptions(user) {
  return teamsCache.map((team) => {
    const assigned =
      (team.assignedCoachIds || []).includes(user.uid) ||
      (user.assignedTeamIds || []).includes(team.id);

    return `
      <label class="checkbox-row">
        <input
          type="checkbox"
          class="team-assignment-checkbox"
          data-user="${user.uid}"
          data-team="${team.id}"
          ${assigned ? "checked" : ""}
        />

        <span>
          <strong>${team.name || "Unnamed Team"}</strong>
          <small>${team.ageGroup || "No age group"}</small>
        </span>
      </label>
    `;
  }).join("");
}

function normalizeName(value) {
  return String(value || "")
    .trim()
    .toLowerCase()
    .replace(/\s+/g, " ");
}

function renderPlayerLinkCards(user) {
  const userName = normalizeName(user.fullName);
  const linkedPlayerId = user.playerId || "";

  const matchingPlayers = playersCache.filter((player) => {
    const playerName = normalizeName(getPlayerName(player));

    return (
      player.id === linkedPlayerId ||
      playerName === userName
    );
  });

  if (!matchingPlayers.length) {
    return `
      <div class="app-card">
        No matching player profile found for ${user.fullName || user.email}.
      </div>
    `;
  }

  return matchingPlayers.map((player) => {
    const isLinked = user.playerId === player.id;

    const teamNames =
      player.teamNames?.length
        ? player.teamNames.join(", ")
        : getPlayerTeamName(player);

    return `
      <div class="checkbox-row player-link-row">
        <span>
          <strong>${getPlayerName(player)}</strong>
          <small>${teamNames} (${player.ageGroup || "No group"})</small>
        </span>

        <button
          class="${isLinked ? "btn-danger" : "btn-secondary"} player-link-btn"
          data-user="${user.uid}"
          data-player="${player.id}"
          data-linked="${isLinked ? "yes" : "no"}"
          type="button"
        >
          ${isLinked ? "Unlink" : "Link Player"}
        </button>
      </div>
    `;
  }).join("");
}

function getInviteExpiryDate() {
  const expiryDate = new Date();
  expiryDate.setDate(expiryDate.getDate() + 7);
  return expiryDate;
}

function formatInviteExpiry(invite) {
  if (!invite.expiresAt) return "No expiry date";

  const expiryDate = invite.expiresAt.toDate
    ? invite.expiresAt.toDate()
    : new Date(invite.expiresAt);

  return expiryDate.toLocaleDateString("en-ZA", {
    day: "2-digit",
    month: "short",
    year: "numeric"
  });
}

function isInviteExpired(invite) {
  if (!invite.expiresAt) return false;

  const expiryDate = invite.expiresAt.toDate
    ? invite.expiresAt.toDate()
    : new Date(invite.expiresAt);

  return expiryDate < new Date();
}

function renderPendingInvites() {
  if (!pendingInvitesList) return;

  pendingInvitesList.innerHTML = "";

  if (!invitesCache.length) {
    pendingInvitesList.innerHTML = `<div class="app-card">No pending invites.</div>`;
    return;
  }

  invitesCache.forEach((invite) => {
    const expired = isInviteExpired(invite);

    const item = document.createElement("div");
    item.className = `elite-match-card ${expired ? "invite-expired" : ""}`;

    item.innerHTML = `
      <div class="elite-match-header">
        <div>
          <span class="section-eyebrow">Pending Invite</span>
          <h3>
            ${invite.fullName || "Unnamed Invite"}
            <span>${invite.email || "No email"}</span>
          </h3>
          <p>${formatRole(invite.role)} access invite</p>
        </div>

        <span class="report-pill ${expired ? "readiness-danger" : "readiness-monitor"}">
          ${expired ? "Expired" : "Active"}
        </span>
      </div>

      <div class="elite-match-meta-grid">
        <div>
          <span>Role</span>
          <strong>${formatRole(invite.role)}</strong>
        </div>

        <div>
          <span>Email Status</span>
          <strong>${invite.emailSent ? "Sent" : "Pending"}</strong>
        </div>

        <div>
          <span>Expires</span>
          <strong>${formatInviteExpiry(invite)}</strong>
        </div>
      </div>

      <div class="elite-match-footer">
        <span class="small-text">Invite status: ${invite.status || "pending"}</span>

        <div class="record-actions">
          ${
            expired
              ? `
                <button class="btn-secondary recreate-invite-btn" data-id="${invite.id}" type="button">
                  Create New Invite
                </button>
              `
              : `
                <button class="btn-secondary resend-invite-btn" data-id="${invite.id}" type="button">
                  Resend Invite
                </button>
              `
          }

          <button class="btn-danger cancel-invite-btn" data-id="${invite.id}" type="button">
            Cancel Invite
          </button>
        </div>
      </div>
    `;

    pendingInvitesList.appendChild(item);
  });
}

function renderAcceptedInvites() {
  if (!acceptedInvitesList) return;

  acceptedInvitesList.innerHTML = "";

  if (!acceptedInvitesCache.length) {
    acceptedInvitesList.innerHTML = `<div class="app-card">No accepted invites yet.</div>`;
    return;
  }

  acceptedInvitesCache.forEach((invite) => {
    const acceptedDate = invite.acceptedAt?.toDate
      ? invite.acceptedAt.toDate().toLocaleString("en-ZA", {
          day: "2-digit",
          month: "short",
          year: "numeric",
          hour: "2-digit",
          minute: "2-digit"
        })
      : "Accepted date unavailable";

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

    item.innerHTML = `
      <div class="elite-match-header">
        <div>
          <span class="section-eyebrow">Accepted Invite</span>
          <h3>
            ${invite.fullName || "Unnamed User"}
            <span>${invite.email || "No email"}</span>
          </h3>
          <p>${formatRole(invite.role)} joined successfully.</p>
        </div>

        <span class="report-pill readiness-ready">Accepted</span>
      </div>

      <div class="elite-match-meta-grid">
        <div>
          <span>Role</span>
          <strong>${formatRole(invite.role)}</strong>
        </div>

        <div>
          <span>Status</span>
          <strong>Accepted</strong>
        </div>

        <div>
          <span>Accepted</span>
          <strong>${acceptedDate}</strong>
        </div>
      </div>
    `;

    acceptedInvitesList.appendChild(item);
  });
}

function renderUsers() {
  userList.innerHTML = "";

  if (!usersCache.length) {
    userList.innerHTML = `<div class="app-card">No users found.</div>`;
    return;
  }

  usersCache
    .filter((user) => user.status !== "inactive")
    .forEach((user) => {
    
    const card = document.createElement("div");
    card.className = "elite-match-card user-management-card";

    card.innerHTML = `
      <div class="elite-match-header">
        <div>
          <span class="section-eyebrow">Platform User</span>
          <h3>
            ${getUserName(user)}
            <span>${user.email || "No email"}</span>
          </h3>
          <p>Assigned Teams: ${renderAssignedTeamSummary(user)}</p>
        </div>

        <span class="report-pill readiness-ready">
          ${formatRole(user.role)}
        </span>
      </div>

      ${
        user.role === "coach" || user.role === "biokineticist"
          ? `
            <div class="assignment-section">
              <h4>Assign to Teams</h4>
              <p class="small-text">Tick the teams this ${formatRole(user.role)} may access.</p>

              <div class="assignment-grid">
                ${renderTeamOptions(user)}
              </div>
            </div>
          `
          : ""
      }

      ${
        user.role === "player"
          ? `
            <div class="assignment-section">
              <h4>Linked Player Profile</h4>
              <p class="small-text">Connect this login account to a player profile.</p>

              <div class="assignment-grid">
                ${renderPlayerLinkCards(user)}
              </div>      
            </div>
          `
          : ""
      }

      ${
        user.uid !== activeProfile.uid && user.role !== "director"
          ? `
            <div class="record-actions">
              <button
                class="btn-danger deactivate-user-btn"
                data-user="${user.uid}"
                type="button"
              >
                Deactivate User
              </button>
            </div>
          `
          : ""
      }
    `;

    userList.appendChild(card);
  });
}

function updateUserTeamCache(userId, teamId, isAssigned) {
  usersCache = usersCache.map((user) => {
    if (user.uid !== userId) return user;

    const assignedTeamIds = user.assignedTeamIds || [];

    return {
      ...user,
      assignedTeamIds: isAssigned
        ? [...new Set([...assignedTeamIds, teamId])]
        : assignedTeamIds.filter((id) => id !== teamId)
    };
  });

  teamsCache = teamsCache.map((team) => {
    if (team.id !== teamId) return team;

    const assignedCoachIds = team.assignedCoachIds || [];

    return {
      ...team,
      assignedCoachIds: isAssigned
        ? [...new Set([...assignedCoachIds, userId])]
        : assignedCoachIds.filter((id) => id !== userId)
    };
  });
}

function updatePlayerLinkCache(userId, playerId) {
  const linkedPlayer = playersCache.find((player) => player.id === playerId);

  usersCache = usersCache.map((user) => {
    if (user.uid !== userId) return user;

    return {
      ...user,
      playerId: playerId || "",
      assignedPlayerIds: playerId ? [playerId] : [],
      assignedTeamIds: linkedPlayer?.teamId ? [linkedPlayer.teamId] : []
    };
  });

  playersCache = playersCache.map((player) => {
    if (player.id === playerId) {
      return {
        ...player,
        userId
      };
    }

    if (player.userId === userId && player.id !== playerId) {
      return {
        ...player,
        userId: ""
      };
    }

    return player;
  });
}

async function createTeamAssignmentNotification({
  selectedUser,
  teamId,
  isAssigned
}) {
  const team = teamsCache.find((item) => item.id === teamId);
  const teamName = team ? team.name || "Unnamed Team" : "Unknown Team";
  const userName = getUserName(selectedUser);
  const role = selectedUser.role || "user";

  await addDoc(collection(db, "notifications"), {
    sourceId: `${selectedUser.uid}-${teamId}`,
    sourceCollection: "users",
    type: "user",
    severity: "info",
    title: isAssigned
      ? `${userName} assigned to ${teamName}`
      : `${userName} removed from ${teamName}`,
    message: isAssigned
      ? `${userName} (${role}) was given access to ${teamName}.`
      : `${userName} (${role}) no longer has access to ${teamName}.`,
    playerId: "",
    playerName: "",
    teamId,
    teamName,
    organisationId: activeProfile.organisationId,
    userId: selectedUser.uid,
    userName,
    userRole: role,
    isRead: false,
    createdAt: serverTimestamp(),
    updatedAt: serverTimestamp()
  });
}

userList.addEventListener("change", async function (event) {
  const checkbox = event.target.closest(".team-assignment-checkbox");

  if (checkbox) {
    const userId = checkbox.dataset.user;
    const teamId = checkbox.dataset.team;
    const checked = checkbox.checked;

    const selectedUser = usersCache.find((user) => user.uid === userId);

    if (!selectedUser) {
      showToast("User not found.", "error");
      return;
    }

    checkbox.disabled = true;
    showLoader("Updating team assignment...");

    try {
      const teamRef = doc(db, "teams", teamId);
      const userRef = doc(db, "users", getUserDocId(selectedUser));

      if (checked) {
        await Promise.all([
          updateDoc(teamRef, { assignedCoachIds: arrayUnion(userId) }),
          updateDoc(userRef, { assignedTeamIds: arrayUnion(teamId) })
        ]);
      } else {
        await Promise.all([
          updateDoc(teamRef, { assignedCoachIds: arrayRemove(userId) }),
          updateDoc(userRef, { assignedTeamIds: arrayRemove(teamId) })
        ]);
      }

      await createTeamAssignmentNotification({
        selectedUser,
        teamId,
        isAssigned: checked
      });

      updateUserTeamCache(userId, teamId, checked);
      renderUsers();

      showToast(
        checked ? "Team assigned successfully." : "Team assignment removed.",
        "success"
      );
    } catch (error) {
      console.error("Assignment error:", error);
      checkbox.checked = !checked;
      showToast("Could not update team assignment: " + error.message, "error");
    } finally {
      checkbox.disabled = false;
      hideLoader();
    }

    return;
  }
});

userList.addEventListener("click", async function (event) {

  const deactivateBtn = event.target.closest(".deactivate-user-btn");

  if (deactivateBtn) {
    const userId = deactivateBtn.dataset.user;
    const selectedUser = usersCache.find((user) => user.uid === userId);

    if (!selectedUser) {
      showToast("User not found.", "error");
      return;
    }

    const confirmed = confirm(`Deactivate ${getUserName(selectedUser)}?`);
    if (!confirmed) return;

    try {
      deactivateBtn.disabled = true;
      deactivateBtn.textContent = "Deactivating...";

      await updateDoc(doc(db, "users", getUserDocId(selectedUser)), {
        status: "inactive",
        assignedTeamIds: [],
        assignedPlayerIds: [],
        playerId: "",
        updatedAt: serverTimestamp()
      });

      if (selectedUser.role === "player" && selectedUser.playerId) {
        await updateDoc(doc(db, "players", selectedUser.playerId), {
          userId: "",
          updatedAt: serverTimestamp()
        });
      }

      await loadPageData();
      showToast("User deactivated successfully.", "success");
    } catch (error) {
      console.error("Deactivate user error:", error);
      showToast("Could not deactivate user: " + error.message, "error");
    }

    return;
  }

  const linkBtn = event.target.closest(".player-link-btn");

  if (!linkBtn) return;

  const userId = linkBtn.dataset.user;
  const playerId = linkBtn.dataset.player;
  const isLinked = linkBtn.dataset.linked === "yes";

  const selectedUser = usersCache.find(
    (user) => user.uid === userId
  );

  const selectedPlayer = playersCache.find(
    (player) => player.id === playerId
  );

  if (!selectedUser || !selectedPlayer) {
    showToast("User or player profile not found.", "error");
    return;
  }

  const teamIds =
    selectedPlayer.teamIds ||
    (selectedPlayer.teamId
      ? [selectedPlayer.teamId]
      : []);

  try {
    linkBtn.disabled = true;
    linkBtn.textContent = isLinked
      ? "Unlinking..."
      : "Linking...";

    await Promise.all([
      updateDoc(
        doc(db, "users", getUserDocId(selectedUser)),
        {
          playerId: isLinked ? "" : playerId,
          assignedPlayerIds: isLinked ? [] : [playerId],
          assignedTeamIds: isLinked ? [] : teamIds,
          updatedAt: serverTimestamp()
        }
      ),

      updateDoc(
        doc(db, "players", playerId),
        {
          userId: isLinked ? "" : userId,
          updatedAt: serverTimestamp()
        }
      )
    ]);

    await loadPageData();

    showToast(
      isLinked
        ? "Player profile unlinked."
        : "Player profile linked successfully.",
      "success"
    );

  } catch (error) {
    console.error("Player link error:", error);

    showToast(
      "Could not update player link: " + error.message,
      "error"
    );
  }
});

async function sendInviteEmail(invite) {
  const registerUrl = "https://www.trytrack.co.za/register.html";
  const logoUrl = "https://www.trytrack.co.za/assets/trytrack-logo.png";

  await addDoc(collection(db, "mail"), {
    to: invite.email,
    message: {
      subject: "You have been invited to join TryTrack",
      html: `
        <div style="margin:0;padding:0;background:#07111f;font-family:Arial,sans-serif;color:#ffffff;">
          <div style="max-width:640px;margin:0 auto;padding:36px 18px;">
            <div style="background:#0f172a;border:1px solid rgba(148,163,184,0.22);border-radius:28px;overflow:hidden;">
              <div style="background:linear-gradient(135deg,#38bdf8,#2563eb);padding:38px 30px;text-align:center;">
                <img src="${logoUrl}" alt="TryTrack" style="max-width:190px;height:auto;margin-bottom:22px;display:inline-block;" />
                <h1 style="margin:0;color:#ffffff;font-size:30px;line-height:1.1;font-weight:800;">You're invited to TryTrack</h1>
                <p style="margin:12px 0 0;color:rgba(255,255,255,0.88);font-size:16px;">Join your sports performance workspace</p>
              </div>

              <div style="padding:36px 32px;">
                <p style="margin:0 0 18px;color:#e5e7eb;font-size:17px;">Hi <strong>${invite.fullName || "there"}</strong>,</p>
                <p style="margin:0 0 22px;color:#cbd5e1;font-size:15px;line-height:1.7;">
                  You have been invited to join <strong style="color:#ffffff;">TryTrack</strong>
                  as a <strong style="color:#ffffff;">${formatRole(invite.role)}</strong>.
                </p>

                <div style="margin:26px 0;padding:18px 20px;background:#07111f;border:1px solid rgba(148,163,184,0.18);border-radius:18px;">
                  <p style="margin:0 0 8px;color:#94a3b8;font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;">
                    Register with this email
                  </p>
                  <p style="margin:0;color:#ffffff;font-size:17px;font-weight:800;">${invite.email}</p>
                </div>

                <div style="text-align:center;margin:34px 0;">
                  <a href="${registerUrl}" style="display:inline-block;padding:16px 28px;background:linear-gradient(135deg,#38bdf8,#2563eb);color:#ffffff;text-decoration:none;border-radius:14px;font-size:16px;font-weight:800;">
                    Register Now
                  </a>
                </div>

                <p style="margin:0;color:#94a3b8;font-size:14px;line-height:1.7;">
                  After registration, your account will automatically join the correct organisation.
                  ${
                    invite.role === "player"
                      ? "Your director can then link your login account to your player profile."
                      : "Your director can then assign you to the relevant team."
                    }
                    <br><br>
                    This invite expires in 7 days.
                </p>
              </div>

              <div style="padding:22px 28px;background:#020617;border-top:1px solid rgba(148,163,184,0.14);text-align:center;">
                <p style="margin:0;color:#64748b;font-size:12px;">TryTrack Sports Performance Platform</p>
              </div>
            </div>
          </div>
        </div>
      `,
      text:
        `Hi ${invite.fullName || "there"},\n\n` +
        `You have been invited to join TryTrack as a ${formatRole(invite.role)}.\n\n` +
        `Please register using this email address: ${invite.email}\n\n` +
        `Register now: ${registerUrl}\n\n` +
        `After registration, your account will automatically join the correct organisation. ` +
        `${invite.role === "player" ? "Your director can then link your login account to your player profile." : "Your director can then assign you to the relevant team."}`
    },
    createdAt: serverTimestamp()
  });
}

async function canInviteRole(role) {
  if (!activeProfile?.organisationId) return false;

  if (role === "director") {
    showToast("Director accounts cannot be invited from here.", "warning");
    return false;
  }

  const organisationRef = doc(db, "organisations", activeProfile.organisationId);
  const organisationSnap = await getDoc(organisationRef);

  if (!organisationSnap.exists()) {
    showToast("Organisation not found.", "error");
    return false;
  }

  const organisation = organisationSnap.data();
  const subscription = organisation.subscription || {};
  const limits = subscription.limits || {};

  const activeUsersForRole = usersCache.filter((user) => {
    return (
      String(user.role || "").toLowerCase() === role &&
      user.status !== "inactive"
    );
  });

  const pendingInvitesForRole = invitesCache.filter((invite) => {
    return String(invite.role || "").toLowerCase() === role;
  });

  const currentTotal = activeUsersForRole.length + pendingInvitesForRole.length;

  let maxAllowed = 0;
  let roleLabel = formatRole(role);

  if (role === "coach") {
    maxAllowed = Number(limits.maxCoaches || 0);
  }

  if (role === "biokineticist") {
    maxAllowed = Number(limits.maxBiokineticists || 0);
  }

  if (role === "player") {
    maxAllowed = Number(limits.maxPlayers || 0);
  }

  if (!maxAllowed) {
    showToast(`No ${roleLabel} limit found for this subscription.`, "warning");
    return false;
  }

  if (currentTotal >= maxAllowed) {
    showToast(
      `Your current subscription allows a maximum of ${maxAllowed} ${roleLabel}(s). Please upgrade your plan to invite more.`,
      "warning"
    );

    return false;
  }

  return true;
}

if (inviteUserForm) {
  inviteUserForm.addEventListener("submit", async function (event) {
    event.preventDefault();

    const fullName = inviteFullName.value.trim();
    const email = inviteEmail.value.trim().toLowerCase();
    const role = inviteRole.value;

    if (!fullName || !email || !role) {
      showToast("Please complete all invite fields.", "warning");
      return;
    }

    const existingInvite = invitesCache.find((invite) => {
      return String(invite.email || "").toLowerCase() === email;
    });

    const existingUser = usersCache.find((user) => {
      return String(user.email || "").toLowerCase() === email;
    });
    
    if (existingUser) {
    
      if (existingUser.status !== "inactive") {
        showToast("This email already belongs to an active user.", "warning");
        return;
      }
    
      const confirmed = confirm(
        `${existingUser.fullName || existingUser.email} was previously deactivated.\n\nReactivate this user instead of creating a new invite?`
      );
    
      if (confirmed) {
    
        await updateDoc(
          doc(db, "users", getUserDocId(existingUser)),
          {
            status: "active",
            updatedAt: serverTimestamp()
          }
        );
    
        await loadPageData();
    
        showToast(
          "User reactivated successfully.",
          "success"
        );
    
        return;
      }
    }

    if (existingUser) {
      showToast("This email already belongs to an active user.", "warning");
      return;
    }

    const allowedToInvite = await canInviteRole(role);

    if (!allowedToInvite) {
      return;
    }
    
    setInviteLoading(true);

    try {
      const inviteData = {
        fullName,
        email,
        role,
        organisationId: activeProfile.organisationId,
        assignedTeamIds: [],
        assignedPlayerIds: [],
        status: "pending",
        invitedBy: activeProfile.uid,
        createdAt: serverTimestamp(),
        updatedAt: serverTimestamp(),
        expiresAt: getInviteExpiryDate()
      };

      const inviteRef = await addDoc(collection(db, "userInvites"), inviteData);

      await sendInviteEmail({
        id: inviteRef.id,
        ...inviteData
      });

      await updateDoc(doc(db, "userInvites", inviteRef.id), {
        emailSent: true,
        emailSentAt: serverTimestamp(),
        updatedAt: serverTimestamp()
      });

      inviteUserForm.reset();

      await loadPageData();

      showToast("Invite created and added to pending invites.", "success");
    } catch (error) {
      console.error("Invite user error:", error);
      showToast("Could not create invite: " + error.message, "error");
    } finally {
      setInviteLoading(false);
    }
  });
}

if (pendingInvitesList) {
  pendingInvitesList.addEventListener("click", async function (event) {
    const resendBtn = event.target.closest(".resend-invite-btn");
    const cancelBtn = event.target.closest(".cancel-invite-btn");
    const recreateBtn = event.target.closest(".recreate-invite-btn");

    if (recreateBtn) {
      const inviteId = recreateBtn.dataset.id;
      const oldInvite = invitesCache.find((item) => item.id === inviteId);

      if (!oldInvite) {
        showToast("Invite not found.", "error");
        return;
      }

      try {
        recreateBtn.disabled = true;
        recreateBtn.textContent = "Creating...";

        await deleteDoc(doc(db, "userInvites", inviteId));

        const newInviteData = {
          fullName: oldInvite.fullName,
          email: oldInvite.email,
          role: oldInvite.role,
          organisationId: oldInvite.organisationId,
          assignedTeamIds: oldInvite.assignedTeamIds || [],
          assignedPlayerIds: oldInvite.assignedPlayerIds || [],
          status: "pending",
          invitedBy: activeProfile.uid,
          createdAt: serverTimestamp(),
          updatedAt: serverTimestamp(),
          expiresAt: getInviteExpiryDate()
        };

        const newInviteRef = await addDoc(collection(db, "userInvites"), newInviteData);

        await sendInviteEmail({
          id: newInviteRef.id,
          ...newInviteData
        });

        await updateDoc(doc(db, "userInvites", newInviteRef.id), {
          emailSent: true,
          emailSentAt: serverTimestamp(),
          updatedAt: serverTimestamp()
        });

        await loadPageData();

        showToast("New invite created and sent.", "success");
      } catch (error) {
        console.error("Recreate invite error:", error);
        showToast("Could not create new invite: " + error.message, "error");
      }

      return;
    }

    if (resendBtn) {
      const inviteId = resendBtn.dataset.id;
      const invite = invitesCache.find((item) => item.id === inviteId);

      if (!invite) {
        showToast("Invite not found.", "error");
        return;
      }

      if (isInviteExpired(invite)) {
        showToast("This invite has expired. Please create a new invite.", "warning");
        return;
      }

      try {
        resendBtn.disabled = true;
        resendBtn.textContent = "Sending...";

        await sendInviteEmail(invite);

        await updateDoc(doc(db, "userInvites", invite.id), {
          resentAt: serverTimestamp(),
          updatedAt: serverTimestamp()
        });

        showToast("Invite email resent.", "success");
      } catch (error) {
        console.error("Resend invite error:", error);
        showToast("Could not resend invite: " + error.message, "error");
      } finally {
        resendBtn.disabled = false;
        resendBtn.textContent = "Resend Invite";
      }

      return;
    }

    if (cancelBtn) {
      const inviteId = cancelBtn.dataset.id;

      const confirmed = confirm("Are you sure you want to cancel this invite?");
      if (!confirmed) return;

      try {
        cancelBtn.disabled = true;
        cancelBtn.textContent = "Cancelling...";

        await deleteDoc(doc(db, "userInvites", inviteId));

        invitesCache = invitesCache.filter((invite) => invite.id !== inviteId);
        renderPendingInvites();

        await loadPageData();

        showToast("Invite cancelled and deleted.", "success");
      } catch (error) {
        console.error("Cancel invite error:", error);
        showToast("Could not delete invite: " + error.message, "error");
      }
    }
  });
}

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

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

  showLoader("Loading user management...");

  try {
    await loadPageData();
  } catch (error) {
    console.error("User management error:", error);
    userList.innerHTML = `
      <div class="app-card">
        <strong>Error loading user management.</strong>
        <p>${error.message}</p>
      </div>
    `;
    showToast("Could not load user management: " + error.message, "error");
  } finally {
    hideLoader();
  }
});