package net.zstong.awump.monitoring.web;


import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.zstong.awump.monitoring.entity.AwMonitoringAreaEntity;
import net.zstong.awump.monitoring.service.AwMonitoringAreaService;
import org.hswebframework.web.api.crud.entity.QueryNoPagingOperation;
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
import org.hswebframework.web.api.crud.entity.TreeSupportEntity;
import org.hswebframework.web.authorization.Authentication;
import org.hswebframework.web.authorization.annotation.Authorize;
import org.hswebframework.web.authorization.annotation.Resource;
import org.hswebframework.web.authorization.annotation.SaveAction;
import org.hswebframework.web.crud.service.ReactiveCrudService;
import org.hswebframework.web.crud.web.reactive.ReactiveServiceCrudController;
import org.hswebframework.web.exception.NotFoundException;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping({"/aw/monitoring/area"})
@Slf4j
@Tag(name = "监控区域信息管理")
@AllArgsConstructor
@Resource(id = "aw-base-region", name = "监控区域信息管理")
public class AwMonitoringAreaController implements ReactiveServiceCrudController<AwMonitoringAreaEntity, String> {


    private final AwMonitoringAreaService awMonitoringAreaService;


    @Override
    public ReactiveCrudService<AwMonitoringAreaEntity, String> getService() {
        return awMonitoringAreaService;
    }


    @GetMapping
    @QueryNoPagingOperation(summary = "获取全部区域")
    @Authorize(merge = false)
    public Flux<AwMonitoringAreaEntity> getAllCategory(@Parameter(hidden = true) QueryParamEntity query) {
        return this
            .awMonitoringAreaService
            .createQuery()
            .setParam(query)
            .fetch();
    }

    @GetMapping("/_tree")
    @QueryNoPagingOperation(summary = "获取全部区域(树结构)")
    @Authorize(merge = false)
    public Flux<AwMonitoringAreaEntity> getAllCategoryTree(@Parameter(hidden = true) QueryParamEntity query) {
        return this
            .awMonitoringAreaService
            .createQuery()
            .setParam(query)
            .fetch()
            .collectList()
            .flatMapMany(all -> {
                return Flux.fromIterable(TreeSupportEntity.list2tree(all, AwMonitoringAreaEntity::setChildren));
            });
    }

    @PostMapping("/_tree")
    @QueryNoPagingOperation(summary = "获取全部区域(树结构)")
    @Authorize(merge = false)
    public Flux<AwMonitoringAreaEntity> getAllCategoryTreeByQueryParam(@RequestBody Mono<QueryParamEntity> query) {
        return this.awMonitoringAreaService.getAllCategoryTreeByQueryParam(query);
    }


    @PutMapping({"/{id}"})
    @SaveAction
    @Operation(
        summary = "根据ID修改数据"
    )
    public Mono<Boolean> update(@PathVariable String id, @RequestBody Mono<AwMonitoringAreaEntity> payload) {
        return Authentication.currentReactive().flatMap((auth) -> {
            return payload.map((entity) -> {
                return this.applyAuthentication(entity, auth);
            });
        }).switchIfEmpty(payload).flatMap((entity) -> {
            return this.getService().updateById(id, Mono.just(entity));
        }).doOnNext((i) -> {
            if (i == 0) {
                throw new NotFoundException();
            }
        }).thenReturn(true);
    }

}
