const { Companies } = require("../models");
const { encryptMsToken, decryptMsToken } = require("./msTokenCrypto");
const { refreshToken: msRefreshAccess } = require("../services/microsoftGraph");

const SKEW_MS = 5 * 60 * 1000;

/**
 * Returns a valid Microsoft Graph access token for the company, refreshing if needed.
 * Updates Companies row when refresh occurs.
 */
async function ensureFreshMsAccessToken(companyId) {
  if (!companyId) return null;

  const company = await Companies.findByPk(companyId);
  if (!company || !company.msRefreshToken) return null;

  const expiresAt = company.msTokenExpiresAt ? new Date(company.msTokenExpiresAt) : null;
  const stillValid = expiresAt && expiresAt.getTime() > Date.now() + SKEW_MS;

  if (stillValid) {
    return decryptMsToken(company.msAccessToken);
  }

  const refreshPlain = decryptMsToken(company.msRefreshToken);
  if (!refreshPlain) return null;

  try {
    const refreshed = await msRefreshAccess(refreshPlain);
    const newAccessEnc = encryptMsToken(refreshed.accessToken);
    const newRefreshEnc = encryptMsToken(refreshed.refreshToken);
    const msTokenExpiresAt = new Date(Date.now() + (refreshed.expiresIn || 3600) * 1000);

    await Companies.update(
      {
        msAccessToken: newAccessEnc,
        msRefreshToken: newRefreshEnc,
        msTokenExpiresAt,
      },
      { where: { id: companyId } },
    );

    return refreshed.accessToken;
  } catch (e) {
    console.error("ensureFreshMsAccessToken refresh failed:", e.message);
    return null;
  }
}

module.exports = { ensureFreshMsAccessToken };
