package com.vaessl.app.search;

import java.util.List;
import java.util.Map;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClient;

import com.vaessl.app.connection.ConnectionEntity;
import com.vaessl.app.connection.ConnectionRepository;
import com.vaessl.app.connection.HomeboxEntity;
import com.vaessl.app.exception.ConnectionNotFoundException;
import com.vaessl.app.exception.RemoteApiException;

import static com.vaessl.app.connection.Endpoint.*;

@Component
public class HomeboxSearchProvider implements SearchProvider {

    private final RestClient.Builder restClientBuilder;

    private final ConnectionRepository cRepository;

    public HomeboxSearchProvider(RestClient.Builder restClientBuilder,
            ConnectionRepository cRepository) {
        this.restClientBuilder = restClientBuilder;
        this.cRepository = cRepository;
    }

    @Override
    public String getServiceType() {
        return "HOMEBOX";
    }

    @Override
    public Page<SearchResponse> getSearchResults(SearchRequest request, Pageable pageable) {

        ConnectionEntity entity =
                cRepository.findByAppUrlAndUsername(request.appUrl(), request.username());

        if (!(entity instanceof HomeboxEntity hbEntity)) {
            throw new ConnectionNotFoundException();
        }

        HomeboxSearchResponse hbResponse = restClientBuilder.baseUrl(request.appUrl()).build().get()
                .uri(u -> u.path(HOMEBOX_QUERY_ALL_ITEMS.getValue())
                        .queryParam("q", request.query())
                        .queryParam("page", pageable.getPageNumber() + 1)
                        .queryParam("pageSize", pageable.getPageSize()).build())
                .headers(h -> h.setBearerAuth(
                        hbEntity.getToken())).retrieve().body(HomeboxSearchResponse.class);

        if (hbResponse == null) {
            throw new RemoteApiException(request.appUrl());
        }

        List<SearchResponse> items = hbResponse.items().stream().map(i -> {
            String title = i.name();
            String description = i.description();
            Map<String, Object> extraSearchResponseData = Map.of("location", i.location());
            return new SearchResponse(title, description, extraSearchResponseData);
        }).toList();

        return new PageImpl<>(items, pageable, hbResponse.total());
    }

    private record HomeboxSearchResponse(int page, int pageSize, int total,
            List<HomeboxItem> items) {
    }

    private record HomeboxItem(String name, String description, HomeboxLocation location) {
    }

    private record HomeboxLocation(String name, String description) {
    }
}
