import * as serverApi from '../../api/api';
import { QueryElem, QueryFor, simplify, toApiQuery } from '../query/Query';
import backendRequest from './request';

export async function queryItems(
    type: serverApi.ResourceType,
    query: QueryElem | undefined,
    offset: number | undefined,
    limit: number | undefined,
    responseType: serverApi.QueryResponseType,
): Promise<serverApi.QueryResponse> {
    const queryForMapping : any = {
        [serverApi.ResourceType.Album]: QueryFor.Albums,
        [serverApi.ResourceType.Artist]: QueryFor.Artists,
        [serverApi.ResourceType.Tag]: QueryFor.Tags,
        [serverApi.ResourceType.Track]: QueryFor.Tracks,
    };

    const simplified = simplify(query || null, queryForMapping[type]);

    var q: serverApi.QueryRequest = {
        query: simplified ? toApiQuery(simplified, queryForMapping[type]) : {},
        offsetsLimits: {
            artistOffset: (type == serverApi.ResourceType.Artist) ? (offset || 0) : undefined,
            artistLimit: (type == serverApi.ResourceType.Artist) ? (limit || -1) : undefined,
            albumOffset: (type == serverApi.ResourceType.Album) ? (offset || 0) : undefined,
            albumLimit: (type == serverApi.ResourceType.Album) ? (limit || -1) : undefined,
            trackOffset: (type == serverApi.ResourceType.Track) ? (offset || 0) : undefined,
            trackLimit: (type == serverApi.ResourceType.Track) ? (limit || -1) : undefined,
            tagOffset: (type == serverApi.ResourceType.Tag) ? (offset || 0) : undefined,
            tagLimit: (type == serverApi.ResourceType.Tag) ? (limit || -1) : undefined,
        },
        ordering: {
            orderBy: {
                type: serverApi.OrderByType.Name,
            },
            ascending: true,
        },
        responseType: responseType,
    };

    const requestOpts = {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(q),
    };

    return (async () => {
        const response = await backendRequest((process.env.REACT_APP_BACKEND || "") + serverApi.QueryEndpoint, requestOpts)
        let json: any = await response.json();
        return json;
    })();
}

export async function queryArtists(
    query: QueryElem | undefined,
    offset: number | undefined,
    limit: number | undefined,
    responseType: serverApi.QueryResponseType,
): Promise<serverApi.QueryResponseArtistDetails[] | number[] | number> {
    let r = await queryItems(serverApi.ResourceType.Artist, query, offset, limit, responseType);
    return r.artists;
}

export async function queryAlbums(
    query: QueryElem | undefined,
    offset: number | undefined,
    limit: number | undefined,
    responseType: serverApi.QueryResponseType,
): Promise<serverApi.QueryResponseAlbumDetails[] | number[] | number> {
    let r = await queryItems(serverApi.ResourceType.Album, query, offset, limit, responseType);
    return r.albums;
}

export async function queryTracks(
    query: QueryElem | undefined,
    offset: number | undefined,
    limit: number | undefined,
    responseType: serverApi.QueryResponseType,
): Promise<serverApi.QueryResponseTrackDetails[] | number[] | number> {
    let r = await queryItems(serverApi.ResourceType.Track, query, offset, limit, responseType);
    return r.tracks;
}

export async function queryTags(
    query: QueryElem | undefined,
    offset: number | undefined,
    limit: number | undefined,
    responseType: serverApi.QueryResponseType,
): Promise<serverApi.QueryResponseTagDetails[] | number[] | number> {
    let r = await queryItems(serverApi.ResourceType.Tag, query, offset, limit, responseType);
    return r.tags;
}