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

import ru.yandex.direct.core.entity.banner.service.validation.defects.BannerDefects.imageNotFound
import ru.yandex.direct.core.entity.banner.type.href.BannerHrefValidator
import ru.yandex.direct.core.entity.image.repository.BannerImageFormatRepository
import ru.yandex.direct.core.entity.uac.model.AdvType
import ru.yandex.direct.core.entity.uac.repository.ydb.model.UacCpmAsset
import ru.yandex.direct.dbutil.model.ClientId
import ru.yandex.direct.dbutil.sharding.ShardHelper
import ru.yandex.direct.validation.builder.Constraint
import ru.yandex.direct.validation.builder.When
import ru.yandex.direct.validation.result.Defect
import ru.yandex.direct.validation.result.ValidationResult
import ru.yandex.direct.validation.util.listProperty
import ru.yandex.direct.validation.util.property
import ru.yandex.direct.validation.util.validateObject
import ru.yandex.direct.validation.wrapper.DefaultValidator
import ru.yandex.direct.web.entity.uac.service.UacCampaignValidationService

class CpmAssetValidator (
    private val uacCampaignValidationService: UacCampaignValidationService,
    private val bannerImageFormatRepository: BannerImageFormatRepository,
    private val shardHelper: ShardHelper,
    private val clientId: ClientId,
) :
    DefaultValidator<UacCpmAsset> {
    override fun apply(uacCpmAsset: UacCpmAsset): ValidationResult<UacCpmAsset, Defect<*>> {
        val imageTypeByHash = uacCpmAsset.logoImageHash?.let {
            bannerImageFormatRepository
                .getExistingImageHashesWithType(shardHelper.getShardByClientId(clientId), clientId, listOf(it))
        } ?: emptyMap()

        return validateObject(uacCpmAsset) {
            property(UacCpmAsset::bannerHref) {
                checkBy(BannerHrefValidator(), When.notNull())
            }

            property(UacCpmAsset::body) {
                checkBy(uacCampaignValidationService.getTextValidator(AdvType.CPM_BANNER), When.notNull())
            }

            property(UacCpmAsset::title) {
                checkBy(uacCampaignValidationService.getTitleValidator(), When.notNull())
            }

            property(UacCpmAsset::titleExtension) {
                checkBy(uacCampaignValidationService.getTitleExtensionValidator(), When.notNull())
            }

            listProperty(UacCpmAsset::measurers) {//валидатор вызовется только если есть измеритель
                checkEachBy(uacCampaignValidationService.getCpmUacMeasurersValidator(clientId), When.notNull())
            }

            property(UacCpmAsset::button) {
                checkBy(CpmAssetButtonValidator(uacCampaignValidationService.getAllowedButtonActions(clientId)), When.notNull())
            }

            property(UacCpmAsset::logoImageHash) {
                check(
                    Constraint.fromPredicate({ hash -> imageTypeByHash.keys.contains(hash) }, imageNotFound()),
                    When.notNull()
                )
            }
        }
    }
}
