package com.purui.prims.headless.server.rest.api;

import com.purui.prims.auth.api.authentication.pojo.User;
import com.purui.prims.common.pojo.ResultData;
import com.purui.prims.common.pojo.enums.QueryType;
import com.purui.prims.headless.api.pojo.enums.AppAuthType;
import com.purui.prims.headless.api.pojo.request.QueryDataSetReq;
import com.purui.prims.headless.api.pojo.request.QueryMetricReq;
import com.purui.prims.headless.api.pojo.request.QueryStructReq;
import com.purui.prims.headless.api.pojo.request.SemanticQueryReq;
import com.purui.prims.headless.api.pojo.response.AppDetailResp;
import com.purui.prims.headless.api.pojo.response.SemanticQueryResp;
import com.purui.prims.headless.server.annotation.ApiHeaderCheck;
import com.purui.prims.headless.server.service.AppService;
import com.purui.prims.headless.server.service.DataSetService;
import com.purui.prims.headless.server.service.MetricService;
import com.purui.prims.headless.server.service.SemanticLayerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PathVariable;
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.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * OpenAPI 对外提供接口类
 *
 * @author charlie
 * @date 2024/6/19
 */
@RestController
@RequestMapping("/api/openapi")
@Slf4j
public class OpenApiController {

    private static final String APPID = "appId";

    final AppService appService;

    final MetricService metricService;

    final DataSetService dataSetService;

    final SemanticLayerService queryService;

    public OpenApiController(AppService appService, SemanticLayerService queryService, DataSetService dataSetService,
                             MetricService metricService) {
        this.appService = appService;
        this.queryService = queryService;
        this.dataSetService = dataSetService;
        this.metricService = metricService;
    }

    // 查询所有可访问的指标
    @ApiHeaderCheck
    @PostMapping("/metrics")
    public ResultData<String> getMetrics(String params, HttpServletRequest request) {

        return ResultData.success("总金额");
    }

    // 查询某个指标
    @ApiHeaderCheck
    @PostMapping("/metric/{id}")
    public ResultData<Object> getMetric(@PathVariable Long id, HttpServletRequest request, @RequestBody QueryMetricReq queryMetricReq) {
        String appId = request.getHeader(APPID);
        if (!checkAppMetricsPermission(appId, id)) {
            return ResultData.fail(401, "无权限");
        }

        if (queryMetricReq == null || CollectionUtils.isEmpty(queryMetricReq.getMetricIds())) {
            queryMetricReq = metricService.newQueryMetricReq(id);
        }
        QueryStructReq queryStructReq = metricService.convert(queryMetricReq);
        try {
            SemanticQueryResp queryResp = queryService.queryByReq(queryStructReq.convert(true), User.getFakeUser());
            return ResultData.success(queryResp);
        } catch (Exception e) {
            return ResultData.fail(500, e.getMessage());
        }
    }

    // 查询某个数据集
    @ApiHeaderCheck
    @PostMapping("/dataset/{id}")
    public ResultData getDataset(@PathVariable Long id, HttpServletRequest request) {
        String appId = request.getHeader(APPID);
        if (!checkAppDatasetPermission(appId, id)) {
            return ResultData.fail(401, "无权限");
        }

        QueryDataSetReq queryDataSetReq = new QueryDataSetReq();
        queryDataSetReq.setDataSetId(id);
        queryDataSetReq.setQueryType(QueryType.METRIC);
        try {
            SemanticQueryReq queryReq = dataSetService.convert(queryDataSetReq);
            Object data = queryService.queryByReq(queryReq, User.getFakeUser());
            return ResultData.success(data);
        } catch (Exception e) {
            return ResultData.fail(500, e.getMessage());
        }
    }

    private boolean checkAppDatasetPermission(String appId, Long id) {
        AppDetailResp app = appService.getApp(appId);
        if (app == null) {
            return false;
        }
        return appService.checkPermission(app, AppAuthType.DATASET, id);
    }

    private boolean checkAppMetricsPermission(String appId, Long metricId) {
        AppDetailResp app = appService.getApp(appId);
        if (app == null) {
            return false;
        }
        return appService.checkPermission(app, AppAuthType.METRIC, metricId);
    }

}
