/*
 *  author: Yagnik Poshiya
 *  organization: Webbrains Technologies Private Limited
 */

/**
 * Rendered size (in CSS px) for animated avatar launchers (GIF/MP4).
 *
 * The value caps the largest rendered dimension on the visitor's website;
 * aspect ratio is preserved by the widget. It only applies to avatar mode —
 * static icons and Lucide icons keep the fixed round button.
 */

export const DEFAULT_WIDGET_AVATAR_SIZE_PX = 180;
export const MIN_WIDGET_AVATAR_SIZE_PX = 48;
export const MAX_WIDGET_AVATAR_SIZE_PX = 512;

/** Returns a clamped integer size, or null when not set / invalid. */
export function normalizeWidgetAvatarSize(raw: unknown): number | null {
  if (raw == null || raw === '') return null;
  const n = Math.round(Number(raw));
  if (!Number.isFinite(n)) return null;
  if (n < MIN_WIDGET_AVATAR_SIZE_PX) return MIN_WIDGET_AVATAR_SIZE_PX;
  if (n > MAX_WIDGET_AVATAR_SIZE_PX) return MAX_WIDGET_AVATAR_SIZE_PX;
  return n;
}

export function ensureWidgetAvatarSize(raw: unknown): number {
  return normalizeWidgetAvatarSize(raw) ?? DEFAULT_WIDGET_AVATAR_SIZE_PX;
}

export function validateWidgetAvatarSize(
  raw: unknown,
): { ok: true; value: number | null } | { ok: false; message: string } {
  if (raw == null || raw === '') return { ok: true, value: null };
  const n = Number(raw);
  if (!Number.isFinite(n)) {
    return { ok: false, message: 'Avatar size must be a number.' };
  }
  const rounded = Math.round(n);
  if (rounded < MIN_WIDGET_AVATAR_SIZE_PX || rounded > MAX_WIDGET_AVATAR_SIZE_PX) {
    return {
      ok: false,
      message: `Avatar size must be between ${MIN_WIDGET_AVATAR_SIZE_PX} and ${MAX_WIDGET_AVATAR_SIZE_PX} px.`,
    };
  }
  return { ok: true, value: rounded };
}

/* ------------------------------------------------------------------ *
 * Per-device sizes (mobile / tablet / desktop)
 *
 * Widget breakpoints: mobile < 768px, tablet 768–1023px, desktop >= 1024px.
 * ------------------------------------------------------------------ */

export const WIDGET_AVATAR_DEVICES = ['mobile', 'tablet', 'desktop'] as const;
export type WidgetAvatarDevice = (typeof WIDGET_AVATAR_DEVICES)[number];

export const WIDGET_AVATAR_DEVICE_LABELS: Record<WidgetAvatarDevice, string> = {
  mobile: 'Mobile',
  tablet: 'Tablet',
  desktop: 'Desktop',
};

export type WidgetAvatarSizeConfig = {
  mobile: number | null;
  tablet: number | null;
  desktop: number | null;
};

/** Per-device sizes with every device resolved to a concrete pixel value. */
export type ResolvedWidgetAvatarSizeConfig = Record<WidgetAvatarDevice, number>;

export function emptyWidgetAvatarSizeConfig(): WidgetAvatarSizeConfig {
  return { mobile: null, tablet: null, desktop: null };
}

export function normalizeWidgetAvatarSizeConfig(raw: unknown): WidgetAvatarSizeConfig {
  const obj = (raw ?? {}) as Record<string, unknown>;
  return {
    mobile: normalizeWidgetAvatarSize(obj.mobile),
    tablet: normalizeWidgetAvatarSize(obj.tablet),
    desktop: normalizeWidgetAvatarSize(obj.desktop),
  };
}

/** Fills any unset device with the shared default (180px). */
export function ensureWidgetAvatarSizeConfig(raw: unknown): ResolvedWidgetAvatarSizeConfig {
  const n = normalizeWidgetAvatarSizeConfig(raw);
  return {
    mobile: n.mobile ?? DEFAULT_WIDGET_AVATAR_SIZE_PX,
    tablet: n.tablet ?? DEFAULT_WIDGET_AVATAR_SIZE_PX,
    desktop: n.desktop ?? DEFAULT_WIDGET_AVATAR_SIZE_PX,
  };
}

export function widgetAvatarSizeConfigEquals(
  a: WidgetAvatarSizeConfig,
  b: WidgetAvatarSizeConfig,
): boolean {
  return WIDGET_AVATAR_DEVICES.every(
    (d) => (a[d] ?? DEFAULT_WIDGET_AVATAR_SIZE_PX) === (b[d] ?? DEFAULT_WIDGET_AVATAR_SIZE_PX),
  );
}

export function validateWidgetAvatarSizeConfig(
  raw: unknown,
): { ok: true; value: WidgetAvatarSizeConfig } | { ok: false; message: string } {
  if (raw == null) return { ok: true, value: emptyWidgetAvatarSizeConfig() };
  if (typeof raw !== 'object') {
    return { ok: false, message: 'Avatar size must be an object of device sizes.' };
  }
  const obj = raw as Record<string, unknown>;
  const out = emptyWidgetAvatarSizeConfig();
  for (const device of WIDGET_AVATAR_DEVICES) {
    const result = validateWidgetAvatarSize(obj[device]);
    if (!result.ok) {
      return { ok: false, message: `${WIDGET_AVATAR_DEVICE_LABELS[device]}: ${result.message}` };
    }
    out[device] = result.value;
  }
  return { ok: true, value: out };
}
