package io.delphiplatform.api.v3.view.tiktok;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.NativeWebRequest;

import java.time.LocalDate;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;

import javax.validation.constraints.Pattern;

import io.delphiplatform.api.util.CollectionUtils;
import io.delphiplatform.api.v3.constant.ApplicationConstants;
import io.delphiplatform.api.v3.constant.CountryCodeConstant;
import io.delphiplatform.api.v3.model.tiktok.TikTokBreakdown;
import io.delphiplatform.api.v3.model.tiktok.TikTokContentType;
import io.delphiplatform.api.v3.model.tiktok.TikTokMetric;
import io.delphiplatform.api.v3.model.tiktok.TikTokTrackAnalytics;
import io.delphiplatform.api.v3.model.video.ExpandTo;
import io.delphiplatform.api.v3.view.interceptor.OnlyDeclaredParams;
import io.delphiplatform.api.v3.view.util.Params;

@Validated
public interface TikTokApi {

    default Optional<NativeWebRequest> getRequest() {
        return Optional.empty();
    }

    /**
     * GET /tiktok/tracks/analytics : Get Analytics for TikTok tracks Analytics for TikTok tracks by date range. Usually
     * split into beakdowns.
     *
     * @param startDate   The earliest date to include in the query range. Data is start_date inclusive. (required)
     * @param endDate     The latest date to include in the query. Data returned is end_date inclusive. (required)
     * @param isrc        International Standard Recording Code (ISRC) number (optional)
     * @param contentType Content types of TikTok tracks like UGC, PGC (optional, default to new ArrayList&lt;&gt;())
     * @param countryCode Typically a lower-case two letter code for the country (optional, default to new
     *                    ArrayList&lt;&gt;())
     * @param breakdowns  Breakdowns for TikTok Track analytics (optional, default to new ArrayList&lt;&gt;())
     * @return &#x60;TikTokTrackAnalytics&#x60; response object (status code 200) or A &#x60;400 Bad Request&#x60;
     * response status indicates a problem with the input provided by a client request. If you are receiving this error,
     * check your request parameters are valid. (status code 400) or A &#x60;401 Unauthorized&#x60; response status
     * indicates that the request did not include a required Authorization header, or that there was a problem
     * authenticating the client. Possible problems include an expired or invalid token, or the Authorization header is
     * not in the expected format. (status code 401) or A &#x60;500 Internal Error&#x60; response status is returned for
     * any application and server level errors that are not already associated with another error status. A 500 is used
     * as a generic fallback error. (status code 500)
     */
    @OnlyDeclaredParams
    @RequestMapping(value = "/tiktok/tracks/analytics",
        produces = {"application/json"},
        method = RequestMethod.GET)
    default CompletableFuture<ResponseEntity<TikTokTrackAnalytics>> tiktokTrackAnalyticsSearch(
        @RequestParam(value = "start_date") @DateTimeFormat(iso = ISO.DATE) LocalDate startDate,
        @RequestParam(value = "end_date") @DateTimeFormat(iso = ISO.DATE) LocalDate endDate,
        @Pattern(regexp = ApplicationConstants.ISRC_PATTERN) @RequestParam(value = "isrc") String isrc,
        @RequestParam(value = "content_type", required = false) Set<TikTokContentType> contentType,
        @RequestParam(value = "expand_to", required = false) Set<ExpandTo> expandTo,
        @RequestParam(value = "country_code", required = false) Set<String> countryCode,
        @RequestParam(value = "breakdowns", required = false, defaultValue = ApplicationConstants.DEFAULT_TIK_TOK_BREAKDOWN)
            Set<TikTokBreakdown> breakdowns,
        @RequestParam(value = "metrics", required = false) Set<TikTokMetric> metrics) {
        return getTikTokAnalytics(Params.builder()
            .startDate(startDate)
            .endDate(endDate)
            .isrc(CollectionUtils.isEmpty(isrc) ? null : Collections.singletonList(isrc))
            .expandTo(expandTo)
            .tikTokContentTypes(CollectionUtils.isEmpty(contentType) ? Set.of(TikTokContentType.values()) : contentType)
            .countryCode(CollectionUtils.isEmpty(countryCode) ? Set.of(CountryCodeConstant.WORLDWIDE) : countryCode)
            .tikTokBreakdowns(breakdowns)
            .metrics(metrics)
            .build());
    }

    CompletableFuture<ResponseEntity<TikTokTrackAnalytics>> getTikTokAnalytics(Params build);

}
