package ink.wgink.gateway.handler.route.request;

import ink.wgink.gateway.dao.route.request.IResponseHeaderDao;
import ink.wgink.gateway.enums.FilterRequestResponseTypeEnum;
import ink.wgink.gateway.exception.ParamsException;
import ink.wgink.gateway.exception.SearchException;
import ink.wgink.gateway.handler.BaseHandler;
import ink.wgink.gateway.pojo.result.SuccessResult;
import ink.wgink.gateway.pojo.route.request.ResponseHeader;
import ink.wgink.gateway.util.RequestFieldCheckUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: ResponseHeaderHandler
 * @Description: 响应头处理
 * @Author: WangGeng
 * @Date: 2021/5/30 17:00
 * @Version: 1.0
 **/
@Service
public class ResponseHeaderHandler extends BaseHandler {

    private IResponseHeaderDao responseHeaderDao;

    public ResponseHeaderHandler(IResponseHeaderDao responseHeaderDao) {
        this.responseHeaderDao = responseHeaderDao;
    }

    public Mono<ServerResponse> save(ServerRequest serverRequest) {
        Mono<ResponseHeader> requestHeaderMono = serverRequest.bodyToMono(ResponseHeader.class);
        return requestHeaderMono.flatMap(responseHeader -> {
            RequestFieldCheckUtil.check(responseHeader);
            if (!StringUtils.equals(FilterRequestResponseTypeEnum.REMOVE.getValue(), responseHeader.getType()) && StringUtils.isBlank(responseHeader.getValue())) {
                return Mono.error(new ParamsException("值不能为空"));
            }
            setSave(responseHeader);

            ResponseHeader responseHeaderExample = new ResponseHeader();
            responseHeaderExample.setName(responseHeader.getName().trim());
            ExampleMatcher exampleMatcher = ExampleMatcher.matching().withMatcher("name", ExampleMatcher.GenericPropertyMatcher::exact).withIgnoreCase("id");
            Example example = Example.of(responseHeaderExample, exampleMatcher);
            return responseHeaderDao.findOne(example).flatMap(
                    r -> Mono.error(new SearchException("参数已经存在"))
            ).switchIfEmpty(responseHeaderDao.save(responseHeader));
        }).then(ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8).body(Flux.just(new SuccessResult()), SuccessResult.class));
    }

    public Mono<ServerResponse> delete(ServerRequest serverRequest) {
        String ids = serverRequest.pathVariable("ids");
        List<String> idList = Arrays.asList(ids.split(","));
        return responseHeaderDao.findAllById(idList).flatMap(requestHeader -> responseHeaderDao.delete(requestHeader)).then(ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8).body(Mono.just(new SuccessResult()), SuccessResult.class));
    }

    public Mono<ServerResponse> list(ServerRequest serverRequest) {
        String routeId = serverRequest.pathVariable("routeId");
        Optional<String> keywords = serverRequest.queryParam("keywords");
        Optional<String> type = serverRequest.queryParam("type");

        ResponseHeader responseHeaderExample = new ResponseHeader();
        responseHeaderExample.setRouteId(routeId);

        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withMatcher("routeId", ExampleMatcher.GenericPropertyMatcher::exact)
                .withIgnoreCase("id");
        if (keywords.isPresent()) {
            responseHeaderExample.setName(keywords.get().trim());
            exampleMatcher.withMatcher("name", ExampleMatcher.GenericPropertyMatcher::contains);
        }
        if (type.isPresent()) {
            responseHeaderExample.setType(type.get().trim());
            exampleMatcher.withMatcher("type", ExampleMatcher.GenericPropertyMatcher::exact);
        }
        Example example = Example.of(responseHeaderExample, exampleMatcher);
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8).body(responseHeaderDao.findAll(example), ResponseHeader.class);
    }

    public Mono<ServerResponse> get(ServerRequest serverRequest) {
        String id = serverRequest.pathVariable("id");
        return responseHeaderDao.findById(id).flatMap(
                requestHeader -> ServerResponse.ok().body(Mono.just(requestHeader), ResponseHeader.class)
        ).switchIfEmpty(ServerResponse.notFound().build());
    }

}
