package ru.yandex.direct.web.entity.uac.model

import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.databind.PropertyNamingStrategy
import com.fasterxml.jackson.databind.annotation.JsonNaming
import ru.yandex.direct.core.entity.campaign.model.CampaignSource
import ru.yandex.direct.core.entity.uac.model.AdvType
import ru.yandex.direct.core.entity.uac.model.DeviceType
import ru.yandex.direct.core.entity.uac.model.InventoryType
import ru.yandex.direct.core.entity.uac.model.LimitPeriodType
import ru.yandex.direct.core.entity.uac.model.AltAppStore
import ru.yandex.direct.core.entity.uac.model.Sitelink
import ru.yandex.direct.core.entity.uac.model.Socdem
import ru.yandex.direct.core.entity.uac.model.TargetType
import ru.yandex.direct.core.entity.uac.model.TimeTarget
import ru.yandex.direct.core.entity.uac.model.UacAdjustmentRequest
import ru.yandex.direct.core.entity.uac.model.UacFeedFilter
import ru.yandex.direct.core.entity.uac.model.UacGoal
import ru.yandex.direct.core.entity.uac.model.UacRetargetingCondition
import ru.yandex.direct.core.entity.uac.model.UacShowsFrequencyLimit
import ru.yandex.direct.core.entity.uac.model.UacStrategy
import ru.yandex.direct.core.entity.uac.model.UacStrategyPlatform
import ru.yandex.direct.core.entity.uac.model.relevance_match.UacRelevanceMatch
import ru.yandex.direct.core.entity.uac.repository.ydb.model.UacBrandsafety
import ru.yandex.direct.core.entity.uac.repository.ydb.model.UacCampaignMeasurer
import ru.yandex.direct.core.entity.uac.repository.ydb.model.UacCpmAsset
import ru.yandex.direct.core.entity.uac.repository.ydb.model.UacDisabledPlaces
import ru.yandex.direct.core.entity.uac.repository.ydb.model.UacSearchLift
import ru.yandex.direct.web.entity.uac.calculateCampaignSource
import java.math.BigDecimal

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy::class)
data class CreateCampaignRequest(
    val displayName: String,
    val href: String,
    val appId: String?,
    val texts: List<String>?,
    val titles: List<String>?,
    val regions: List<Long>?,
    val minusRegions: List<Long>?,
    val contentIds: List<String>?,
    val trackingUrl: String?,
    val impressionUrl: String?,
    val targetId: TargetType?,
    val cpa: BigDecimal?,
    val crr: Long?,
    val weekLimit: BigDecimal?,
    val limitPeriod: LimitPeriodType? = LimitPeriodType.WEEK,
    val hyperGeoId: Long?,
    val keywords: List<String>?,
    val minusKeywords: List<String>?,
    val socdem: Socdem?,
    val deviceTypes: Set<DeviceType>?,
    val inventoryTypes: Set<InventoryType>?,
    val goals: List<UacGoal>?,
    val goalCreateRequest: GoalCreateRequest?,
    val counters: List<Int>?,
    val permalinkId: Long?,
    val phoneId: Long?,
    val calltrackingPhones: List<String>?,
    val sitelinks: List<Sitelink>?,
    val skadNetworkEnabled: Boolean?,
    val adultContentEnabled: Boolean?,
    val advType: AdvType = AdvType.MOBILE_CONTENT,
    val timeTarget: TimeTarget?,
    val strategy: UacStrategy?,
    val retargetingCondition: UacRetargetingCondition?,
    val videosAreNonSkippable: Boolean?,
    val brandSurveyId: String?,
    val brandSurveyName: String?,
    val showsFrequencyLimit: UacShowsFrequencyLimit?,
    val strategyPlatform: UacStrategyPlatform?,
    val cloneFromCampaignId: Long?,
    val cpmAssets: Map<String, UacCpmAsset>?,
    val campaignMeasurers: List<UacCampaignMeasurer>?,
    val uacBrandsafety: UacBrandsafety?,
    val uacDisabledPlaces: UacDisabledPlaces?,
    val mobileAppId: Long?,

    // Список корректировок ставки, задаваемых пользователем
    val adjustments: List<UacAdjustmentRequest>?,

    @JsonProperty("ecom") val isEcom: Boolean?,
    val feedId: Long?,
    val feedFilters: List<UacFeedFilter>?,
    val trackingParams: String?,

    val source: CampaignSource?,
    val widgetPartnerId: Long?,
    @JsonProperty("recommendations_management_enabled") val isRecommendationsManagementEnabled: Boolean?,
    @JsonProperty("price_recommendations_management_enabled") val isPriceRecommendationsManagementEnabled: Boolean?,
    val relevanceMatch: UacRelevanceMatch?,
    val showTitleAndBody: Boolean?,
    val altAppStores: Set<AltAppStore>?,
    val bizLandingId: Long?,
    val searchLift: UacSearchLift?,
) {
    fun toInternal(
        calltrackingSettingsId: Long?,
        goals: List<UacGoal>?,
        zenPublisherId: String?,
    ): CreateCampaignInternalRequest {
        val source = calculateCampaignSource(this.source, this.widgetPartnerId)
        // Правим возможную неконсистентность, возникающую при изначальном создании кампании в профи-интерфейсе.
        // У ecom-кампании не должно быть включенных флагов управления от Яндекса
        var isRecommendationsManagementEnabled = this.isRecommendationsManagementEnabled
        var isPriceRecommendationsManagementEnabled = this.isPriceRecommendationsManagementEnabled
        if (this.isEcom == true) {
            isRecommendationsManagementEnabled = false
            isPriceRecommendationsManagementEnabled = false
        }
        return CreateCampaignInternalRequest(
            displayName = this.displayName,
            href = this.href,
            appId = this.appId,
            texts = this.texts,
            titles = this.titles,
            regions = this.regions,
            minusRegions = this.minusRegions,
            contentIds = this.contentIds,
            trackingUrl = this.trackingUrl,
            impressionUrl = this.impressionUrl,
            targetId = this.targetId,
            cpa = this.cpa,
            crr = this.crr,
            weekLimit = this.weekLimit,
            limitPeriod = this.limitPeriod,
            hyperGeoId = this.hyperGeoId,
            keywords = this.keywords,
            minusKeywords = this.minusKeywords,
            socdem = this.socdem,
            deviceTypes = this.deviceTypes,
            inventoryTypes = this.inventoryTypes,
            goals = goals,
            counters = this.counters,
            permalinkId = this.permalinkId,
            phoneId = this.phoneId,
            sitelinks = this.sitelinks,
            skadNetworkEnabled = this.skadNetworkEnabled,
            adultContentEnabled = this.adultContentEnabled,
            advType = this.advType,
            timeTarget = this.timeTarget,
            strategy = this.strategy,
            retargetingCondition = this.retargetingCondition,
            videosAreNonSkippable = this.videosAreNonSkippable,
            brandSurveyId = this.brandSurveyId,
            brandSurveyName = this.brandSurveyName,
            showsFrequencyLimit = this.showsFrequencyLimit,
            strategyPlatform = this.strategyPlatform,
            adjustments = this.adjustments,
            isEcom = this.isEcom,
            feedId = this.feedId,
            feedFilters = this.feedFilters,
            trackingParams = this.trackingParams,
            cpmAssets = this.cpmAssets,
            campaignMeasurers = this.campaignMeasurers,
            uacBrandsafety = this.uacBrandsafety,
            uacDisabledPlaces = this.uacDisabledPlaces,
            mobileAppId = this.mobileAppId,
            widgetPartnerId = this.widgetPartnerId,
            isRecommendationsManagementEnabled = isRecommendationsManagementEnabled,
            isPriceRecommendationsManagementEnabled = isPriceRecommendationsManagementEnabled,
            relevanceMatch = this.relevanceMatch,
            showTitleAndBody = this.showTitleAndBody,
            altAppStores = this.altAppStores,
            bizLandingId = this.bizLandingId,
            searchLift = this.searchLift,

            // Ниже перечислены поля, которых нет в [CreateCampaignRequest]
            calltrackingSettingsId = calltrackingSettingsId,
            source = source,
            zenPublisherId = zenPublisherId,
        )
    }
}
