import type { ApiUser } from "@/lib/api/types";

export const SESSION_COOKIE = "algobrix_session";
const COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 7;

const LS_SESSION = "algobrix.session";
const LS_EMAIL = "algobrix.email";
const LS_TOKEN = "algobrix.token";
const LS_USER = "algobrix.user";

export type SessionUser = {
  id?: number | string;
  name?: string;
  email?: string;
};

export type SessionPayload = {
  email: string;
  token?: string;
  user?: SessionUser;
};

type RawSessionInput = {
  email: string;
  token?: string;
  user?: ApiUser | SessionUser | null;
};

function normalizeUser(user: ApiUser | SessionUser | null | undefined): SessionUser | undefined {
  if (!user) return undefined;
  const name =
    (user as ApiUser).Name ??
    (user as SessionUser).name ??
    undefined;
  const email =
    (user as ApiUser).Email ??
    (user as SessionUser).email ??
    undefined;
  return {
    id: user.id,
    name: typeof name === "string" ? name : undefined,
    email: typeof email === "string" ? email : undefined,
  };
}

function safeLocalStorage(): Storage | null {
  if (typeof window === "undefined") return null;
  try {
    return window.localStorage;
  } catch {
    return null;
  }
}

export const session = {
  set(payload: RawSessionInput) {
    const normalized: SessionPayload = {
      email: payload.email,
      token: payload.token,
      user: normalizeUser(payload.user),
    };

    if (typeof document !== "undefined") {
      const value = encodeURIComponent(JSON.stringify(normalized));
      document.cookie = `${SESSION_COOKIE}=${value}; path=/; max-age=${COOKIE_MAX_AGE_SECONDS}; SameSite=Lax`;
    }

    const ls = safeLocalStorage();
    if (ls) {
      ls.setItem(LS_SESSION, JSON.stringify(normalized));
      ls.setItem(LS_EMAIL, normalized.email);
      if (normalized.token) ls.setItem(LS_TOKEN, normalized.token);
      if (normalized.user) ls.setItem(LS_USER, JSON.stringify(normalized.user));
    }
  },

  get(): SessionPayload | null {
    const ls = safeLocalStorage();
    if (ls) {
      const raw = ls.getItem(LS_SESSION);
      if (raw) {
        try {
          return JSON.parse(raw) as SessionPayload;
        } catch {
          // fall through to cookie
        }
      }
    }

    if (typeof document === "undefined") return null;
    const match = document.cookie.match(
      new RegExp(`(?:^|; )${SESSION_COOKIE}=([^;]*)`)
    );
    if (!match) return null;
    try {
      return JSON.parse(decodeURIComponent(match[1])) as SessionPayload;
    } catch {
      return null;
    }
  },

  getToken(): string | undefined {
    const ls = safeLocalStorage();
    if (ls) {
      const t = ls.getItem(LS_TOKEN);
      if (t) return t;
    }
    return session.get()?.token;
  },

  getEmail(): string | undefined {
    const ls = safeLocalStorage();
    if (ls) {
      const e = ls.getItem(LS_EMAIL);
      if (e) return e;
    }
    return session.get()?.email;
  },

  clear() {
    if (typeof document !== "undefined") {
      document.cookie = `${SESSION_COOKIE}=; path=/; max-age=0; SameSite=Lax`;
    }
    const ls = safeLocalStorage();
    if (ls) {
      ls.removeItem(LS_SESSION);
      ls.removeItem(LS_EMAIL);
      ls.removeItem(LS_TOKEN);
      ls.removeItem(LS_USER);
    }
  },
};

export function displayNameFor(payload: SessionPayload | null | undefined): string {
  const name = payload?.user?.name?.trim();
  if (name) return name;
  const email = payload?.email || payload?.user?.email || "";
  if (email.includes("@")) return email.split("@")[0];
  return "Backer";
}
