/**
 * FE-API-008: Unified search service for tracks, users, and playlists
 * This service provides a centralized interface for all search operations
 */

import { searchTracks } from '@/features/tracks/services/trackSearchService';
import { playlistsApi } from '@/services/api/playlists';
import { searchUsers } from './searchService';
import { logger } from '@/utils/logger';
import type {
  TrackSearchParams,
  TrackSearchResponse,
} from '@/features/tracks/services/trackSearchService';
import type {
  SearchPlaylistsParams,
  PlaylistListResponse,
} from '@/services/api/playlists';
import type { SearchUsersParams, SearchUsersResponse } from './searchService';

export interface UnifiedSearchParams {
  query: string;
  types?: ('tracks' | 'playlists' | 'users')[];
  page?: number;
  limit?: number;
}

export interface UnifiedSearchResponse {
  tracks?: {
    data: TrackSearchResponse['tracks'];
    total: number;
    page: number;
    limit: number;
  };
  playlists?: {
    data: PlaylistListResponse['playlists'];
    total: number;
    page: number;
    limit: number;
  };
  users?: {
    data: SearchUsersResponse['users'];
    total: number;
    page: number;
    limit: number;
  };
}

/**
 * Unified search across tracks, playlists, and users
 * @param params Search parameters
 * @returns Combined search results
 */
export async function unifiedSearch(
  params: UnifiedSearchParams,
): Promise<UnifiedSearchResponse> {
  const {
    query,
    types = ['tracks', 'playlists', 'users'],
    page = 1,
    limit = 20,
  } = params;

  const results: UnifiedSearchResponse = {};

  // Execute searches in parallel for better performance
  const searchPromises: Promise<void>[] = [];

  if (types.includes('tracks')) {
    searchPromises.push(
      searchTracks({
        query,
        page,
        limit,
      } as TrackSearchParams)
        .then((response) => {
          results.tracks = {
            data: response.tracks,
            total: response.pagination.total,
            page: response.pagination.page,
            limit: response.pagination.limit,
          };
        })
        .catch((error) => {
          logger.error('Error searching tracks', {
            error: error instanceof Error ? error.message : String(error),
            stack: error instanceof Error ? error.stack : undefined,
            query,
          });
          // Continue with other searches even if one fails
        }),
    );
  }

  if (types.includes('playlists')) {
    searchPromises.push(
      playlistsApi.search({
        q: query,
        page,
        limit,
      } as SearchPlaylistsParams)
        .then((response) => {
          results.playlists = {
            data: response.playlists,
            total: response.total,
            page: response.page,
            limit: response.limit,
          };
        })
        .catch((error) => {
          logger.error('Error searching playlists', {
            error: error instanceof Error ? error.message : String(error),
            stack: error instanceof Error ? error.stack : undefined,
            query,
          });
          // Continue with other searches even if one fails
        }),
    );
  }

  if (types.includes('users')) {
    searchPromises.push(
      searchUsers({
        query,
        page,
        limit,
      } as SearchUsersParams)
        .then((response) => {
          results.users = {
            data: response.users,
            total: response.total,
            page: response.page || page,
            limit: response.limit || limit,
          };
        })
        .catch((error) => {
          logger.error('Error searching users', {
            error: error instanceof Error ? error.message : String(error),
            stack: error instanceof Error ? error.stack : undefined,
            query,
          });
          // Continue with other searches even if one fails
        }),
    );
  }

  // Wait for all searches to complete
  await Promise.allSettled(searchPromises);

  return results;
}

/**
 * Search tracks only
 * @param params Search parameters
 * @returns Track search results
 */
export async function searchTracksOnly(
  params: TrackSearchParams,
): Promise<TrackSearchResponse> {
  return searchTracks(params);
}

/**
 * Search playlists only
 * @param params Search parameters
 * @returns Playlist search results
 */
export async function searchPlaylistsOnly(
  params: SearchPlaylistsParams,
): Promise<PlaylistListResponse> {
  return playlistsApi.search(params);
}

/**
 * Search users only
 * @param params Search parameters
 * @returns User search results
 */
export async function searchUsersOnly(
  params: SearchUsersParams,
): Promise<SearchUsersResponse> {
  return searchUsers(params);
}

/**
 * Get search suggestions for autocomplete
 * @param query Search query
 * @param limit Maximum number of suggestions per type
 * @returns Search suggestions
 */
export async function getSearchSuggestions(
  query: string,
  limit: number = 5,
): Promise<UnifiedSearchResponse> {
  return unifiedSearch({
    query,
    types: ['tracks', 'playlists', 'users'],
    page: 1,
    limit,
  });
}
