import {
  getAcademicMode,
  getAcademicYearId,
  getAcademicYears,
  setAcademicContext,
  type AcademicContextState,
} from "./academic-context";

const ROLE_KEY = "admin_active_role";
const BRANCH_KEY = "admin_active_branch_id";
const ASSIGNMENT_KEY = "admin_active_assignment_id";
const READY_KEY = "admin_session_ready";
const PERMS_KEY = "admin_active_permissions";
const IMPERSONATOR_TOKEN_KEY = "admin_impersonator_token";
const IMPERSONATOR_USER_KEY = "admin_impersonator_user";
const IMPERSONATOR_SNAPSHOT_KEY = "admin_impersonator_snapshot";

export interface RoleAssignment {
  id: number;
  role_id: number;
  role_name: string;
  role_label: string;
  branch_id: number | null;
  branch_name: string | null;
  branch_code: string | null;
}

export interface SessionContextState {
  active_role: string;
  active_role_label: string;
  active_branch_id: number | null;
  active_branch_name: string | null;
  active_academic_year_id: number;
  assignment_id: number | null;
  permissions: string[];
}

export function getActiveRole(): string | null {
  if (typeof window === "undefined") return null;
  return localStorage.getItem(ROLE_KEY);
}

export function getActiveRoleLabel(): string | null {
  if (typeof window === "undefined") return null;
  return localStorage.getItem("admin_active_role_label");
}

export function getActiveBranchId(): number | null {
  if (typeof window === "undefined") return null;
  const raw = localStorage.getItem(BRANCH_KEY);
  return raw ? Number(raw) : null;
}

export function getActiveAssignmentId(): number | null {
  if (typeof window === "undefined") return null;
  const raw = localStorage.getItem(ASSIGNMENT_KEY);
  return raw ? Number(raw) : null;
}

export function isSessionReady(): boolean {
  if (typeof window === "undefined") return false;
  return localStorage.getItem(READY_KEY) === "1";
}

export function getActivePermissions(): string[] {
  if (typeof window === "undefined") return [];
  const raw = localStorage.getItem(PERMS_KEY);
  if (!raw) return [];
  try {
    return JSON.parse(raw) as string[];
  } catch {
    return [];
  }
}

export const SESSION_CHANGED_EVENT = "school-session-changed";

export function notifySessionChanged() {
  if (typeof window === "undefined") return;
  window.dispatchEvent(new Event(SESSION_CHANGED_EVENT));
}

export function setSessionContext(ctx: SessionContextState) {
  localStorage.setItem(ROLE_KEY, ctx.active_role);
  localStorage.setItem("admin_active_role_label", ctx.active_role_label);
  localStorage.setItem(BRANCH_KEY, ctx.active_branch_id ? String(ctx.active_branch_id) : "");
  localStorage.setItem(ASSIGNMENT_KEY, ctx.assignment_id ? String(ctx.assignment_id) : "");
  localStorage.setItem(PERMS_KEY, JSON.stringify(ctx.permissions));
  localStorage.setItem(READY_KEY, "1");
  notifySessionChanged();
}

export function clearSessionContext() {
  localStorage.removeItem(ROLE_KEY);
  localStorage.removeItem("admin_active_role_label");
  localStorage.removeItem(BRANCH_KEY);
  localStorage.removeItem(ASSIGNMENT_KEY);
  localStorage.removeItem(PERMS_KEY);
  localStorage.removeItem(READY_KEY);
}

export type ImpersonationBackup = {
  token: string;
  user: unknown;
  session?: SessionContextState;
  academic?: AcademicContextState;
};

export function isImpersonating(): boolean {
  const backup = getImpersonationBackup();
  if (!backup?.token) return false;
  if (typeof window === "undefined") return false;
  const current = localStorage.getItem("admin_token");
  return Boolean(current && current !== backup.token);
}

export function setImpersonationBackup(token: string, user: unknown) {
  if (typeof window === "undefined") return;
  if (getImpersonationBackup()) return;

  const snapshot: ImpersonationBackup = {
    token,
    user,
    session: isSessionReady()
      ? {
          active_role: getActiveRole() ?? "",
          active_role_label: getActiveRoleLabel() ?? "",
          active_branch_id: getActiveBranchId(),
          active_branch_name: null,
          active_academic_year_id: getAcademicYearId() ?? 0,
          assignment_id: getActiveAssignmentId(),
          permissions: getActivePermissions(),
        }
      : undefined,
    academic: {
      active_academic_year_id: getAcademicYearId(),
      academic_years: getAcademicYears(),
      mode: getAcademicMode(),
    },
  };

  localStorage.setItem(IMPERSONATOR_SNAPSHOT_KEY, JSON.stringify(snapshot));
  localStorage.setItem(IMPERSONATOR_TOKEN_KEY, token);
  localStorage.setItem(IMPERSONATOR_USER_KEY, JSON.stringify(user));
}

export function getImpersonationBackup(): ImpersonationBackup | null {
  if (typeof window === "undefined") return null;

  const snapshotRaw = localStorage.getItem(IMPERSONATOR_SNAPSHOT_KEY);
  if (snapshotRaw) {
    try {
      const parsed = JSON.parse(snapshotRaw) as ImpersonationBackup;
      if (parsed?.token) return parsed;
    } catch {
      // fall through to legacy keys
    }
  }

  const token = localStorage.getItem(IMPERSONATOR_TOKEN_KEY);
  const raw = localStorage.getItem(IMPERSONATOR_USER_KEY);
  if (!token || !raw) return null;
  try {
    return { token, user: JSON.parse(raw) };
  } catch {
    return null;
  }
}

export function restoreImpersonationBackup(): boolean {
  if (typeof window === "undefined") return false;
  const backup = getImpersonationBackup();
  if (!backup) return false;

  localStorage.setItem("admin_token", backup.token);
  localStorage.setItem("admin_user", JSON.stringify(backup.user));

  if (backup.session) {
    setSessionContext(backup.session);
  }

  if (backup.academic) {
    setAcademicContext(backup.academic);
  }

  clearImpersonationBackup();
  notifySessionChanged();
  return true;
}

export function clearImpersonationBackup() {
  if (typeof window === "undefined") return;
  localStorage.removeItem(IMPERSONATOR_SNAPSHOT_KEY);
  localStorage.removeItem(IMPERSONATOR_TOKEN_KEY);
  localStorage.removeItem(IMPERSONATOR_USER_KEY);
}

export function clearAllSessionStorage() {
  clearSessionContext();
  clearImpersonationBackup();
  notifySessionChanged();
}
