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

import org.springframework.http.HttpStatus
import ru.yandex.direct.appmetrika.model.response.UniversalCampaignInfo
import ru.yandex.direct.audience.client.model.AudienceSegment
import ru.yandex.direct.core.entity.uac.UacCommonUtils.uacErrorResponse
import ru.yandex.direct.core.entity.uac.model.AppInfo
import ru.yandex.direct.core.entity.uac.model.Content
import ru.yandex.direct.core.entity.uac.model.UacRetargetingCondition
import ru.yandex.direct.geosuggest.client.model.GeoSuggestResponse
import ru.yandex.direct.grid.core.entity.showcondition.model.GdiAggregatedShowCondition
import ru.yandex.direct.tracing.Trace
import ru.yandex.direct.web.entity.uac.model.AggregatedTrackingUrlStat
import ru.yandex.direct.web.entity.uac.model.AggregatedTrackingUrlStatResponse
import ru.yandex.direct.web.entity.uac.model.CreateImpressionUrlResponse
import ru.yandex.direct.web.entity.uac.model.CreatedImpressionUrl
import ru.yandex.direct.web.entity.uac.model.Suggest
import ru.yandex.direct.web.entity.uac.model.UacAggregatedShowConditionsResponse
import ru.yandex.direct.web.entity.uac.model.UacAppInfosResponse
import ru.yandex.direct.web.entity.uac.model.UacAudienceSegmentListResponse
import ru.yandex.direct.web.entity.uac.model.UacAudienceSegmentResponse
import ru.yandex.direct.web.entity.uac.model.UacAvailableStrategyGoals
import ru.yandex.direct.web.entity.uac.model.UacAvailableStrategyGoalsResponse
import ru.yandex.direct.web.entity.uac.model.UacCampaign
import ru.yandex.direct.web.entity.uac.model.UacCampaignProtoResponse
import ru.yandex.direct.web.entity.uac.model.UacCampaignResponse
import ru.yandex.direct.web.entity.uac.model.UacContentResponse
import ru.yandex.direct.web.entity.uac.model.UacContentStatistics
import ru.yandex.direct.web.entity.uac.model.UacContentStatisticsResponse
import ru.yandex.direct.web.entity.uac.model.UacContentsResponse
import ru.yandex.direct.web.entity.uac.model.UacCreateTrackingUrlResponse
import ru.yandex.direct.web.entity.uac.model.UacDirectApp
import ru.yandex.direct.web.entity.uac.model.UacDirectAppResponse
import ru.yandex.direct.web.entity.uac.model.UacGeoSuggestResponse
import ru.yandex.direct.web.entity.uac.model.UacGoalInfo
import ru.yandex.direct.web.entity.uac.model.UacGoalInfoResponse
import ru.yandex.direct.web.entity.uac.model.UacNavigationInfo
import ru.yandex.direct.web.entity.uac.model.UacProperties
import ru.yandex.direct.web.entity.uac.model.UacPropertiesResponse
import ru.yandex.direct.web.entity.uac.model.UacQr
import ru.yandex.direct.web.entity.uac.model.UacQrResponse
import ru.yandex.direct.web.entity.uac.model.UacRetargetingCampaign
import ru.yandex.direct.web.entity.uac.model.UacRetargetingCampaignResponse
import ru.yandex.direct.web.entity.uac.model.UacRetargetingConditionsResponse
import ru.yandex.direct.web.entity.uac.model.UacRetargetingGoals
import ru.yandex.direct.web.entity.uac.model.UacRetargetingGoalsResponse
import ru.yandex.direct.web.entity.uac.model.UacSiteSuggest
import ru.yandex.direct.web.entity.uac.model.UacSiteSuggestResponse
import ru.yandex.direct.web.entity.uac.model.UacSuggestResponse
import ru.yandex.direct.web.entity.uac.model.UacTrackingInfo
import ru.yandex.direct.web.entity.uac.model.UacTrackingInfoResponse
import ru.yandex.direct.web.entity.uac.model.ValidatedTrackingUrl
import ru.yandex.direct.web.entity.uac.model.ValidatedTrackingUrlResponse
import ru.yandex.direct.web.entity.uac.model.history.UacCampaignHistory
import ru.yandex.direct.web.entity.uac.model.history.UacCampaignHistoryResponse
import ru.yandex.direct.web.proto.api.uac.GetCampaignResponse.TGetCampaignResponse

const val USER_REJECTED = 101
const val NOT_OWNER = 102
const val NOT_ALLOWED = 103
const val BY_CSRF = 104
const val NO_COOKIE = 105
const val BY_OAUTH = 106
const val ZERO_BALANCE = 107
const val VIDEO_NOT_READY = 108
const val CAMPAIGN_STARTED = 109
const val CAMPAIGN_STOPPED = 110

@Deprecated("Нужно использовать CAMPAIGN_ARCHIVED")
const val CAMPAIGN_REMOVED = 111

const val NOT_CLIENT = 112
const val EMPTY_CONTENTS = 113
const val EMPTY_TEXTS = 114
const val EMPTY_TITLES = 115
const val NO_PERMISSION = 116
const val IMPRESSION_DOES_NOT_EXIST = 117
const val APP_INFO_DOES_NOT_EXIST = 118
const val CAMPAIGN_ARCHIVED = 119
const val EMPTY_REGIONS = 120
const val EMPTY_TRACKING_URL = 121

const val INVALID_REGION_IDS = 1019
const val TOO_LONG_TEXT = 1028
const val HAS_FAILED_AUDIENCE_SEGMENTS = 1029

fun notFoundResponse() = uacErrorResponse(title = "404 Not Found", status = HttpStatus.NOT_FOUND)
fun notOwnerResponse() = uacErrorResponse(
    title = "Forbidden",
    description = "You dont have permission for that",
    status = HttpStatus.FORBIDDEN,
    code = NOT_OWNER,
)

fun actionNotAllowedResponse() = uacErrorResponse(
    title = "Forbidden",
    description = "Action not allowed",
    status = HttpStatus.FORBIDDEN,
    code = NOT_ALLOWED,
)

fun notAllowedResponse() = uacErrorResponse(
    title = "Forbidden",
    description = "Not allowed",
    status = HttpStatus.FORBIDDEN,
    code = NOT_ALLOWED,
)

fun campaignIsArchivedResponse() = uacErrorResponse(
    title = "Forbidden",
    description = "Campaign is archived",
    status = HttpStatus.FORBIDDEN,
    code = CAMPAIGN_ARCHIVED,
)

fun contentsEmptyResponse() = uacErrorResponse(
    title = "Forbidden",
    description = "Contents must not be empty",
    status = HttpStatus.FORBIDDEN,
    code = EMPTY_CONTENTS,
)

fun textsEmptyResponse() = uacErrorResponse(
    title = "Forbidden",
    description = "Texts must not be empty",
    status = HttpStatus.FORBIDDEN,
    code = EMPTY_TEXTS,
)

fun titlesEmptyResponse() = uacErrorResponse(
    title = "Forbidden",
    description = "Titles must not be empty",
    status = HttpStatus.FORBIDDEN,
    code = EMPTY_TITLES,
)

fun errorCreatingDirectCampaignResponse() = uacErrorResponse(
    title = "Internal Error",
    description = "Error creating direct campaign",
    status = HttpStatus.INTERNAL_SERVER_ERROR,
)

fun campaignAlreadyStoppedResponse() = uacErrorResponse(
    title = "Forbidden",
    description = "Campaign is already stopped",
    status = HttpStatus.FORBIDDEN,
    code = CAMPAIGN_STOPPED,
)

fun campaignAlreadyStartedResponse() = uacErrorResponse(
    title = "Forbidden",
    description = "Campaign is already started",
    status = HttpStatus.FORBIDDEN,
    code = CAMPAIGN_STARTED,
)

fun campaignDoesNotExistResponse() = uacErrorResponse(
    title = "Forbidden",
    description = "Direct campaign does not exists or still drafted",
    status = HttpStatus.FORBIDDEN,
    code = NOT_ALLOWED,
)

fun regionsEmptyResponse() = uacErrorResponse(
    title = "Forbidden",
    description = "Regions must not be empty",
    status = HttpStatus.FORBIDDEN,
    code = EMPTY_REGIONS,
)

fun trackingUrlEmptyResponse() = uacErrorResponse(
    title = "Forbidden",
    description = "Tracking url must not be empty",
    status = HttpStatus.FORBIDDEN,
    code = EMPTY_TRACKING_URL,
)

fun invalidUrl() = uacErrorResponse(
    title = "Bad request",
    description = "Not a valid url",
    status = HttpStatus.BAD_REQUEST
)

fun regionIdsEmptyResponse() = uacErrorResponse(
    title = "Bad request",
    description = "Region ids must not be empty",
    status = HttpStatus.BAD_REQUEST,
    code = INVALID_REGION_IDS
)

fun geoSuggestTextTooLongResponse() = uacErrorResponse(
    title = "Bad request",
    description = "Text is too long",
    status = HttpStatus.BAD_REQUEST,
    code = TOO_LONG_TEXT,
)

fun cantStartCpmBannerCampaign() = uacErrorResponse(
    title = "Forbidden",
    description = "Cant start cpm banner campaign",
    status = HttpStatus.FORBIDDEN,
    code = CAMPAIGN_STARTED,
)

fun UacCampaign.toResponse(): UacCampaignResponse {
    val reqId = Trace.current().spanId.toString()

    return UacCampaignResponse(reqId)
        .withResult(this)
}

fun TGetCampaignResponse.toResponse(): UacCampaignProtoResponse {
    val reqId = Trace.current().spanId.toString()
    return UacCampaignProtoResponse(reqId, this)
}

fun Content.toResponse(): UacContentResponse {
    val reqId = Trace.current().spanId.toString()

    return UacContentResponse(reqId)
        .withResult(this)
}

fun Suggest.toResponse(): UacSuggestResponse {
    val reqId = Trace.current().spanId.toString()

    return UacSuggestResponse(reqId)
        .withResult(this)
}

fun toResponse(
    contentStatistics: List<UacContentStatistics>,
    navigationInfo: UacNavigationInfo,
): UacContentStatisticsResponse {
    val reqId = Trace.current().spanId.toString()

    return UacContentStatisticsResponse(reqId, contentStatistics, navigationInfo)
}

fun List<Content>.toResponse(
    additionalInfo: Map<String, Any>? = null
): UacContentsResponse {
    val reqId = Trace.current().spanId.toString()

    return UacContentsResponse(reqId, this, additionalInfo)
}

fun UacQr.toResponse(): UacQrResponse {
    val reqId = Trace.current().spanId.toString()

    return UacQrResponse(reqId)
        .withResult(this)
}

fun List<AppInfo>.toResponse(): UacAppInfosResponse {
    val reqId = Trace.current().spanId.toString()

    return UacAppInfosResponse(reqId)
        .withResult(this)
}

fun List<UacSiteSuggest>.toResponse(): UacSiteSuggestResponse {
    val reqId = Trace.current().spanId.toString()

    return UacSiteSuggestResponse(reqId)
        .withResult(this)
}

fun List<UacGoalInfo>.toResponse(): UacGoalInfoResponse {
    val reqId = Trace.current().spanId.toString()

    return UacGoalInfoResponse(reqId)
        .withResult(this)
}

fun UacDirectApp.toResponse(): UacDirectAppResponse {
    val reqId = Trace.current().spanId.toString()
    return UacDirectAppResponse(reqId, this)
}

fun GeoSuggestResponse.toResponse(): UacGeoSuggestResponse {
    val reqId = Trace.current().spanId.toString()

    return UacGeoSuggestResponse(reqId)
        .withResult(this)
}

fun UacProperties.toResponse(): UacPropertiesResponse {
    val reqId = Trace.current().spanId.toString()
    return UacPropertiesResponse(reqId)
        .withResult(this)
}

fun ValidatedTrackingUrl?.toResponse(): ValidatedTrackingUrlResponse {
    val reqId = Trace.current().spanId.toString()

    return ValidatedTrackingUrlResponse(reqId)
        .withResult(this)
}

fun AggregatedTrackingUrlStat?.toResponse(): AggregatedTrackingUrlStatResponse {
    val reqId = Trace.current().spanId.toString()

    return AggregatedTrackingUrlStatResponse(reqId)
        .withResult(this)
}

fun CreatedImpressionUrl?.toResponse(): CreateImpressionUrlResponse {
    val reqId = Trace.current().spanId.toString()
    return CreateImpressionUrlResponse(reqId)
        .withResult(this)
}

fun List<UacTrackingInfo>.toResponse(): UacTrackingInfoResponse {
    val reqId = Trace.current().spanId.toString()
    return UacTrackingInfoResponse(reqId)
        .withResult(this)
}

fun List<GdiAggregatedShowCondition>.toResponse(): UacAggregatedShowConditionsResponse {
    val reqId = Trace.current().spanId.toString()
    return UacAggregatedShowConditionsResponse(reqId)
        .withResult(this)
}

fun UacRetargetingGoals.toResponse(): UacRetargetingGoalsResponse {
    val reqId = Trace.current().spanId.toString()
    return UacRetargetingGoalsResponse(reqId)
        .withResult(this)
}

fun List<UacRetargetingCondition>.toResponse(): UacRetargetingConditionsResponse {
    val reqId = Trace.current().spanId.toString()
    return UacRetargetingConditionsResponse(reqId)
        .withResult(this)
}

fun List<UacRetargetingCampaign>.toResponse(): UacRetargetingCampaignResponse {
    val reqId = Trace.current().spanId.toString()
    return UacRetargetingCampaignResponse(reqId)
        .withResult(this)
}

fun AudienceSegment.toResponse(): UacAudienceSegmentResponse {
    val reqId = Trace.current().spanId.toString()
    return UacAudienceSegmentResponse(reqId)
        .withResult(this)
}

fun UacAvailableStrategyGoals.toResponse(): UacAvailableStrategyGoalsResponse {
    val reqId = Trace.current().spanId.toString()
    return UacAvailableStrategyGoalsResponse(reqId)
        .withResult(this)
}

fun List<AudienceSegment>.toResponse(): UacAudienceSegmentListResponse {
    val reqId = Trace.current().spanId.toString()
    return UacAudienceSegmentListResponse(reqId)
        .withResult(this)
}

fun UniversalCampaignInfo.toResponse(): UacCreateTrackingUrlResponse {
    val reqId = Trace.current().spanId.toString()
    return UacCreateTrackingUrlResponse(reqId)
        .withResult(this)
}

fun List<UacCampaignHistory>.toResponse(): UacCampaignHistoryResponse {
    val reqId = Trace.current().spanId.toString()
    return UacCampaignHistoryResponse(reqId).withResult(this)
}
