import {
  userFromJwt,
  rolesFromJwt,
  roleIdsFromJwt,
} from "./jwtPayload.js";
import { decodeJwtPayload, JWT_PURPOSE } from "./tokenClaims.js";

export const AUTH_STORAGE_KEY = "hse_auth";

const LEGACY_JSON_KEYS = ["ptw_auth", "swi_auth", "risk_assessment_auth"];

function usesSessionStorage() {
  if (typeof import.meta !== "undefined" && import.meta.env) {
    const flag = import.meta.env.VITE_HSE_AUTH_STORAGE;
    if (flag != null && String(flag).trim().toLowerCase() === "local") {
      return false;
    }
    if (flag != null && String(flag).trim().toLowerCase() === "session") {
      return true;
    }
    if (import.meta.env.VITE_HSE_APP_AUD) {
      return true;
    }
  }
  if (typeof process !== "undefined" && process.env) {
    const cra = process.env.REACT_APP_HSE_AUTH_STORAGE;
    if (cra != null && String(cra).trim().toLowerCase() === "local") {
      return false;
    }
    if (cra != null && String(cra).trim().toLowerCase() === "session") {
      return true;
    }
    if (process.env.REACT_APP_HSE_APP_AUD) {
      return true;
    }
  }
  return false;
}

function authStorage(scope) {
  if (typeof window === "undefined") return null;
  if (scope === "master") {
    return window.localStorage;
  }
  return usesSessionStorage() ? window.sessionStorage : window.localStorage;
}

function readAuthFromStorage(storage) {
  if (!storage) return null;
  try {
    const raw = storage.getItem(AUTH_STORAGE_KEY);
    if (!raw) return null;
    return normalizeAuth(parseJson(raw));
  } catch {
    return null;
  }
}

function isUsableMasterLoginToken(token) {
  const payload = decodeJwtPayload(token);
  if (!payload) return false;
  if (
    payload.purpose === JWT_PURPOSE.APP_LAUNCH ||
    payload.purpose === JWT_PURPOSE.APP_SESSION
  ) {
    return false;
  }
  return true;
}

function parseJson(raw) {
  try {
    return JSON.parse(raw);
  } catch {
    return null;
  }
}

function authFromLegacy() {
  if (typeof localStorage === "undefined") return null;

  const rawToken = localStorage.getItem("token");
  const isAuthenticated = localStorage.getItem("isAuthenticated") === "true";
  if (rawToken && isAuthenticated) {
    return {
      token: rawToken,
      user: userFromJwt(rawToken),
      roles: rolesFromJwt(rawToken),
      roleIds: roleIdsFromJwt(rawToken),
    };
  }

  for (const key of LEGACY_JSON_KEYS) {
    const raw = localStorage.getItem(key);
    if (!raw) continue;
    const parsed = parseJson(raw);
    if (parsed?.token) {
      return normalizeAuth(parsed);
    }
  }

  return null;
}

export function normalizeAuth(auth) {
  if (!auth?.token) return null;
  const token = String(auth.token).trim();
  if (!token) return null;
  return {
    token,
    user:
      auth.user ||
      userFromJwt(token) || { userId: null, employeeName: "HSE User", email: "" },
    roles: auth.roles?.length ? auth.roles : rolesFromJwt(token),
    roleIds: auth.roleIds?.length ? auth.roleIds : roleIdsFromJwt(token),
  };
}

export function getStoredAuth() {
  const storage = authStorage();
  if (!storage) return null;
  try {
    const parsed = readAuthFromStorage(storage);
    if (parsed?.token) return parsed;
    if (!usesSessionStorage()) {
      const migrated = authFromLegacy();
      if (migrated?.token) {
        setStoredAuth(migrated);
        clearLegacyAuth();
        return migrated;
      }
    }
    return null;
  } catch {
    return null;
  }
}

/** Master Dashboard login JWT — always from localStorage, never child session tokens. */
export function getMasterStoredAuth() {
  const parsed = readAuthFromStorage(
    typeof window !== "undefined" ? window.localStorage : null
  );
  if (!parsed?.token || !isUsableMasterLoginToken(parsed.token)) {
    return null;
  }
  return parsed;
}

export function getMasterLoginToken() {
  return getMasterStoredAuth()?.token || null;
}

export function clearMasterStoredAuth() {
  if (typeof localStorage === "undefined") return;
  localStorage.removeItem(AUTH_STORAGE_KEY);
  localStorage.removeItem("isAuthenticated");
  clearLegacyAuth();
}

export function setStoredAuth(auth, options = {}) {
  const storage = authStorage(options.scope);
  if (!storage) return;
  const normalized = normalizeAuth(auth);
  if (normalized) {
    storage.setItem(AUTH_STORAGE_KEY, JSON.stringify(normalized));
    if (options.scope === "master" || !usesSessionStorage()) {
      localStorage.setItem("isAuthenticated", "true");
    }
  } else {
    storage.removeItem(AUTH_STORAGE_KEY);
    if (options.scope === "master" || !usesSessionStorage()) {
      localStorage.removeItem("isAuthenticated");
    }
  }
}

export function clearStoredAuth() {
  const storage = authStorage();
  if (!storage) return;
  storage.removeItem(AUTH_STORAGE_KEY);
  if (!usesSessionStorage()) {
    localStorage.removeItem("isAuthenticated");
    clearLegacyAuth();
  }
}

function clearLegacyAuth() {
  localStorage.removeItem("token");
  localStorage.removeItem("ptw_auth");
  localStorage.removeItem("swi_auth");
  localStorage.removeItem("risk_assessment_auth");
}

export function getToken() {
  return getStoredAuth()?.token || null;
}

export function isAuthenticated() {
  return Boolean(getToken());
}
