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

import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import ru.yandex.direct.core.entity.uac.service.trackingurl.ParserType
import ru.yandex.direct.core.entity.uac.service.trackingurl.TrackingUrlParseService
import ru.yandex.direct.core.entity.uac.validation.appInfoNotFound
import ru.yandex.direct.core.entity.uac.validation.invalidTrackingUrl
import ru.yandex.direct.core.security.authorization.PreAuthorizeRead
import ru.yandex.direct.validation.result.Defect
import ru.yandex.direct.validation.result.ValidationResult
import ru.yandex.direct.web.core.security.DirectWebAuthenticationSource
import ru.yandex.direct.web.core.security.authentication.DirectCookieAuthProvider
import ru.yandex.direct.web.entity.uac.service.UacGoalsService
import ru.yandex.direct.web.entity.uac.service.UacMobileAppService
import ru.yandex.direct.web.entity.uac.toResponse
import ru.yandex.direct.web.validation.kernel.ValidationResultConversionService

@RestController
@Api(tags = ["uac"])
@RequestMapping("/uac", produces = [MediaType.APPLICATION_JSON_VALUE])
class UacStrategyController(
    private val uacGoalsService: UacGoalsService,
    private val uacMobileAppService: UacMobileAppService,
    private val trackingUrlParseService: TrackingUrlParseService,
    private val validationResultConversionService: ValidationResultConversionService,
    private val authenticationSource: DirectWebAuthenticationSource,
) {
    @ApiOperation(
        value = "getAvailableStrategiesAndTargets",
        httpMethod = "GET",
        nickname = "getAvailableStrategiesAndTargets",
    )
    @PreAuthorizeRead
    @GetMapping(value = ["strategy"])
    fun getAvailableStrategyGoals(
        @ApiParam(value = "url", required = false) @RequestParam("url") url: String?,
        @ApiParam(value = "app_info_id", required = false) @RequestParam("app_info_id") appInfoId: String?,
        @ApiParam(value = "isSkadNetworkEnabled", required = false) @RequestParam isSkadNetworkEnabled: Boolean = false,
        @RequestParam(value = DirectCookieAuthProvider.PARAMETER_ULOGIN) ulogin: String?,
    ): ResponseEntity<Any> {
        val subjectUser = authenticationSource.authentication.subjectUser
        val clientId = subjectUser.clientId
        if (url == null && appInfoId == null) {
            return ResponseEntity.ok(
                uacGoalsService
                    .getAvailableStrategyGoalsForRmp(clientId, null, null, isSkadNetworkEnabled)
                    .toResponse()
            )
        }
        if (url == null) {
            return badRequestResponse(ValidationResult.failed(url, invalidTrackingUrl()))
        }
        val trackingUrl = trackingUrlParseService.parse(url, null, ParserType.TRACKING_URL)
            ?: return badRequestResponse(ValidationResult.failed(url, invalidTrackingUrl()))
        val appInfo = uacMobileAppService.getAppInfo(appInfoId)
            ?: return badRequestResponse(ValidationResult.failed(url, appInfoNotFound()))

        return ResponseEntity.ok(
            uacGoalsService
                .getAvailableStrategyGoalsForRmp(clientId, trackingUrl, appInfo, isSkadNetworkEnabled)
                .toResponse()
        )
    }

    private fun badRequestResponse(validationResult: ValidationResult<*, Defect<*>>): ResponseEntity<Any> =
        ResponseEntity(
            validationResultConversionService.buildValidationResponse(validationResult),
            HttpStatus.BAD_REQUEST
        )
}
