// =========================================================
// FILE: auth.js | TYPE: Authentication Logic
// =========================================================

import { auth, db } from "./firebase-config.js";

import {
  signInWithEmailAndPassword,
  createUserWithEmailAndPassword,
  sendPasswordResetEmail,
  onAuthStateChanged,
  signOut
} from "https://www.gstatic.com/firebasejs/10.12.2/firebase-auth.js";

import {
  collection,
  doc,
  getDoc,
  getDocs,
  setDoc,
  addDoc,
  updateDoc,
  query,
  where,
  serverTimestamp
} from "https://www.gstatic.com/firebasejs/10.12.2/firebase-firestore.js";

const loginForm = document.getElementById("loginForm");
const registerForm = document.getElementById("registerForm");
const resetPasswordForm = document.getElementById("resetPasswordForm");
const logoutBtn = document.getElementById("logoutBtn");

const userRoleSelect = document.getElementById("userRole");
const directorOnlyFields = document.querySelectorAll(".director-only-field");
const inviteOnlyNotice = document.getElementById("inviteOnlyNotice");

function getRoleHomePage(role) {
  const roleHomePages = {
    director: "dashboard.html",
    coach: "dashboard.html",
    player: "player-dashboard.html",
    biokineticist: "bio-dashboard.html"
  };

  return roleHomePages[role] || "dashboard.html";
}

function setButtonLoading(button, isLoading, loadingText, defaultText) {
  if (!button) return;

  button.disabled = isLoading;
  button.textContent = isLoading ? loadingText : defaultText;
}

function showMessage(message) {
  // Inline message — no alert() 
  alert(message);
}

function getFirebaseErrorMessage(error) {
  const code = error?.code || "";

  const messages = {
    "auth/invalid-email": "Please enter a valid email address.",
    "auth/user-not-found": "No account was found with this email address.",
    "auth/wrong-password": "The password you entered is incorrect.",
    "auth/invalid-credential": "The email or password is incorrect.",
    "auth/email-already-in-use": "An account already exists with this email address.",
    "auth/weak-password": "Your password should be at least 6 characters long.",
    "auth/network-request-failed": "Network error. Please check your connection and try again.",
    "permission-denied": "You do not have permission to complete this action."
  };

  return messages[code] || error?.message || "Something went wrong. Please try again.";
}

function updateRegisterRoleUI() {
  if (!userRoleSelect) return;

  const isDirector = userRoleSelect.value === "director";

  directorOnlyFields.forEach((field) => {
    field.classList.toggle("hidden", !isDirector);
  });

  if (inviteOnlyNotice) {
    inviteOnlyNotice.classList.toggle("hidden", isDirector);
  }
}

if (userRoleSelect) {
  updateRegisterRoleUI();
  userRoleSelect.addEventListener("change", updateRegisterRoleUI);
}

async function findPendingInvite(email) {
  const inviteQuery = query(
    collection(db, "userInvites"),
    where("email", "==", email.toLowerCase()),
    where("status", "==", "pending")
  );

  const snapshot = await getDocs(inviteQuery);

  if (snapshot.empty) return null;

  const inviteDoc = snapshot.docs[0];

  return {
    id: inviteDoc.id,
    ...inviteDoc.data()
  };
}

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

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

  return expiryDate < new Date();
}

async function createUserNotification({
  organisationId,
  userId,
  fullName,
  email,
  role,
  type,
  title,
  message
}) {
  await addDoc(collection(db, "notifications"), {
    sourceId: userId,
    sourceCollection: "users",
    type,
    severity: "info",
    title,
    message,
    playerId: "",
    playerName: "",
    teamId: "",
    teamName: "",
    organisationId,
    userId,
    userName: fullName || "",
    userEmail: email || "",
    userRole: role || "",
    isRead: false,
    createdAt: serverTimestamp(),
    updatedAt: serverTimestamp()
  });
}

async function redirectUserByRole(user) {
  const userRef = doc(db, "users", user.uid);
  const userSnap = await getDoc(userRef);

  if (!userSnap.exists()) {
    showMessage("User profile not found. Please contact support.");
    await signOut(auth);
    window.location.href = "login.html";
    return;
  }

  const profile = userSnap.data();

  if (!profile.role) {
    showMessage("No user role found. Please contact support.");
    await signOut(auth);
    window.location.href = "login.html";
    return;
  }

  if (profile.status && profile.status !== "active") {
    showMessage("Your account is not active. Please contact your organisation administrator.");
    await signOut(auth);
    window.location.href = "login.html";
    return;
  }

  window.location.href = getRoleHomePage(profile.role);
}

// =========================================================
// LOGIN
// =========================================================

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

    const email = document.getElementById("email").value.trim().toLowerCase();
    const password = document.getElementById("password").value;
    const submitButton = loginForm.querySelector("button[type='submit']");

    if (!email || !password) {
      showMessage("Please enter your email and password.");
      return;
    }

    setButtonLoading(submitButton, true, "Signing in...", "Sign In");

    try {
      const userCredential = await signInWithEmailAndPassword(auth, email, password);
      await redirectUserByRole(userCredential.user);
    } catch (error) {
      console.error("Login error:", error);
      showMessage("Login failed: " + getFirebaseErrorMessage(error));
    } finally {
      setButtonLoading(submitButton, false, "Signing in...", "Sign In");
    }
  });
}

// =========================================================
// REGISTER
// =========================================================

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

    const fullName = document.getElementById("fullName").value.trim();
    const email = document.getElementById("registerEmail").value.trim().toLowerCase();
    const password = document.getElementById("registerPassword").value;
    const organisationName = document.getElementById("organisationName")?.value.trim() || "";
    const organisationType = document.getElementById("organisationType")?.value || "school";
    const userRole = document.getElementById("userRole").value;
    const submitButton = registerForm.querySelector("button[type='submit']");

    if (!fullName || !email || !password) {
      showMessage("Please complete your name, email and password.");
      return;
    }

    setButtonLoading(submitButton, true, "Creating account...", "Create Account");

    try {
      const pendingInvite = await findPendingInvite(email);

      if (!pendingInvite && userRole !== "director") {
        showMessage("Coach and biokineticist accounts must be invited by a director before registering.");
        return;
      }

      if (pendingInvite && isInviteExpired(pendingInvite)) {
        showMessage("This invite has expired. Please ask your director to send a new invite.");
        return;
      }

      if (!pendingInvite && userRole === "director") {
        if (!organisationName || !organisationType) {
          showMessage("Please complete the organisation fields.");
          return;
        }
      }

      const userCredential = await createUserWithEmailAndPassword(auth, email, password);
      const user = userCredential.user;

      if (pendingInvite) {
        await setDoc(doc(db, "users", user.uid), {
          uid: user.uid,
          fullName: pendingInvite.fullName || fullName,
          email,
          role: pendingInvite.role,
          organisationId: pendingInvite.organisationId,
          assignedTeamIds: pendingInvite.assignedTeamIds || [],
          assignedPlayerIds: pendingInvite.assignedPlayerIds || [],
          status: "active",
          createdFromInvite: true,
          inviteId: pendingInvite.id,
          createdAt: serverTimestamp(),
          updatedAt: serverTimestamp()
        });

        await addDoc(collection(db, "userInviteHistory"), {
          inviteId: pendingInvite.id,
          fullName: pendingInvite.fullName || fullName,
          email,
          role: pendingInvite.role,
          organisationId: pendingInvite.organisationId,
          acceptedBy: user.uid,
          status: "accepted",
          acceptedAt: serverTimestamp(),
          createdAt: serverTimestamp()
        });

        await updateDoc(doc(db, "userInvites", pendingInvite.id), {
          status: "accepted",
          acceptedBy: user.uid,
          acceptedAt: serverTimestamp(),
          updatedAt: serverTimestamp()
        });

        await createUserNotification({
          organisationId: pendingInvite.organisationId,
          userId: user.uid,
          fullName: pendingInvite.fullName || fullName,
          email,
          role: pendingInvite.role,
          type: "user",
          title: `${pendingInvite.fullName || fullName} accepted their TryTrack invite`,
          message: `${pendingInvite.fullName || fullName} registered as ${pendingInvite.role}.`
        });

        showMessage("Account created successfully. You have joined your organisation.");
        window.location.href = getRoleHomePage(pendingInvite.role);
        return;
      }

      const orgRef = await addDoc(collection(db, "organisations"), {
        name: organisationName,
        type: organisationType,
        subscriptionPlan: "trial",
        status: "active",
        ownerUserId: user.uid,
        createdAt: serverTimestamp(),
        updatedAt: serverTimestamp()
      });

      await setDoc(doc(db, "users", user.uid), {
        uid: user.uid,
        fullName,
        email,
        role: userRole,
        organisationId: orgRef.id,
        assignedTeamIds: [],
        assignedPlayerIds: [],
        status: "active",
        createdAt: serverTimestamp(),
        updatedAt: serverTimestamp()
      });

      await createUserNotification({
        organisationId: orgRef.id,
        userId: user.uid,
        fullName,
        email,
        role: userRole,
        type: "user",
        title: `${organisationName} workspace created`,
        message: `${fullName} created the ${organisationName} TryTrack organisation.`
      });

      showMessage("Account and organisation created successfully.");
      window.location.href = getRoleHomePage(userRole);
    } catch (error) {
      console.error("Registration error:", error);
      showMessage("Registration failed: " + getFirebaseErrorMessage(error));
    } finally {
      setButtonLoading(submitButton, false, "Creating account...", "Create Account");
    }
  });
}

// =========================================================
// PASSWORD RESET
// =========================================================

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

    const email = document.getElementById("resetEmail").value.trim().toLowerCase();
    const submitButton = resetPasswordForm.querySelector("button[type='submit']");
    const messageBox = document.getElementById("resetPasswordMessage");

    function showResetMessage(message, type) {
      if (!messageBox) return;

      messageBox.textContent = message;
      messageBox.className = `auth-message auth-message-${type}`;
    }

    if (!email) {
      showResetMessage("Please enter your email address.", "error");
      return;
    }

    setButtonLoading(submitButton, true, "Sending reset link...", "Send Reset Link");

    try {
      await sendPasswordResetEmail(auth, email);

      showResetMessage(
        "Password reset link sent. Please check your inbox and spam folder.",
        "success"
      );
    } catch (error) {
      console.error("Password reset error:", error);

      showResetMessage(
        "No TryTrack account was found with this email address.",
        "error"
      );
    } finally {
      setButtonLoading(submitButton, false, "Sending reset link...", "Send Reset Link");
    }
  });
}

// =========================================================
// LOGOUT
// =========================================================

if (logoutBtn) {
  logoutBtn.addEventListener("click", async function () {
    try {
      await signOut(auth);
      window.location.href = "login.html";
    } catch (error) {
      console.error("Logout error:", error);
      showMessage("Logout failed: " + getFirebaseErrorMessage(error));
    }
  });
}

// =========================================================
// AUTH STATUS HELPER
// =========================================================

onAuthStateChanged(auth, function (user) {
  const authStatus = document.getElementById("authStatus");

  if (authStatus) {
    authStatus.textContent = user ? `Logged in as ${user.email}` : "Not logged in";
  }
});
