import type { LoginStatus } from "@/data/dto/auth";
import type { UserView } from "@/data/dto/user";

export type SidebarUserState = "guest" | "member" | "vip";

export const SIDEBAR_FALLBACK_USERNAME = "User name";

export interface SidebarUserInput {
  currentUser: UserView | null;
  avatarUrl: string | null;
  creditBalance?: number | null;
}

export interface SidebarWalletView {
  creditBalance: number;
  dailyFreeChatLimit: number;
  dailyFreeChatRemaining: number;
  dailyFreePrivateLimit: number;
  dailyFreePrivateRemaining: number;
}

export interface SidebarViewModel {
  state: SidebarUserState;
  name: string;
  avatarUrl: string | null;
  isInitializingUser: boolean;
  wallet: SidebarWalletView;
  canActivateVip: boolean;
  canShowSettings: boolean;
}

export function getSidebarViewModel({
  loginStatus,
  user,
}: {
  loginStatus: LoginStatus;
  user: SidebarUserInput;
}): SidebarViewModel {
  const state = getSidebarUserState(loginStatus, user.currentUser);

  return {
    state,
    name: user.currentUser?.username ?? SIDEBAR_FALLBACK_USERNAME,
    avatarUrl: user.avatarUrl,
    isInitializingUser: state !== "guest" && user.currentUser == null,
    wallet: getSidebarWalletView(user),
    canActivateVip: state !== "vip",
    canShowSettings: state !== "guest",
  };
}

export function getSidebarUserState(
  loginStatus: LoginStatus,
  currentUser: UserView | null,
): SidebarUserState {
  if (loginStatus === "notLoggedIn") return "guest";
  return currentUser?.isVip === true ? "vip" : "member";
}

export function getSidebarWalletView(
  user: SidebarUserInput,
): SidebarWalletView {
  const currentUser = user.currentUser;

  return {
    creditBalance: normalizeSidebarCount(user.creditBalance),
    dailyFreeChatLimit: normalizeSidebarCount(currentUser?.dailyFreeChatLimit),
    dailyFreeChatRemaining: normalizeSidebarCount(
      currentUser?.dailyFreeChatRemaining,
    ),
    dailyFreePrivateLimit: normalizeSidebarCount(
      currentUser?.dailyFreePrivateLimit,
    ),
    dailyFreePrivateRemaining: normalizeSidebarCount(
      currentUser?.dailyFreePrivateRemaining,
    ),
  };
}

export function normalizeSidebarCount(value: number | null | undefined): number {
  if (typeof value !== "number" || !Number.isFinite(value)) return 0;
  return Math.max(0, Math.trunc(value));
}
