package ru.yandex.direct.api.v5.entity.campaigns.validation

import com.yandex.direct.api.v5.campaigns.MobileAppCampaignNetworkStrategyTypeEnum
import com.yandex.direct.api.v5.campaigns.MobileAppCampaignNetworkStrategyTypeEnum.NETWORK_DEFAULT
import com.yandex.direct.api.v5.campaigns.MobileAppCampaignSearchStrategyTypeEnum
import com.yandex.direct.api.v5.campaigns.MobileAppCampaignSetting
import com.yandex.direct.api.v5.campaigns.MobileAppCampaignSettingsEnum
import com.yandex.direct.api.v5.campaigns.MobileAppCampaignStrategy
import com.yandex.direct.api.v5.campaigns.MobileAppCampaignStrategyAdd
import ru.yandex.direct.api.v5.entity.campaigns.CampaignDefectTypes
import ru.yandex.direct.api.v5.entity.campaigns.converter.MobileAppCampaignStrategyConverter.toCampaignStrategy
import ru.yandex.direct.api.v5.entity.campaigns.converter.MobileAppCampaignUpdateItemConverter.Companion.mergeOldAndNewStrategies
import ru.yandex.direct.api.v5.entity.campaigns.converter.StrategyAddConverter.toCampaignsAutobudget
import ru.yandex.direct.api.v5.entity.campaigns.converter.toContextLimit
import ru.yandex.direct.api.v5.validation.DefectType
import ru.yandex.direct.core.entity.campaign.model.CampaignsAutobudget
import ru.yandex.direct.core.entity.campaign.model.MobileContentCampaign

fun limitPercentIsConsistentWithStrategy(strategy: MobileAppCampaignStrategyAdd): DefectType? {
    val notOk = strategy.network?.toContextLimit() != null
        && isAutobudget(strategy)
    return if (notOk) CampaignDefectTypes.parameterInconsistentWithStrategy("LimitPercent") else null
}

fun limitPercentIsConsistentWithStrategy(
    newStrategy: MobileAppCampaignStrategy,
    oldCampaign: MobileContentCampaign
): DefectType? {
    val fullNewStrategy = mergeOldAndNewStrategies(newStrategy, oldCampaign)
    val notOk = fullNewStrategy.network?.toContextLimit() != null
        && isAutobudget(fullNewStrategy)
    return if (notOk) CampaignDefectTypes.parameterInconsistentWithStrategy("LimitPercent") else null
}

fun settingIsConsistentWithStrategy(
    setting: MobileAppCampaignSetting,
    strategy: MobileAppCampaignStrategyAdd
): DefectType? {
    return when (setting.option) {
        MobileAppCampaignSettingsEnum.MAINTAIN_NETWORK_CPC -> {
            val notOk = strategy.network?.toContextLimit() != null
                && isAutobudget(strategy)
            if (notOk) CampaignDefectTypes.settingInconsistentWithStrategy("MAINTAIN_NETWORK_CPC") else null
        }
        else -> {
            null
        }
    }
}

fun settingIsConsistentWithStrategy(
    newSetting: MobileAppCampaignSetting,
    newStrategy: MobileAppCampaignStrategy?,
    oldCampaign: MobileContentCampaign?
): DefectType? {
    return when (newSetting.option) {
        MobileAppCampaignSettingsEnum.MAINTAIN_NETWORK_CPC -> {
            val fullNewStrategy = mergeOldAndNewStrategies(newStrategy, oldCampaign!!)
            val notOk = fullNewStrategy.network?.toContextLimit() != null
                && isAutobudget(fullNewStrategy)
            if (notOk) CampaignDefectTypes.settingInconsistentWithStrategy("MAINTAIN_NETWORK_CPC") else null
        }
        else -> {
            null
        }
    }
}

private fun isAutobudget(strategy: MobileAppCampaignStrategyAdd) =
    toCampaignsAutobudget(toCampaignStrategy(strategy).strategyName) == CampaignsAutobudget.YES

private fun isAutobudget(strategy: MobileAppCampaignStrategy) =
    toCampaignsAutobudget(toCampaignStrategy(strategy).strategyName) == CampaignsAutobudget.YES

fun getNetworkStrategyTypesCompatibleWith(
    searchStrategyType: MobileAppCampaignSearchStrategyTypeEnum
): Set<MobileAppCampaignNetworkStrategyTypeEnum> {
    return when (searchStrategyType) {
        MobileAppCampaignSearchStrategyTypeEnum.AVERAGE_CPC,
        MobileAppCampaignSearchStrategyTypeEnum.AVERAGE_CPI,
        MobileAppCampaignSearchStrategyTypeEnum.WB_MAXIMUM_APP_INSTALLS,
        MobileAppCampaignSearchStrategyTypeEnum.WB_MAXIMUM_CLICKS,
        MobileAppCampaignSearchStrategyTypeEnum.WEEKLY_CLICK_PACKAGE,
        MobileAppCampaignSearchStrategyTypeEnum.PAY_FOR_INSTALL ->
            setOf(
                NETWORK_DEFAULT,
                MobileAppCampaignNetworkStrategyTypeEnum.SERVING_OFF
            )
        MobileAppCampaignSearchStrategyTypeEnum.HIGHEST_POSITION ->
            setOf(
                MobileAppCampaignNetworkStrategyTypeEnum.SERVING_OFF,
                MobileAppCampaignNetworkStrategyTypeEnum.MAXIMUM_COVERAGE
            )
        MobileAppCampaignSearchStrategyTypeEnum.SERVING_OFF ->
            setOf(
                MobileAppCampaignNetworkStrategyTypeEnum.MAXIMUM_COVERAGE,
                MobileAppCampaignNetworkStrategyTypeEnum.AVERAGE_CPC,
                MobileAppCampaignNetworkStrategyTypeEnum.AVERAGE_CPI,
                MobileAppCampaignNetworkStrategyTypeEnum.WB_MAXIMUM_APP_INSTALLS,
                MobileAppCampaignNetworkStrategyTypeEnum.WB_MAXIMUM_CLICKS,
                MobileAppCampaignNetworkStrategyTypeEnum.WEEKLY_CLICK_PACKAGE,
                MobileAppCampaignNetworkStrategyTypeEnum.PAY_FOR_INSTALL
            )
        else ->
            setOf()
    }
}
