// =========================================================
// FILE: subscription.js | TYPE: Subscription Logic
// =========================================================

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

const elements = {
  subscriptionPlan: document.getElementById("subscriptionPlan"),
  subscriptionStatus: document.getElementById("subscriptionStatus"),
  trialDaysLeft: document.getElementById("trialDaysLeft"),
  trialEndDate: document.getElementById("trialEndDate"),
  billingCycle: document.getElementById("billingCycle"),
  currentPeriodEnds: document.getElementById("currentPeriodEnds"),
  limitTeams: document.getElementById("limitTeams"),
  limitPlayers: document.getElementById("limitPlayers"),
  limitCoaches: document.getElementById("limitCoaches"),
  limitBio: document.getElementById("limitBio")
};

let activeProfile = null;

const PLAN_LIMITS = {
  team: {
    maxTeams: 1,
    maxPlayers: 100,
    maxCoaches: 3,
    maxBiokineticists: 1
  },

  club: {
    maxTeams: 8,
    maxPlayers: 500,
    maxCoaches: 20,
    maxBiokineticists: 5
  },

  "high-performance": {
    maxTeams: 999,
    maxPlayers: 9999,
    maxCoaches: 999,
    maxBiokineticists: 999
  }
};

const PLAN_PRICES = {
  team: {
    monthly: 1999,
    yearly: 19990
  },

  club: {
    monthly: 5999,
    yearly: 59990
  },

  "high-performance": {
    monthly: 0,
    yearly: 0
  }
};

function setText(element, value) {
  if (!element) return;
  element.textContent = value;
}

function formatDate(value) {
  if (!value) return "No date set";

  const date = value.toDate ? value.toDate() : new Date(value);

  if (Number.isNaN(date.getTime())) return "Invalid date";

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

function getDaysLeft(value) {
  if (!value) return "-";

  const date = value.toDate ? value.toDate() : new Date(value);
  const today = new Date();

  const difference = date.getTime() - today.getTime();
  const days = Math.ceil(difference / (1000 * 60 * 60 * 24));

  return Math.max(days, 0);
}

function titleCase(value) {
  if (!value) return "Trial";

  return String(value)
    .replaceAll("-", " ")
    .replace(/\b\w/g, (letter) => letter.toUpperCase());
}

async function loadSubscription() {
  if (!activeProfile?.organisationId) return;

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

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

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

  setText(elements.subscriptionPlan, titleCase(subscription.plan || "trial"));
  setText(elements.subscriptionStatus, titleCase(subscription.status || "trial"));

  if (subscription.isDemo || subscription.status === "demo") {
    setText(elements.trialDaysLeft, "Demo");
    setText(elements.trialEndDate, "No expiry");
    setText(elements.billingCycle, "None");
    setText(elements.currentPeriodEnds, "Demo organisation");
  } else {
    setText(elements.trialDaysLeft, `${getDaysLeft(subscription.trialEndsAt)} days`);
    setText(elements.trialEndDate, formatDate(subscription.trialEndsAt));
    setText(elements.billingCycle, titleCase(subscription.billingCycle || "none"));
    setText(elements.currentPeriodEnds, formatDate(subscription.currentPeriodEndsAt));
  }

  setText(elements.limitTeams, limits.maxTeams ?? "-");
  setText(elements.limitPlayers, limits.maxPlayers ?? "-");
  setText(elements.limitCoaches, limits.maxCoaches ?? "-");
  setText(elements.limitBio, limits.maxBiokineticists ?? "-");
}

async function selectPlan(plan, billingCycle = "monthly") {
  if (!activeProfile?.organisationId) return;

  const limits = PLAN_LIMITS[plan];
  const amount = PLAN_PRICES[plan]?.[billingCycle] ?? 0;

  if (!limits) {
    showToast("Unknown plan selected.", "error");
    return;
  }

  if (plan !== "high-performance" && !amount) {
    showToast("Unknown billing cycle selected.", "error");
    return;
  }

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

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

  const organisation = organisationSnap.data();
  const existingSubscription = organisation.subscription || {};
  
  if (existingSubscription.isDemo || existingSubscription.status === "demo") {
    showToast("This is the TryTrack demo organisation. Billing changes are disabled.", "warning");
    return;
  }

  const periodEndsAt = new Date();

  if (billingCycle === "yearly") {
    periodEndsAt.setFullYear(periodEndsAt.getFullYear() + 1);
  } else {
    periodEndsAt.setMonth(periodEndsAt.getMonth() + 1);
  }

  await updateDoc(organisationRef, {
    subscription: {
      ...existingSubscription,
      plan,
      status: "pending_payment",
      billingCycle,
      amount,
      currency: "ZAR",
      active: false,
      currentPeriodEndsAt: periodEndsAt,
      limits
    },
    updatedAt: serverTimestamp()
  });

  showToast(
    plan === "high-performance"
      ? "Custom plan request selected."
      : `${titleCase(plan)} ${titleCase(billingCycle)} plan selected. Redirecting to payment...`,
    "success"
  );

  await loadSubscription();
}

function setupPlanButtons() {
  document.querySelectorAll(".plan-btn").forEach((button) => {
    button.addEventListener("click", async () => {
      const plan = button.dataset.plan;
      const billingCycle = button.dataset.cycle || "monthly";
      const originalText = button.textContent;

      button.disabled = true;
      button.textContent = "Processing...";

      try {
        if (!activeProfile?.organisationId) {
          throw new Error("Organisation not found for this user.");
        }

        if (plan === "high-performance") {
          await selectPlan(plan, "monthly");
          window.location.href = "contact.html?plan=high-performance";
          return;
        }

        await selectPlan(plan, billingCycle);

        const response = await fetch("/api/create-payfast-checkout.php", {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify({
            plan,
            cycle: billingCycle,
            organisationId: activeProfile.organisationId
          })
        });

        const data = await response.json();

        if (!response.ok || !data.paymentUrl) {
          throw new Error(data.error || "Could not start PayFast checkout.");
        }

        window.location.href = data.paymentUrl;
      } catch (error) {
        console.error("Plan selection error:", error);
        showToast("Could not start payment: " + error.message, "error");
      } finally {
        button.disabled = false;
        button.textContent = originalText;
      }
    });
  });
}

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

  setupLogoutButton();

  const userRole = String(profile?.role || "").trim().toLowerCase();

  if (userRole !== "director") {
    showToast("Only directors can manage subscriptions.", "warning");
    window.location.href = "dashboard.html";
    return;
  }

  showLoader("Loading subscription...");

  try {
    await loadSubscription();
    setupPlanButtons();
  } catch (error) {
    console.error("Subscription load error:", error);
    showToast("Could not load subscription: " + error.message, "error");
  } finally {
    hideLoader();
  }
});