/**
 * One namespace for every "get a sized chat image URL" call.
 *
 * Replaces what used to be three pseudo-hooks (`useAvatarFile`,
 * `useImageThumbnail`, `useProgressiveImage`) and one free function
 * (`withImageSize`). None of them did any React-stateful work — they
 * were all pure URL transforms, so they don't need to live behind the
 * `use*` discipline.
 *
 * All methods return `string` except `progressive`, which returns the
 * two-variant tuple that `<ProgressiveImage>` needs. ExpoImage owns
 * the actual fetch + memory/disk cache + retry behind these URLs;
 * different sizes produce different URLs so they land on different
 * cache entries automatically.
 */
import {AvatarSize} from '@components';
import {DPR} from '@modules/chats/constants';

import {avatarSizeToPixels} from './avatar';

const addSize = (url: string | null | undefined, width?: number): string => {
  if (!url) return '';
  if (!width) return url;
  // Local `file://` URIs (still-on-disk uploads) don't take CDN size
  // hints — pass them through untouched.
  if (!url.startsWith('http')) return url;
  const sep = url.includes('?') ? '&' : '?';
  return `${url}${sep}width=${width}`;
};

interface AvatarOptions {
  /**
   * Match the `<Avatar size={…}>` so the requested server variant lines
   * up. The avatar's enum-display dp is multiplied by `PixelRatio.get()`
   * so the fetched pixel count matches what the device actually renders.
   */
  avatarSize?: AvatarSize;
  /**
   * Explicit pixel-width override — already in physical pixels, no
   * DPR multiplication applied. Takes precedence over `avatarSize`.
   * Use this for screens where the rendered avatar is bigger than any
   * `AvatarSize` enum value (group info screen at ~400 px, for example).
   */
  width?: number;
  /** When `false`, returns `''` so the caller can short-circuit. */
  enabled?: boolean;
}

const avatar = (
  url: string | null | undefined,
  {avatarSize, width, enabled = true}: AvatarOptions = {},
): string => {
  if (!enabled) return '';
  const resolvedWidth =
    width ??
    (avatarSize !== undefined
      ? Math.round((avatarSizeToPixels(avatarSize) ?? 0) * DPR)
      : undefined);
  return addSize(url, resolvedWidth);
};

interface ThumbnailOptions {
  /** Optional `?width=N` hint. Omit for the original size. */
  width?: number;
  enabled?: boolean;
}

const thumbnail = (
  url: string | null | undefined,
  {width, enabled = true}: ThumbnailOptions = {},
): string => {
  if (!enabled) return '';
  return addSize(url, width);
};

interface ProgressiveParams {
  url?: string | null;
  /** Always-fetched placeholder variant width. */
  smallWidth: number;
  /**
   * Larger variant.
   * - `number`: request `?width=N` from the server.
   * - `'original'`: request the unsized URL (full original file). The
   *   gallery viewer uses this for full-resolution images.
   * - `undefined`: skip the upgrade pass — small is the only variant.
   */
  largeWidth?: number | 'original';
  enabled?: boolean;
}

interface ProgressiveResult {
  smallUrl: string;
  largeUrl: string;
}

const progressive = ({
  url,
  smallWidth,
  largeWidth,
  enabled = true,
}: ProgressiveParams): ProgressiveResult => {
  if (!enabled || !url) {
    return {smallUrl: '', largeUrl: ''};
  }
  const smallUrl = addSize(url, smallWidth);
  const largeUrl =
    largeWidth === undefined
      ? ''
      : largeWidth === 'original'
      ? url
      : addSize(url, largeWidth);
  return {smallUrl, largeUrl};
};

export const getChatImage = {
  addSize,
  avatar,
  thumbnail,
  progressive,
};
