package ru.yandex.direct.api.v5.entity.adgroups.validation.type

import org.springframework.stereotype.Component
import ru.yandex.direct.api.v5.entity.adgroups.AdGroupDefectTypes.feedsNotAllowed
import ru.yandex.direct.api.v5.entity.adgroups.AdGroupTypeValidationService.checkHasNoCpmPriceAdGroup
import ru.yandex.direct.api.v5.entity.adgroups.container.AddAdGroupsSimpleContainer
import ru.yandex.direct.api.v5.security.ApiAuthenticationSource
import ru.yandex.direct.api.v5.validation.DefectType
import ru.yandex.direct.api.v5.validation.DefectTypes.disableAllAutotargetingCategoriesIsForbidden
import ru.yandex.direct.api.v5.validation.DefectTypes.invalidUseOfField
import ru.yandex.direct.core.entity.adgroup.model.ContentPromotionAdGroup
import ru.yandex.direct.core.entity.adgroup.model.ContentPromotionAdgroupType
import ru.yandex.direct.core.entity.adgroup.model.DynamicAdGroup
import ru.yandex.direct.core.entity.adgroup.model.TextAdGroup
import ru.yandex.direct.validation.builder.Constraint
import ru.yandex.direct.validation.builder.ItemValidationBuilder
import ru.yandex.direct.validation.result.ValidationResult

@Component
class AddAdGroupsSimpleInternalRequestValidationTypeSupport(
    private val auth: ApiAuthenticationSource
) : AdGroupsInternalRequestValidationTypeSupport<AddAdGroupsSimpleContainer> {
    override fun getTypeClass() = AddAdGroupsSimpleContainer::class.java

    override fun validate(items: List<AddAdGroupsSimpleContainer>): List<ValidationResult<AddAdGroupsSimpleContainer, DefectType>> {
        checkHasNoCpmPriceAdGroup(items.map { it.adGroup })
        return items.map { validateItem(it) }
    }

    private fun validateItem(item: AddAdGroupsSimpleContainer) =
        ItemValidationBuilder.of<AddAdGroupsSimpleContainer, DefectType>(item)
            .check(supportedContentPromotion())
            .check(dynamicAdGroupHasNotEmptyRelevanceMatchCategories())
            .weakCheck(feedIsNotSet())
            .result

    private fun supportedContentPromotion(): Constraint<AddAdGroupsSimpleContainer, DefectType> {
        return Constraint.fromPredicate({ request ->
            if (request.adGroup is ContentPromotionAdGroup) {
                request.adGroup.contentPromotionType != ContentPromotionAdgroupType.SERVICE
                    || auth.isServicesApplication
            } else true
        }, invalidUseOfField())
    }

    private fun dynamicAdGroupHasNotEmptyRelevanceMatchCategories(): Constraint<AddAdGroupsSimpleContainer, DefectType> {
        return Constraint.fromPredicate({ request ->
            if (request.adGroup is DynamicAdGroup) {
                val relevanceMatchCategories = request.adGroup.relevanceMatchCategories
                relevanceMatchCategories == null || relevanceMatchCategories.isNotEmpty()
            } else true
        }, disableAllAutotargetingCategoriesIsForbidden())
    }

    private fun feedIsNotSet(): Constraint<AddAdGroupsSimpleContainer, DefectType> {
        return Constraint.fromPredicate({ request ->
            if (request.adGroup is TextAdGroup) {
                request.adGroup.oldFeedId == null && request.adGroup.feedFilterCategories == null
            } else true
        }, feedsNotAllowed())
    }
}
