package io.delphiplatform.api.v3.view;

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

import java.util.ArrayList;
import java.util.List;

import io.delphiplatform.api.util.CollectionUtils;
import io.delphiplatform.api.v3.model.apple.music.AppleMusicChartTrackStates;
import io.delphiplatform.api.v3.model.apple.music.AppleMusicCharts;
import io.delphiplatform.api.v3.model.apple.music.AppleMusicTrackChartsSearchResult;
import io.delphiplatform.api.v3.model.apple.music.AppleMusicTrackChartsSearchResults;
import io.delphiplatform.api.v3.model.charts.ChartTrackState;
import io.delphiplatform.api.v3.model.charts.ChartTracksAnalyticsResults;
import io.delphiplatform.api.v3.model.datahealth.AppleDataHealthStatusSummary;
import io.delphiplatform.api.v3.model.datahealth.ChartsDataHealthStatusReport;
import io.delphiplatform.api.v3.model.spotify.ChartTrackMetricsDimension;
import io.delphiplatform.api.v3.rdb.service.apple.music.AppleMusicChartService;
import io.delphiplatform.api.v3.rdb.service.apple.music.AppleMusicChartTrackAnalyticsService;
import io.delphiplatform.api.v3.rdb.service.apple.music.AppleMusicChartTrackChangesService;
import io.delphiplatform.api.v3.rdb.service.apple.music.AppleMusicChartTrackStateService;
import io.delphiplatform.api.v3.rdb.service.apple.music.AppleMusicChartsDataHealthStatusService;
import io.delphiplatform.api.v3.rdb.service.apple.music.AppleMusicTrackService;
import io.delphiplatform.api.v3.rdb.service.apple.music.AppleMusicTracksChartsChangesService;
import io.delphiplatform.api.v3.rdb.service.apple.music.AppleMusicTracksChartsService;
import io.delphiplatform.api.v3.view.util.Params;

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

    @Autowired
    private AppleMusicChartService chartService;

    @Autowired
    private AppleMusicTrackService trackService;

    @Autowired
    private AppleMusicChartTrackAnalyticsService chartTrackAnalyticsService;

    @Autowired
    private AppleMusicChartTrackStateService appleMusicChartTrackStateService;

    @Autowired
    private AppleMusicTracksChartsService tracksChartsService;

    @Autowired
    private AppleMusicTracksChartsChangesService tracksChartsChangesService;

    @Autowired
    private AppleMusicChartTrackChangesService chartTrackChangesService;

    @Autowired
    private AppleMusicChartsDataHealthStatusService dataHealthStatusService;

    @Override
    public ResponseEntity<AppleMusicCharts> getAppleMusicCharts(Params params) {
        return ResponseEntity.ok(new AppleMusicCharts(chartService.getAppleMusicCharts(params)));
    }

    @Override
    public ResponseEntity<AppleMusicChartTrackStates> getAppleMusicChartTracks(Params params) {
        List<ChartTrackState> chartTrackStates =
            appleMusicChartTrackStateService.getAppleMusicChartTracks(addTrackIdsForIsrc(params));

        return ResponseEntity.ok(new AppleMusicChartTrackStates(chartTrackStates));
    }

    @Override
    public ResponseEntity<AppleMusicChartTrackStates> getAppleMusicChartsTracksAdditions(Params params) {
        return ResponseEntity
            .ok(new AppleMusicChartTrackStates(chartTrackChangesService.getAppleMusicChartTracksAdditions(addTrackIdsForIsrc(params))));
    }

    @Override
    public ResponseEntity<AppleMusicChartTrackStates> getAppleMusicChartsTracksRemovals(Params params) {
        return ResponseEntity
            .ok(new AppleMusicChartTrackStates(chartTrackChangesService.getAppleMusicChartTracksRemovals(addTrackIdsForIsrc(params))));
    }

    @Override
    public ResponseEntity<AppleMusicTrackChartsSearchResults> getAppleMusicTracksCharts(Params params) {
        List<AppleMusicTrackChartsSearchResult> trackChartsSearchResults =
            tracksChartsService.getTrackCharts(addTrackIdsForIsrc(params));
        return ResponseEntity.ok(new AppleMusicTrackChartsSearchResults(trackChartsSearchResults));
    }

    @Override
    public ResponseEntity<AppleMusicTrackChartsSearchResults> getAppleMusicTracksChartsAdditions(Params params) {
        List<AppleMusicTrackChartsSearchResult> trackChartsSearchResults =
            tracksChartsChangesService.getAdditions(addTrackIdsForIsrc(params));
        return ResponseEntity.ok(new AppleMusicTrackChartsSearchResults(trackChartsSearchResults));
    }

    @Override
    public ResponseEntity<AppleMusicTrackChartsSearchResults> getAppleMusicTracksChartsRemovals(Params params) {
        List<AppleMusicTrackChartsSearchResult> trackChartsSearchResults =
            tracksChartsChangesService.getRemovals(addTrackIdsForIsrc(params));
        return ResponseEntity.ok(new AppleMusicTrackChartsSearchResults(trackChartsSearchResults));
    }

    @Override
    public ResponseEntity<AppleMusicTrackChartsSearchResults> getAppleMusicTracksChartsLifetime(Params params) {
        return ResponseEntity.ok(
            new AppleMusicTrackChartsSearchResults(
                tracksChartsService.getAppleMusicTracksChartsLifetime(addTrackIdsForIsrc(params))));
    }

    @Override
    public ResponseEntity<ChartTracksAnalyticsResults> getAppleMusicChartsTracksAnalytics(Params params) {
        return ResponseEntity.ok(
            new ChartTracksAnalyticsResults(chartTrackAnalyticsService.getAppleMusicChartTracksAnalytics(params))
        );
    }

    @Override
    public ResponseEntity<ChartsDataHealthStatusReport<AppleDataHealthStatusSummary>> getAppleMusicChartsDataHealthStatus(Params params) {
        return ResponseEntity.ok(dataHealthStatusService.getAppleMusicChartsDataHealthStatus(params));
    }

    private Params addTrackIdsForIsrc(Params params) {
        if (
            params.getChartTrackMetricsDimension() != null
                && params.getChartTrackMetricsDimension() == ChartTrackMetricsDimension.ISRC
                && CollectionUtils.isEmpty(params.getIsrc())
                && CollectionUtils.isNotEmpty(params.getTrackId())) {
            return params.toBuilder()
                .trackId(new ArrayList<>(trackService.findTracksWithSameIsrcByTrackId(params.getTrackId())))
                .build();
        }
        return params;
    }
}
