package io.delphiplatform.api.v3.view;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.server.ResponseStatusException;

import java.util.List;
import java.util.Set;

import io.delphiplatform.api.util.OffsetBasedPageRequest;
import io.delphiplatform.api.v3.model.Chart;
import io.delphiplatform.api.v3.model.Charts;
import io.delphiplatform.api.v3.model.SortOrder;
import io.delphiplatform.api.v3.model.shazam.ShazamChart;
import io.delphiplatform.api.v3.model.shazam.ShazamChartPositions;
import io.delphiplatform.api.v3.model.shazam.ShazamChartSummaries;
import io.delphiplatform.api.v3.model.shazam.ShazamChartTrackPosition;
import io.delphiplatform.api.v3.model.shazam.ShazamCity;
import io.delphiplatform.api.v3.model.shazam.ShazamCitySummaries;
import io.delphiplatform.api.v3.model.video.ShazamChartTrackSummaries;
import io.delphiplatform.api.v3.model.video.ShazamChartTrackSummary;
import io.delphiplatform.api.v3.rdb.service.ChartService;
import io.delphiplatform.api.v3.rdb.service.ShazamChartService;
import io.delphiplatform.api.v3.rdb.service.ShazamChartSummaryService;
import io.delphiplatform.api.v3.rdb.service.ShazamChartTrackPositionService;
import io.delphiplatform.api.v3.rdb.service.ShazamCityService;
import io.delphiplatform.api.v3.view.util.Params;

@Controller
@RequestMapping("${spring.data.rest.base-path:/v3}")
public class ChartsApiController implements ChartsApi {

    private static final String YOUTUBE_CHART_ID_PREFIX = "youtube_";

    @Autowired
    private ChartService chartService;

    @Autowired
    private ShazamChartSummaryService shazamChartSummaryService;

    @Autowired
    private ShazamCityService shazamCityService;

    @Autowired
    private ShazamChartService shazamChartService;

    @Autowired
    private ShazamChartTrackPositionService shazamChartTrackPositionService;

    @Override
    public ResponseEntity<Chart> findOne(String chartId) {
        if (!chartId.startsWith(YOUTUBE_CHART_ID_PREFIX)) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Only youtube DSP is supported");
        }

        return ResponseEntity.ok(chartService.findOne(chartId));
    }

    @Override
    public ResponseEntity<Charts> getSearchData(String chartGroup, List<String> dsp, Set<String> countries,
        Integer limit, Integer offset,
        String sortBy, SortOrder sortOrder) {
        List<Chart> charts = chartService
            .find(chartGroup, dsp, countries,
                OffsetBasedPageRequest.ofParamsKeepCase(offset, limit, sortOrder, sortBy));
        return ResponseEntity.ok(new Charts().items(charts).count(charts.size()));
    }

    @Override
    public ResponseEntity<ShazamChartTrackSummaries> getShazamChartsSummarySearch(Params params) {
        List<ShazamChartTrackSummary> summaries = shazamChartSummaryService.getShazamChartTrackSummaries(params);

        return ResponseEntity.ok(new ShazamChartTrackSummaries()
            .count(summaries.size())
            .items(summaries)
        );
    }

    @Override
    public ResponseEntity<ShazamCitySummaries> getShazamCities(Params params) {
        List<ShazamCity> summaries = shazamCityService.getShazamCities(params);

        return ResponseEntity.ok(new ShazamCitySummaries(summaries));
    }

    @Override
    public ResponseEntity<ShazamChartSummaries> getShazamCharts(Params params) {
        List<ShazamChart> summaries = shazamChartService.getShazamCharts(params);

        return ResponseEntity.ok(new ShazamChartSummaries(summaries));
    }

    @Override
    public ResponseEntity<ShazamChartPositions> getShazamChartsTrackPositions(Params params) {
        List<ShazamChartTrackPosition> positions = shazamChartTrackPositionService.getShazamChartTrackPositions(params);
        return ResponseEntity.ok(new ShazamChartPositions()
            .count(positions.size())
            .items(positions)
            .nextCursor(params.getNextCursor())
        );
    }

}
