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

import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import org.slf4j.LoggerFactory
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.PostMapping
import org.springframework.web.bind.annotation.RequestBody
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.mobileapp.model.MobileAppAutomaticCreationRequestWithoutSuppliedMobileContent
import ru.yandex.direct.core.entity.mobileapp.service.MobileAppAutomaticCreationService
import ru.yandex.direct.core.entity.mobilecontent.util.MobileAppStoreUrlParser
import ru.yandex.direct.core.security.authorization.PreAuthorizeRead
import ru.yandex.direct.web.core.entity.mobilecontent.model.WebMobileApp
import ru.yandex.direct.web.core.entity.mobilecontent.service.WebCoreMobileAppService
import ru.yandex.direct.web.core.security.DirectWebAuthenticationSource
import ru.yandex.direct.web.core.security.authentication.DirectCookieAuthProvider.PARAMETER_ULOGIN
import ru.yandex.direct.web.entity.uac.converter.UacDirectAppsResponseConverter.toUacDirectApp
import ru.yandex.direct.core.entity.uac.isValidId
import ru.yandex.direct.web.entity.uac.model.CreateDirectAppRequest
import ru.yandex.direct.web.entity.uac.notFoundResponse
import ru.yandex.direct.web.entity.uac.service.UacMobileAppService
import ru.yandex.direct.web.entity.uac.toResponse

@RestController
@Api(tags = ["uac"])
@RequestMapping("/uac", produces = [MediaType.APPLICATION_JSON_VALUE])
class UacDirectAppsController(
    private val authenticationSource: DirectWebAuthenticationSource,
    private val uacMobileAppService: UacMobileAppService,
    private val webCoreMobileAppService: WebCoreMobileAppService,
    private val mobileAppAutomaticCreationService: MobileAppAutomaticCreationService,
) {
    companion object {
        private val logger = LoggerFactory.getLogger(UacDirectAppsController::class.java)
    }

    @ApiOperation(
        value = "directAppsGet",
        httpMethod = "GET",
        nickname = "directAppsGet",
    )
    @PreAuthorizeRead
    @GetMapping(value = ["direct_apps"])
    fun getDirectApp(
        @RequestParam(value = "app_info.id", required = true) appInfoId: String
    ): ResponseEntity<Any> {
        if (!isValidId(appInfoId)) {
            return notFoundResponse()
        }
        val client = authenticationSource.authentication.subjectUser
        val appInfo = uacMobileAppService.getAppInfo(appInfoId) ?: return notFoundResponse()
        val mobileApps = webCoreMobileAppService.getAppList(client.clientId, appInfo.appId, appInfo.region?.uppercase())
        return if (mobileApps.isEmpty()) {
            notFoundResponse()
        } else {
            val mobileApp = toUacDirectApp(
                mobileApps.maxWithOrNull(compareBy<WebMobileApp> { it.hasVerification }.thenBy { it.id })!!)
            ResponseEntity(mobileApp.toResponse(), HttpStatus.OK)
        }
    }

    @ApiOperation(
        value = "directAppsPost",
        httpMethod = "POST",
        nickname = "directAppsPost",
    )
    @PreAuthorizeRead
    @PostMapping(value = ["direct_apps"])
    fun postDirectApp(
        @RequestBody request: CreateDirectAppRequest,
        @RequestParam(value = PARAMETER_ULOGIN) ulogin: String?,
    ): ResponseEntity<Any> {
        if (!isValidId(request.id)) {
            return notFoundResponse()
        }
        val client = authenticationSource.authentication.subjectUser
        val appInfo = uacMobileAppService.getAppInfo(request.id) ?: return notFoundResponse()
        val storeHref = appInfo.url
        val parsedStoreHrefOptional = MobileAppStoreUrlParser.parse(storeHref)
        val creationRequest = MobileAppAutomaticCreationRequestWithoutSuppliedMobileContent(
            parsedStoreHrefOptional.get(), storeHref, null, null, null)
        val result = mobileAppAutomaticCreationService.getOrCreateMobileAppsFromStoreHrefs(
            client.clientId, listOf(creationRequest))

        return if (result.contains(creationRequest)) {
            val mobileApp = toUacDirectApp(result.get(creationRequest)!!)
            ResponseEntity(mobileApp.toResponse(), HttpStatus.OK)
        } else {
            notFoundResponse()
        }
    }
}
