import md5 from 'md5';
import { coverStorageKey, coverStorageKeyFromRef } from '../cover/storageKeys';
import { coverEntryToRef, resolveAlbumCoverEntry } from '../cover/resolveEntry';
import type { CoverArtTier } from '../cover/types';
import { useAuthStore } from '../store/authStore';
import { connectBaseUrlForServer } from '../utils/server/serverEndpoint';
import { findServerByIdOrIndexKey } from '../utils/server/serverLookup';
import { restBaseFromUrl, SUBSONIC_CLIENT, secureRandomSalt } from './subsonicClient';

function coverArtQueryParams(username: string, password: string, id: string, size: number): URLSearchParams {
  const salt = secureRandomSalt();
  const token = md5(password + salt);
  return new URLSearchParams({
    id,
    size: String(size),
    u: username,
    t: token,
    s: salt,
    v: '1.16.1',
    c: SUBSONIC_CLIENT,
    f: 'json',
  });
}

function streamUrlFromProfile(
  serverUrl: string,
  username: string,
  password: string,
  id: string,
): string {
  const baseUrl = restBaseFromUrl(serverUrl);
  const salt = secureRandomSalt();
  const token = md5(password + salt);
  const p = new URLSearchParams({
    id,
    u: username,
    t: token,
    s: salt,
    v: '1.16.1',
    c: SUBSONIC_CLIENT,
    f: 'json',
  });
  return `${baseUrl}/stream.view?${p.toString()}`;
}

export function buildStreamUrlForServer(serverId: string, id: string): string {
  const server = findServerByIdOrIndexKey(serverId);
  if (!server) return buildStreamUrl(id);
  // Dual-address: route the stream through the cached connect endpoint.
  return streamUrlFromProfile(connectBaseUrlForServer(server), server.username, server.password, id);
}

export function buildStreamUrl(id: string): string {
  const { getBaseUrl, getActiveServer } = useAuthStore.getState();
  const server = getActiveServer();
  const baseUrl = getBaseUrl();
  if (!server || !baseUrl) return streamUrlFromProfile('', '', '', id);
  // `getBaseUrl()` already returns the cached connect URL; use it directly
  // instead of re-normalizing `server.url`, which would bypass the dual-
  // address connect cache.
  return streamUrlFromProfile(baseUrl, server.username, server.password, id);
}

/** @deprecated Use `coverStorageKey` from `src/cover/storageKeys` — shim until migration. */
export function coverArtCacheKey(id: string, size = 256): string {
  const entry = resolveAlbumCoverEntry(id, id);
  const ref = coverEntryToRef(entry ?? { cacheKind: 'album', cacheEntityId: id, fetchCoverArtId: id });
  return coverStorageKeyFromRef(ref, size as CoverArtTier);
}

/** @deprecated Use `coverStorageKey` from `src/cover/storageKeys` — shim until migration. */
export function coverArtCacheKeyForServer(serverIdOrKey: string, id: string, size = 256): string {
  const server = findServerByIdOrIndexKey(serverIdOrKey);
  if (!server) return `${serverIdOrKey}:cover:album:${id}:${size}`;
  const entry = resolveAlbumCoverEntry(id, id);
  const ref = coverEntryToRef(
    entry ?? { cacheKind: 'album', cacheEntityId: id, fetchCoverArtId: id },
    {
      kind: 'server',
      serverId: server.id,
      url: server.url,
      username: server.username,
      password: server.password,
    },
  );
  return coverStorageKeyFromRef(ref, size as CoverArtTier);
}

/** @deprecated Use `buildCoverArtFetchUrl` from `src/cover/fetchUrl` — shim until migration. */
export function buildCoverArtUrl(id: string, size = 256): string {
  const { getBaseUrl, getActiveServer } = useAuthStore.getState();
  const server = getActiveServer();
  const baseUrl = getBaseUrl();
  const p = coverArtQueryParams(server?.username ?? '', server?.password ?? '', id, size);
  return `${baseUrl}/rest/getCoverArt.view?${p.toString()}`;
}

/** @deprecated Use `buildCoverArtFetchUrl` from `src/cover/fetchUrl` — shim until migration. */
export function buildCoverArtUrlForServer(
  serverUrl: string,
  username: string,
  password: string,
  id: string,
  size = 256,
): string {
  const p = coverArtQueryParams(username, password, id, size);
  return `${restBaseFromUrl(serverUrl)}/getCoverArt.view?${p.toString()}`;
}

export function buildDownloadUrl(id: string): string {
  const { getBaseUrl, getActiveServer } = useAuthStore.getState();
  const server = getActiveServer();
  const baseUrl = getBaseUrl();
  const salt = secureRandomSalt();
  const token = md5((server?.password ?? '') + salt);
  const p = new URLSearchParams({
    id,
    u: server?.username ?? '',
    t: token, s: salt, v: '1.16.1', c: SUBSONIC_CLIENT, f: 'json',
  });
  return `${baseUrl}/rest/download.view?${p.toString()}`;
}
