package net.zstong.awump.base.web;

import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import net.zstong.awump.base.entity.AwInstitutionEntity;
import net.zstong.awump.base.entity.AwInstitutionInfo;
import net.zstong.awump.base.entity.AwRegionEntity;
import net.zstong.awump.base.service.AwInstitutionService;
import net.zstong.awump.base.service.AwRegionService;
import org.hswebframework.ezorm.rdb.mapping.ReactiveQuery;
import org.hswebframework.web.api.crud.entity.PagerResult;
import org.hswebframework.web.api.crud.entity.QueryOperation;
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
import org.hswebframework.web.api.crud.entity.TreeSupportEntity;
import org.hswebframework.web.authorization.annotation.Authorize;
import org.hswebframework.web.authorization.annotation.QueryAction;
import org.hswebframework.web.authorization.annotation.Resource;
import org.hswebframework.web.crud.service.ReactiveCrudService;
import org.hswebframework.web.crud.web.reactive.ReactiveServiceCrudController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;

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

import static org.hswebframework.reactor.excel.ReactorExcel.read;

@RestController
@RequestMapping({"/aw/base/institution"})
@Resource(id = "aw-base-institution", name = "单位管理接口")
@Tag(name = "单位管理接口")
@Slf4j
public class AwInstitutionController implements ReactiveServiceCrudController<AwInstitutionEntity, String> {

    @Autowired
    private AwInstitutionService awInstitutionService;

    @Autowired
    private AwRegionService awRegionService;

    @Override
    public ReactiveCrudService<AwInstitutionEntity, String> getService() {
        return awInstitutionService;
    }


    @GetMapping({"/_query"})
    @QueryAction
    @QueryOperation(
        summary = "使用GET方式分页动态查询(Override)"
    )
    public Mono<PagerResult<AwInstitutionEntity>> queryPager(@Parameter(hidden = true) QueryParamEntity query) {
        return query.getTotal() != null ? (getService().createQuery()
            .setParam(query.rePaging(query.getTotal())))
            .fetch().collectList()
            .map((list) -> {
                System.out.println("============queryPager=============" + list);
                return PagerResult.of(query.getTotal(), list, query);
            }) : this.getService().queryPager(query);
    }

    @PostMapping("/info/_query")
    @QueryAction
    @Operation(summary = "分页查询单位及相关信息详情")
    public Mono<PagerResult<AwInstitutionInfo>> queryInstitution(@RequestBody Mono<QueryParamEntity> paramBody) {
        return paramBody
            .flatMap(param -> awInstitutionService.queryPager(param)
                .flatMap(result -> Flux
                    .fromIterable(result.getData()).flatMap(tp2 -> convert(tp2))
                    .collectList()
                    .map(info -> PagerResult.of(result.getTotal(), info, param))
                )
            );
    }

    private Mono<AwInstitutionInfo> convert(AwInstitutionEntity entity) {
        return awRegionService.findById(entity.getRegionId()).defaultIfEmpty(new AwRegionEntity()).map(a -> {
                AwInstitutionInfo awInstitutionInfo = AwInstitutionInfo.of(entity);
                awInstitutionInfo.setRegion(a);
                return awInstitutionInfo;
            }).flatMap(i -> {
                return awRegionService.findById(i.getRegion().getParentId()).defaultIfEmpty(new AwRegionEntity()).map(b -> {
                    i.setCity(b);
                    return i;
                });
            })
            .flatMap(j -> {
                return awRegionService.findById(j.getCity().getParentId()).defaultIfEmpty(new AwRegionEntity()).map(c -> {
                    j.setProvince(c);
                    return j;
                });
            });
//        return Mono.zip(
//            awRegionService.findById(entity.getRegionId()).defaultIfEmpty(new AwRegionEntity()),
//            Mono.just(AwInstitutionInfo.of(entity))
//        ).map(tp2 -> {
//            tp2.getT2().setRegion(tp2.getT1());
//            return tp2.getT2();
//        });
    }


    @GetMapping("/_all/tree")
    @Authorize(merge = false)
    @Operation(summary = "获取全部区域单位信息(树结构)")
    public Flux<AwRegionEntity> getAllOrgTree() {
        return awInstitutionService.getAllRegionInstitutionTree();
    }
}
