import { clearWorkpulsePermissions } from "~/utils/workpulse-permissions";

/** Meta user ringan di sessionStorage (bukan rahasia) — supaya UI tahu role setelah full page reload; otorisasi nyata tetap di BE + JWT. */

const KEYS = {
  userId: "workpulse:session-user-id",
  role: "workpulse:session-role",
  email: "workpulse:session-email",
  name: "workpulse:session-name",
  avatarUrl: "workpulse:session-avatar-url",
  accessToken: "workpulse:access-token",
  refreshToken: "workpulse:refresh-token"
} as const;

const REMEMBER_ME_KEY = "workpulse:remember-me";
const REMEMBER_EMAIL_KEY = "workpulse:remember-email";

const PERSIST_KEYS = {
  accessToken: "workpulse:persist-access-token",
  refreshToken: "workpulse:persist-refresh-token"
} as const;

/**
 * Mirror token lintas-tab.
 * Dipakai agar tab baru (sessionStorage kosong) tetap bisa baca token aktif dari tab lain.
 * Dihapus saat logout/clear session.
 */
const TAB_SHARED_KEYS = {
  accessToken: "workpulse:tab-shared-access-token",
  refreshToken: "workpulse:tab-shared-refresh-token"
} as const;

export function readRememberMePreference(): boolean {
  if (!import.meta.client) return false;
  try {
    return localStorage.getItem(REMEMBER_ME_KEY) === "1";
  } catch {
    return false;
  }
}

export function readRememberedLoginEmail(): string | null {
  if (!import.meta.client || !readRememberMePreference()) return null;
  try {
    const em = (localStorage.getItem(REMEMBER_EMAIL_KEY) || "").trim();
    return em || null;
  } catch {
    return null;
  }
}

export function setRememberMePreference(enabled: boolean, email?: string) {
  if (!import.meta.client) return;
  try {
    if (enabled) {
      localStorage.setItem(REMEMBER_ME_KEY, "1");
      const em = (email || "").trim();
      if (em) localStorage.setItem(REMEMBER_EMAIL_KEY, em);
    } else {
      localStorage.removeItem(REMEMBER_ME_KEY);
      localStorage.removeItem(REMEMBER_EMAIL_KEY);
      clearPersistentSessionTokens();
    }
  } catch {
    /* ignore */
  }
}

function clearPersistentSessionTokens() {
  if (!import.meta.client) return;
  try {
    localStorage.removeItem(PERSIST_KEYS.accessToken);
    localStorage.removeItem(PERSIST_KEYS.refreshToken);
  } catch {
    /* ignore */
  }
}

function clearTabSharedSessionTokens() {
  if (!import.meta.client) return;
  try {
    localStorage.removeItem(TAB_SHARED_KEYS.accessToken);
    localStorage.removeItem(TAB_SHARED_KEYS.refreshToken);
  } catch {
    /* ignore */
  }
}

/** Dipancarkan setelah profil/avatar diperbarui agar header ikut refresh. */
export const WORKPULSE_PROFILE_UPDATED_EVENT = "workpulse:profile-updated";

export function notifyWorkpulseProfileUpdated() {
  if (!import.meta.client) return;
  window.dispatchEvent(new CustomEvent(WORKPULSE_PROFILE_UPDATED_EVENT));
}

export function persistWorkpulseSessionUser(user: {
  id: number;
  role: string;
  email: string;
  name: string;
  avatarUrl?: string | null;
}) {
  if (!import.meta.client) return;
  try {
    sessionStorage.setItem(KEYS.userId, String(user.id));
    sessionStorage.setItem(KEYS.role, user.role);
    sessionStorage.setItem(KEYS.email, user.email);
    sessionStorage.setItem(KEYS.name, user.name);
    const av = (user.avatarUrl ?? "").trim();
    if (av) sessionStorage.setItem(KEYS.avatarUrl, av);
    else sessionStorage.removeItem(KEYS.avatarUrl);
  } catch {
    /* private / disabled storage */
  }
}

/** Simpan JWT di sessionStorage; jika rememberMe, juga di localStorage agar tetap login setelah tutup browser. */
export function persistWorkpulseSessionTokens(
  access: string,
  refresh: string | null,
  options?: { rememberMe?: boolean }
) {
  if (!import.meta.client) return;
  const remember = options?.rememberMe === true;
  try {
    sessionStorage.setItem(KEYS.accessToken, access);
    if (refresh) sessionStorage.setItem(KEYS.refreshToken, refresh);
    else sessionStorage.removeItem(KEYS.refreshToken);

    // Selalu mirror ke localStorage agar tab baru bisa ikut sesi yang sama.
    localStorage.setItem(TAB_SHARED_KEYS.accessToken, access);
    if (refresh) localStorage.setItem(TAB_SHARED_KEYS.refreshToken, refresh);
    else localStorage.removeItem(TAB_SHARED_KEYS.refreshToken);

    if (remember) {
      localStorage.setItem(PERSIST_KEYS.accessToken, access);
      if (refresh) localStorage.setItem(PERSIST_KEYS.refreshToken, refresh);
      else localStorage.removeItem(PERSIST_KEYS.refreshToken);
    } else {
      clearPersistentSessionTokens();
    }
  } catch {
    /* ignore */
  }
}

export function readWorkpulseAccessToken(): string | null {
  if (!import.meta.client) return null;
  try {
    const fromSession = sessionStorage.getItem(KEYS.accessToken);
    if (fromSession) {
      // Backfill mirror agar tab baru bisa langsung pakai token.
      localStorage.setItem(TAB_SHARED_KEYS.accessToken, fromSession);
      return fromSession;
    }
    const fromShared = localStorage.getItem(TAB_SHARED_KEYS.accessToken);
    if (fromShared) return fromShared;
    if (readRememberMePreference()) {
      const fromPersist = localStorage.getItem(PERSIST_KEYS.accessToken);
      if (fromPersist) localStorage.setItem(TAB_SHARED_KEYS.accessToken, fromPersist);
      return fromPersist;
    }
    return null;
  } catch {
    return null;
  }
}

export function readWorkpulseRefreshToken(): string | null {
  if (!import.meta.client) return null;
  try {
    const fromSession = sessionStorage.getItem(KEYS.refreshToken);
    if (fromSession) {
      // Backfill mirror agar tab baru bisa langsung refresh token.
      localStorage.setItem(TAB_SHARED_KEYS.refreshToken, fromSession);
      return fromSession;
    }
    const fromShared = localStorage.getItem(TAB_SHARED_KEYS.refreshToken);
    if (fromShared) return fromShared;
    if (readRememberMePreference()) {
      const fromPersist = localStorage.getItem(PERSIST_KEYS.refreshToken);
      if (fromPersist) localStorage.setItem(TAB_SHARED_KEYS.refreshToken, fromPersist);
      return fromPersist;
    }
    return null;
  } catch {
    return null;
  }
}

export function clearWorkpulseSessionUser() {
  if (!import.meta.client) return;
  try {
    sessionStorage.removeItem(KEYS.userId);
    sessionStorage.removeItem(KEYS.role);
    sessionStorage.removeItem(KEYS.email);
    sessionStorage.removeItem(KEYS.name);
    sessionStorage.removeItem(KEYS.avatarUrl);
    sessionStorage.removeItem(KEYS.accessToken);
    sessionStorage.removeItem(KEYS.refreshToken);
    clearPersistentSessionTokens();
    clearTabSharedSessionTokens();
    clearWorkpulsePermissions();
  } catch {
    /* ignore */
  }
}

export function readWorkpulseSessionRole(): string | null {
  if (!import.meta.client) return null;
  try {
    return sessionStorage.getItem(KEYS.role);
  } catch {
    return null;
  }
}

export function readWorkpulseSessionUserId(): number | null {
  if (!import.meta.client) return null;
  try {
    const raw = sessionStorage.getItem(KEYS.userId);
    if (raw == null || raw === "") return null;
    const n = Number(raw);
    return Number.isFinite(n) ? n : null;
  } catch {
    return null;
  }
}

export function readWorkpulseSessionEmail(): string | null {
  if (!import.meta.client) return null;
  try {
    return sessionStorage.getItem(KEYS.email);
  } catch {
    return null;
  }
}

export function readWorkpulseSessionName(): string | null {
  if (!import.meta.client) return null;
  try {
    return sessionStorage.getItem(KEYS.name);
  } catch {
    return null;
  }
}

export function readWorkpulseSessionAvatarUrl(): string | null {
  if (!import.meta.client) return null;
  try {
    return sessionStorage.getItem(KEYS.avatarUrl);
  } catch {
    return null;
  }
}

const TOKEN_STORAGE_KEYS = new Set<string>([
  KEYS.accessToken,
  KEYS.refreshToken,
  TAB_SHARED_KEYS.accessToken,
  TAB_SHARED_KEYS.refreshToken,
  PERSIST_KEYS.accessToken,
  PERSIST_KEYS.refreshToken
]);

/** Tab lain menulis token baru setelah refresh — sinkronkan tanpa logout paksa. */
export function installWorkpulseTokenStorageSync(onChange: () => void) {
  if (!import.meta.client) return () => {};
  const handler = (e: StorageEvent) => {
    if (!e.key || !TOKEN_STORAGE_KEYS.has(e.key)) return;
    onChange();
  };
  window.addEventListener("storage", handler);
  return () => window.removeEventListener("storage", handler);
}
