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

import org.springframework.stereotype.Service
import ru.yandex.direct.core.entity.feature.service.enabled
import ru.yandex.direct.core.entity.uac.converter.UacContentConverter
import ru.yandex.direct.core.entity.uac.model.AdvType
import ru.yandex.direct.core.entity.uac.model.AppInfo
import ru.yandex.direct.core.entity.uac.model.CampaignContentsContainer
import ru.yandex.direct.core.entity.uac.model.LimitPeriodType
import ru.yandex.direct.core.entity.uac.model.TargetStatus
import ru.yandex.direct.core.entity.uac.model.TrackingUrl
import ru.yandex.direct.core.entity.uac.model.UacAdjustmentRequest
import ru.yandex.direct.core.entity.uac.repository.ydb.model.UacYdbCampaign
import ru.yandex.direct.core.entity.uac.service.UacContentService
import ru.yandex.direct.feature.FeatureName
import ru.yandex.direct.web.entity.uac.model.CreateCampaignInternalRequest
import ru.yandex.direct.web.entity.uac.model.PatchCampaignInternalRequest
import ru.yandex.direct.web.entity.uac.model.UacModifyCampaignDataContainer
import java.time.LocalDateTime
import ru.yandex.direct.web.entity.uac.model.UacAdGroupBriefRequest

@Service
class UacModifyCampaignDataContainerFactory(
    private val uacContentService: UacContentService,
    private val uacMobileAppService: UacMobileAppService,
) {
    fun dataContainerFromPatchRequest(
        campaignId: String,
        type: AdvType,
        createdAt: LocalDateTime,
        startedAt: LocalDateTime?,
        request: PatchCampaignInternalRequest,
        advancedGeoTargeting: Boolean,
    ) = UacModifyCampaignDataContainer(
        id = campaignId,
        advType = type,
        displayName = request.displayName!!,
        appInfo = null,
        texts = request.texts,
        titles = request.titles,
        sitelinks = request.sitelinks,
        regions = request.regions,
        minusRegions = request.minusRegions,
        targetId = request.targetId,
        cpa = request.cpa,
        crr = request.crr,
        weekLimit = request.weekLimit,
        trackingUrl = null,
        impressionUrl = null,
        href = request.href!!,
        createdTime = createdAt,
        updatedTime = LocalDateTime.now(),
        contentFlags = null,
        limitPeriod = request.limitPeriod,
        startedTime = startedAt ?: LocalDateTime.now(),
        targetStatus = TargetStatus.STOPPED,
        hyperGeoId = request.hyperGeoId,
        keywords = request.keywords,
        minusKeywords = request.minusKeywords,
        socdem = request.socdem,
        deviceTypes = request.deviceTypes,
        inventoryTypes = request.inventoryTypes,
        goals = request.goals,
        counters = request.counters,
        permalinkId = request.permalinkId,
        phoneId = request.phoneId,
        calltrackingSettingsId = request.calltrackingSettingsId,
        timeTarget = request.timeTarget,
        strategy = request.strategy,
        retargetingCondition = request.retargetingCondition,
        skadNetworkEnabled = null,
        videosAreNonSkippable = request.videosAreNonSkippable,
        adultContentEnabled = request.adultContentEnabled,
        zenPublisherId = request.zenPublisherId,
        brandSurveyId = request.brandSurveyId,
        brandSurveyName = request.brandSurveyName,
        showsFrequencyLimit = request.showsFrequencyLimit,
        strategyPlatform = request.strategyPlatform,
        adjustments = request.adjustments,
        isEcom = request.isEcom,
        feedId = request.feedId,
        feedFilters = request.feedFilters,
        trackingParams = request.trackingParams,
        cpmAssets = request.cpmAssets,
        campaignMeasurers = request.campaignMeasurers,
        uacBrandsafety = request.uacBrandsafety,
        uacDisabledPlaces = request.uacDisabledPlaces,
        widgetPartnerId = null,
        source = null,
        mobileAppId = null,
        isRecommendationsManagementEnabled = request.isRecommendationsManagementEnabled,
        isPriceRecommendationsManagementEnabled = request.isPriceRecommendationsManagementEnabled,
        relevanceMatch = request.relevanceMatch,
        showTitleAndBody = request.showTitleAndBody,
        altAppStores = null,
        bizLandingId = request.bizLandingId,
        searchLift = request.searchLift,
        useCurrentRegion = if (advancedGeoTargeting) true else null,
        useRegularRegion = if (advancedGeoTargeting) false else null,
    )

    fun dataContainerFromCreateRequest(
        campaignId: String,
        request: CreateCampaignInternalRequest,
        appInfo: AppInfo?,
        trackingUrl: TrackingUrl?,
        impressionUrl: TrackingUrl?,
        advancedGeoTargeting: Boolean,
        adGroupBriefRequests: List<UacAdGroupBriefRequest>? = null,
    ) = UacModifyCampaignDataContainer(
        id = campaignId,
        advType = request.advType,
        displayName = request.displayName,
        appInfo = appInfo,
        texts = request.texts,
        titles = request.titles,
        sitelinks = request.sitelinks,
        regions = request.regions,
        minusRegions = request.minusRegions,
        targetId = request.targetId,
        cpa = request.cpa,
        crr = request.crr,
        weekLimit = request.weekLimit,
        trackingUrl = trackingUrl,
        impressionUrl = impressionUrl,
        href = request.href,
        skadNetworkEnabled = request.skadNetworkEnabled,
        adultContentEnabled = request.adultContentEnabled,
        createdTime = LocalDateTime.now(),
        updatedTime = LocalDateTime.now(),
        contentFlags = null,
        limitPeriod = request.limitPeriod,
        startedTime = null,
        targetStatus = TargetStatus.STOPPED,
        hyperGeoId = request.hyperGeoId,
        keywords = request.keywords,
        minusKeywords = request.minusKeywords,
        socdem = request.socdem,
        deviceTypes = request.deviceTypes,
        inventoryTypes = request.inventoryTypes,
        goals = request.goals,
        counters = request.counters,
        permalinkId = request.permalinkId,
        phoneId = request.phoneId,
        calltrackingSettingsId = request.calltrackingSettingsId,
        timeTarget = request.timeTarget,
        strategy = request.strategy,
        retargetingCondition = request.retargetingCondition,
        videosAreNonSkippable = request.videosAreNonSkippable,
        zenPublisherId = request.zenPublisherId,
        brandSurveyId = request.brandSurveyId,
        brandSurveyName = request.brandSurveyName,
        showsFrequencyLimit = request.showsFrequencyLimit,
        strategyPlatform = request.strategyPlatform,
        adjustments = request.adjustments,
        isEcom = request.isEcom,
        feedId = request.feedId,
        feedFilters = request.feedFilters,
        trackingParams = request.trackingParams,
        cpmAssets = request.cpmAssets,
        campaignMeasurers = request.campaignMeasurers,
        uacBrandsafety = request.uacBrandsafety,
        uacDisabledPlaces = request.uacDisabledPlaces,
        widgetPartnerId = request.widgetPartnerId,
        source = request.source,
        mobileAppId = request.mobileAppId,
        isRecommendationsManagementEnabled = request.isRecommendationsManagementEnabled,
        isPriceRecommendationsManagementEnabled = request.isPriceRecommendationsManagementEnabled,
        relevanceMatch = request.relevanceMatch,
        showTitleAndBody = request.showTitleAndBody,
        altAppStores = request.altAppStores,
        bizLandingId = request.bizLandingId,
        searchLift = request.searchLift,
        useCurrentRegion = if (advancedGeoTargeting) true else null,
        useRegularRegion = if (advancedGeoTargeting) false else null,
        adGroupBriefRequests = adGroupBriefRequests,
    )

    fun dataContainerFromUacYdbCampaign(uacYdbCampaign: UacYdbCampaign): UacModifyCampaignDataContainer {
        val appInfo = uacMobileAppService.getAppInfo(uacYdbCampaign.appId)
        val trackingUrl = uacMobileAppService.getTrackingUrl(uacYdbCampaign.trackingUrl, appInfo)
        val impressionUrl = uacMobileAppService.getImpressionUrl(uacYdbCampaign.impressionUrl, appInfo)

        val campaignContentsContainer = uacContentService.getCampaignContentsContainer(uacYdbCampaign)

        return dataContainerFromUacYdbCampaign(
            uacYdbCampaign, appInfo,
            trackingUrl, impressionUrl, campaignContentsContainer,
            FeatureName.ADVANCED_GEOTARGETING.enabled()
        )
    }

    fun dataContainerFromUacYdbCampaign(
        uacYdbCampaign: UacYdbCampaign,
        appInfo: AppInfo?,
        trackingUrl: TrackingUrl?,
        impressionUrl: TrackingUrl?
    ): UacModifyCampaignDataContainer {
        val campaignContentsContainer = uacContentService.getCampaignContentsContainer(uacYdbCampaign)
        return dataContainerFromUacYdbCampaign(
            uacYdbCampaign, appInfo,
            trackingUrl, impressionUrl, campaignContentsContainer,
            FeatureName.ADVANCED_GEOTARGETING.enabled()
        )
    }

    private fun dataContainerFromUacYdbCampaign(
        uacYdbCampaign: UacYdbCampaign,
        appInfo: AppInfo?,
        trackingUrl: TrackingUrl?,
        impressionUrl: TrackingUrl?,
        campaignContentsContainer: CampaignContentsContainer,
        advancedGeoTargeting: Boolean,
        adjustments: List<UacAdjustmentRequest>? = null,
    ) = UacModifyCampaignDataContainer(
        id = uacYdbCampaign.id,
        advType = uacYdbCampaign.advType,
        displayName = uacYdbCampaign.name,
        appInfo = appInfo,
        texts = campaignContentsContainer.textContents.mapNotNull { it.text },
        titles = campaignContentsContainer.titleContents.mapNotNull { it.text },
        regions = uacYdbCampaign.regions,
        minusRegions = uacYdbCampaign.minusRegions,
        trackingUrl = trackingUrl,
        impressionUrl = impressionUrl,
        href = uacYdbCampaign.storeUrl,

        targetId = uacYdbCampaign.targetId,
        cpa = uacYdbCampaign.cpa,
        crr = uacYdbCampaign.crr,
        weekLimit = uacYdbCampaign.weekLimit,
        createdTime = uacYdbCampaign.createdAt,
        updatedTime = uacYdbCampaign.updatedAt,
        startedTime = uacYdbCampaign.startedAt,
        targetStatus = uacYdbCampaign.targetStatus,
        contentFlags = uacYdbCampaign.contentFlags,
        limitPeriod = uacYdbCampaign.options?.limitPeriod ?: LimitPeriodType.WEEK,
        skadNetworkEnabled = uacYdbCampaign.skadNetworkEnabled,
        adultContentEnabled = uacYdbCampaign.adultContentEnabled,
        hyperGeoId = uacYdbCampaign.hyperGeoId,
        keywords = uacYdbCampaign.keywords,
        minusKeywords = uacYdbCampaign.minusKeywords,
        socdem = uacYdbCampaign.socdem,
        deviceTypes = uacYdbCampaign.deviceTypes,
        inventoryTypes = uacYdbCampaign.inventoryTypes,
        goals = uacYdbCampaign.goals,
        counters = uacYdbCampaign.counters,
        permalinkId = uacYdbCampaign.permalinkId,
        phoneId = uacYdbCampaign.phoneId,
        calltrackingSettingsId = uacYdbCampaign.calltrackingSettingsId,
        sitelinks = campaignContentsContainer.sitelinkContents.map { UacContentConverter.toSitelink(it) },
        timeTarget = uacYdbCampaign.timeTarget,
        strategy = uacYdbCampaign.strategy,
        retargetingCondition = uacYdbCampaign.retargetingCondition,
        videosAreNonSkippable = uacYdbCampaign.videosAreNonSkippable,
        zenPublisherId = uacYdbCampaign.zenPublisherId,
        brandSurveyId = uacYdbCampaign.brandSurveyId,
        brandSurveyName = null,
        showsFrequencyLimit = uacYdbCampaign.showsFrequencyLimit,
        strategyPlatform = uacYdbCampaign.strategyPlatform,
        adjustments = adjustments,
        isEcom = uacYdbCampaign.isEcom,
        feedId = uacYdbCampaign.feedId,
        feedFilters = uacYdbCampaign.feedFilters,
        trackingParams = uacYdbCampaign.trackingParams,
        cpmAssets = uacYdbCampaign.cpmAssets,
        campaignMeasurers = uacYdbCampaign.campaignMeasurers,
        uacBrandsafety = uacYdbCampaign.uacBrandsafety,
        uacDisabledPlaces = uacYdbCampaign.uacDisabledPlaces,
        widgetPartnerId = null,
        source = null,
        mobileAppId = null,
        isRecommendationsManagementEnabled = uacYdbCampaign.recommendationsManagementEnabled,
        isPriceRecommendationsManagementEnabled = uacYdbCampaign.priceRecommendationsManagementEnabled,
        relevanceMatch = uacYdbCampaign.relevanceMatch,
        showTitleAndBody = uacYdbCampaign.showTitleAndBody,
        altAppStores = null,
        bizLandingId = uacYdbCampaign.bizLandingId,
        searchLift = uacYdbCampaign.searchLift,
        useCurrentRegion = if (advancedGeoTargeting) true else null,
        useRegularRegion = if (advancedGeoTargeting) false else null,
    )
}
