package io.delphiplatform.api.v3.constant;

import java.time.LocalDate;

/**
 * Container for pagination configuration and general application-wide constants
 */
public abstract class ApplicationConstants {

    public static final int DAYS_IN_WEEK = 7;

    public static final String ROW_KEY_SEPARATOR = "~";

    public static final String CLOSES_PREVIOUS_THURSDAY_SQL = "date - ((3 + extract(DOW FROM date)::int) % 7)";

    /**
     * {@code DEFAULT_PAGE_SIZE} applies to Entities
     */
    public static final int DEFAULT_PAGE_SIZE = 5000;
    /**
     * {@code MAX_PAGE_SIZE} applies to Entities
     */
    public static final int MAX_PAGE_SIZE = 5000;

    /**
     * {@code MAX_PAGE_SIZE} applies to Bigtable Entities
     */
    public static final int MAX_BIGTABLE_PAGE_SIZE = 25000;

    /**
     * {@code DEFAULT_PAGE_SIZE} applies to Bigtable Entities
     */
    public static final int DEFAULT_BIGTABLE_PAGE_SIZE = 10000;

    /**
     * {@code DEFAULT_SEARCH_LIMIT} applies to Elasticsearch queries
     */
    public static final int DEFAULT_SEARCH_LIMIT = 10;

    /**
     * {@code DEFAULT_RESPONSE_LIMIT} applies to API responses to limit the total number of {@code items}
     */
    public static final long DEFAULT_RESPONSE_LIMIT = 5000;
    public static final String DEFAULT_RESPONSE_LIMIT_PARAM_VALUE = "5000";

    public static final long MIN_PREMIUM_UGC_VIEWS = 10000;

    /**
     * Min date of streaming data
     */
    public static final LocalDate MIN_STREAMS_DATE = LocalDate.of(2014, 1, 1);

    /**
     * Ads Data
     */
    public static final String DEFAULT_ADS_DATE_CURRENCY = "USD";
    public static final String ADS_UNKNOWN_CURRENCY = "null";

    /**
     * Cursor-based pagination configuration
     */
    public static final String PAGE_CURSOR_PREFIX_DATE = "date:";
    public static final String PAGE_CURSOR_PATTERN = "^(" + PAGE_CURSOR_PREFIX_DATE + ")\\d{4}-\\d{2}-\\d{2}$";
    public static final String PAGE_LIMIT_RANGE_PREFIX_DAYS = "days:";
    public static final String PAGE_LIMIT_RANGE_PATTERN = "^(" + PAGE_LIMIT_RANGE_PREFIX_DAYS + ")[1-9]\\d*$";

    /**
     * Patterns
     */
    public static final String ISRC_PATTERN = "^[A-Z]{2}\\w{3}\\d{2}\\d{5}$";
    public static final String GRAS_ID_PATTERN = "^GRAS_.*$";
    public static final String VIDEO_ID_PATTERN = "^\\w+_.*$";
    public static final String NOT_EMPTY_PATTERN = "^\\S+$";
    public static final String COUNTRY_CODE_PATTERN = "[A-z]{2,}";
    public static final String NO_COMMA_PATTERN = "[^,]+";

    /**
     * Common constants
     */
    public static final String TRACK = "track";
    public static final String CHART = "chart";
    public static final String DEFAULT_SORT_ORDER = "desc";
    public static final String DEFAULT_OFFSET = "0";
    public static final String DEFAULT_TIK_TOK_BREAKDOWN = "daily";

    public static final String SCRIPT_CHECK_DATES_BOTH_PRESENT_OR_NULL = "(startDate != null && endDate != null) || (startDate == null && endDate == null)";
    public static final String SCRIPT_CHECK_DATES = "startDate != null && endDate != null && startDate <= endDate";
    public static final String SCRIPT_CHECK_DATES_NULLABLE = "startDate == null || endDate == null || startDate <= endDate";
    public static final String SCRIPT_PRODUCT_SALE_DATES_IN_ORDER =
        "(minProductSaleDate == null || maxProductSaleDate == null) || minProductSaleDate <= maxProductSaleDate";
    public static final String SCRIPT_CHECK_EITHER_TRACK_ID_OR_ISRC = "!(trackIds && isrc) && (trackIds || isrc)";
    public static final String SCRIPT_CHECK_TRACK_ID_OR_ISRC = "!(trackIds && isrc)";
    public static final String SCRIPT_CHECK_EITHER_TRACK_ID_OR_UPC = "!(trackId && upc) && (trackId || upc)";
    public static final String SCRIPT_CHECK_POSITIONS = "minPosition==null || maxPosition==null || maxPosition > minPosition";
    public static final String SCRIPT_COUNTRY_CODE_SINGLE_WORLDWIDE = "countryCode.size() <= 1 || !countryCode.contains(\"worldwide\")";

    public static final String PREVIOUS_DATE_IS_AFTER_DATE = "previousDate == null || previousDate < date";
    public static final String COMMA = ",";

    /**
     * Error constants
     */
    public static final String ERROR_MESSAGE_START_END_DATES_BOTH_PRESENT_OR_NULL = "start_date / end_date params should be either both set or both not set";
    public static final String ERROR_MESSAGE_START_END_DATES = "The end_date parameter should be greater than the start_date";
    public static final String ERROR_MESSAGE_MIN_MAX_SELL_DATES = "The max_product_sale_date parameter should be greater than the min_product_sale_date";
    public static final String ERROR_MESSAGE_IS_EMPTY = " should not be empty";
    public static final String ERROR_MESSAGE_STATUS_IS_EMPTY = RequestConstants.STATUS + ERROR_MESSAGE_IS_EMPTY;
    public static final String ERROR_MESSAGE = "%s should be at least one from [%s] : unexpected value '%s'";
    public static final String ERROR_MESSAGE_EITHER_TRACK_ID_OR_ISRC = "Please use exactly one of params: track_id, isrc";
    public static final String ERROR_MESSAGE_EITHER_TRACK_ID_OR_UPC = "Please use exactly one of params: track_id, upc";
    public static final String ERROR_MESSAGE_TRACK_ID_OR_ISRC = "Please do not use track_id and isrc at the same time";
    public static final String ADS_SORT_BY_INVALID_ERROR_MESSAGE = "Please specify %s group by param to sort by %s.";
    public static final String ERROR_MESSAGE_MIN_MAX_POSITIONS = "The max_position parameter should be greater than the min_position";
    public static final String ERROR_MESSAGE_ARRAYS_INSTEAD_OF_SINGLE_ELEMENT = "Only single value is accepted.";
    public static final String ERROR_MESSAGE_COUNTRY_CODE_WORLDWIDE_SINGLE_VALUE = "countryCode 'worldwide' must be the only value";

    public static final String ERROR_MESSAGE_PREVIOUS_DATE_IS_AFTER_DATE = "previous date should be less than date";
    public static final String ALLOWED_VALUES_PLACEHOLDER = "allowed_values";
    public static final String ERROR_MESSAGE_SORT_BY_PARAMETER =
        "parameter 'sort_by' must be one of the next values : {" + ALLOWED_VALUES_PLACEHOLDER + "}";

    public static final String ISO_DATE_TIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss";
}
