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

import com.yandex.direct.api.v5.campaignsext.CampaignUpdateItem
import com.yandex.direct.api.v5.campaignsext.CpmBannerCampaignUpdateItem
import com.yandex.direct.api.v5.campaignsext.DynamicTextCampaignUpdateItem
import com.yandex.direct.api.v5.campaignsext.MobileAppCampaignUpdateItem
import com.yandex.direct.api.v5.campaignsext.SmartCampaignUpdateItem
import com.yandex.direct.api.v5.campaignsext.TextCampaignUpdateItem
import org.springframework.stereotype.Component
import ru.yandex.direct.api.v5.entity.campaigns.validation.CampaignsUpdateRequestValidator.SimpleValidations.validateCampaignUpdateItemCommonDefects
import ru.yandex.direct.api.v5.entity.campaigns.validation.CpmBannerCampaignUpdateRequestValidator
import ru.yandex.direct.api.v5.entity.campaigns.validation.DynamicTextCampaignUpdateRequestValidator
import ru.yandex.direct.api.v5.entity.campaigns.validation.MobileAppCampaignUpdateRequestValidator
import ru.yandex.direct.api.v5.entity.campaigns.validation.SmartCampaignUpdateRequestValidator
import ru.yandex.direct.api.v5.entity.campaigns.validation.TextCampaignUpdateRequestValidator
import ru.yandex.direct.api.v5.entity.campaignsext.converter.CampaignExtToCampaignConverter
import ru.yandex.direct.api.v5.entity.campaignsext.converter.convertBean
import ru.yandex.direct.api.v5.validation.DefectType
import ru.yandex.direct.core.entity.campaign.model.CampaignType
import ru.yandex.direct.core.entity.campaign.model.CpmBannerCampaign
import ru.yandex.direct.core.entity.campaign.model.DynamicCampaign
import ru.yandex.direct.core.entity.campaign.model.MobileContentCampaign
import ru.yandex.direct.core.entity.campaign.model.SmartCampaign
import ru.yandex.direct.core.entity.campaign.model.TextCampaign
import ru.yandex.direct.core.entity.timetarget.model.GeoTimezone
import ru.yandex.direct.validation.result.ValidationResult

/**
 * Валидаторы для всех кампаний, кроме ContentPromotion
 */
@Component
class OtherCampaignsUpdateRequestValidator(
    private val converter: CampaignExtToCampaignConverter,
) {

    fun validateCampaignUpdateItemNormalDefects(
        campaignsExtItem: CampaignUpdateItem,
        timeZones: Map<String, GeoTimezone>,
        type: CampaignType?,
        requestCampaignIds: List<Long>,
    ): ValidationResult<CampaignUpdateItem, DefectType> =
        toCampaignsExtResult(
            campaignsExtItem,
            validateCampaignUpdateItemCommonDefects(
                converter.convertUpdateItem(campaignsExtItem), timeZones, type, requestCampaignIds
            )
        )

    fun validateCpmBannerCampaign(
        campaignsExtItem: CpmBannerCampaignUpdateItem,
        campaignFromDb: CpmBannerCampaign?
    ): ValidationResult<CpmBannerCampaignUpdateItem, DefectType?> =
        toCampaignsExtResult(
            campaignsExtItem,
            CpmBannerCampaignUpdateRequestValidator.validateCpmBannerCampaign(
                campaignsExtItem.convertBean(), campaignFromDb
            )
        )

    fun validateDynamicTextCampaign(
        campaignsExtItem: DynamicTextCampaignUpdateItem,
        campaignFromDb: DynamicCampaign?
    ): ValidationResult<DynamicTextCampaignUpdateItem, DefectType?> =
        toCampaignsExtResult(
            campaignsExtItem,
            DynamicTextCampaignUpdateRequestValidator.validateDynamicTextCampaign(
                campaignsExtItem.convertBean(), campaignFromDb
            )
        )

    fun validateMobileAppCampaign(
        campaignsExtItem: MobileAppCampaignUpdateItem,
        campaignFromDb: MobileContentCampaign?
    ): ValidationResult<MobileAppCampaignUpdateItem, DefectType?> =
        toCampaignsExtResult(
            campaignsExtItem,
            MobileAppCampaignUpdateRequestValidator.validateMobileAppCampaign(
                campaignsExtItem.convertBean(), campaignFromDb
            )
        )

    fun validateSmartCampaign(
        campaignsExtItem: SmartCampaignUpdateItem,
        campaignFromDb: SmartCampaign?
    ): ValidationResult<SmartCampaignUpdateItem, DefectType?> =
        toCampaignsExtResult(
            campaignsExtItem,
            SmartCampaignUpdateRequestValidator.validateSmartCampaign(
                 campaignsExtItem.convertBean(), campaignFromDb
            )
        )

    fun validateTextCampaign(
        campaignsExtItem: TextCampaignUpdateItem,
        campaignFromDb: TextCampaign?,
    ): ValidationResult<TextCampaignUpdateItem, DefectType?> =
        toCampaignsExtResult(
            campaignsExtItem,
            TextCampaignUpdateRequestValidator.validateTextCampaign(
                   campaignsExtItem.convertBean(), campaignFromDb
            )
        )

    private fun <T> toCampaignsExtResult(campaignsExtItem: T, convertedResult: ValidationResult<*, DefectType>) =
        ValidationResult(
            campaignsExtItem,
            convertedResult.errors,
            convertedResult.warnings,
            convertedResult.subResults,
        )
}
