package ru.yandex.direct.web.entity.placements;

import java.util.List;
import java.util.stream.Collectors;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import ru.yandex.direct.core.entity.placements.model1.GeoBlock;
import ru.yandex.direct.core.entity.placements.model1.Placement;
import ru.yandex.direct.core.entity.placements.model1.PlacementBlock;
import ru.yandex.direct.core.entity.placements.model1.PlacementsFilter;
import ru.yandex.direct.dbutil.model.ClientId;
import ru.yandex.direct.web.core.entity.placement.model.PlacementsResponse;
import ru.yandex.direct.web.core.entity.placement.service.PlacementsService;
import ru.yandex.direct.web.core.security.DirectWebAuthenticationSource;

import static ru.yandex.direct.web.core.security.authentication.DirectCookieAuthProvider.PARAMETER_ULOGIN;

@Api(tags = "placements")
@RestController
@RequestMapping(value = "placements", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class PlacementController {

    private final PlacementsService placementsService;
    private final DirectWebAuthenticationSource authenticationSource;

    @Autowired
    public PlacementController(PlacementsService placementsService,
            DirectWebAuthenticationSource authenticationSource) {
        this.placementsService = placementsService;
        this.authenticationSource = authenticationSource;
    }

    @ApiOperation(
            value = "Get placements with blocks filtered by filter",
            httpMethod = "GET",
            notes = "В outdoor-блоках geoId и адрес могут быть равны null, это нужно учитывать и не фейлиться. "
                    + "Причем эти блоки уже могут быть выбраны рекламодателем, "
                    + "и в этом случае их точно нужно отображать."
    )
    @ApiResponses(@ApiResponse(code = 200, message = "Ok", response = PlacementsResponse.class))
    @RequestMapping(path = "/", method = RequestMethod.GET)
    public PlacementsResponse getPlacements(PlacementsFilter placementsFilter,
            @RequestParam(value = PARAMETER_ULOGIN, required = false) String subjectUser) {
        ClientId clientId = authenticationSource.getAuthentication().getSubjectUser().getClientId();
        PlacementsResponse response = placementsService.getPlacements(placementsFilter, clientId);

        // зануляем переводы чтобы фронт не вздумал их использовать
        List<? extends PlacementBlock> blocks = clearAddressTranslations(response.getPlacementBlocks());
        List<Placement> placements = response.getPlacements().stream()
                .map(placement -> placement.replaceBlocks(clearAddressTranslations(placement.getBlocks())))
                .collect(Collectors.toList());
        response.withPlacementBlocks(blocks)
                .withPlacements(placements);

        return response;
    }

    private List<? extends PlacementBlock> clearAddressTranslations(List<? extends PlacementBlock> blocks) {
        return blocks.stream()
                .map(block -> {
                    if (!(block instanceof GeoBlock)) {
                        return block;
                    }
                    GeoBlock<?> geoBlock = (GeoBlock<?>) block;
                    return (PlacementBlock) geoBlock.withAddressTranslations(null);
                })
                .collect(Collectors.toList());
    }
}
