package com.bcxin.api.controllers;

import cn.myapps.common.data.DataPackage;
import cn.myapps.common.model.task.Task;
import cn.myapps.common.model.workflow.BillDefiVO;
import cn.myapps.designtime.application.service.ApplicationDesignTimeService;
import cn.myapps.designtime.common.service.DesignTimeServiceManager;
import cn.myapps.designtime.task.service.TaskDesignTimeService;
import cn.myapps.designtime.workflow.definition.service.BillDefiDesignTimeService;
import com.bcxin.requests.FlowDefinitionRequest;
import com.bcxin.responses.FlowDefinitionResponse;
import com.bcxin.responses.AppDefinitionResponse;
import com.bcxin.responses.TaskDefinitionResponse;
import com.bcxin.runtime.apis.controllers.ControllerAbstract;
import com.bcxin.saas.core.utils.ExceptionUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

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

@RestController("v2_meta_controller")
@RequestMapping("/api/v2/runtime/definitions/apps")
public class DefinitionController extends ControllerAbstract {
    private final ApplicationDesignTimeService applicationDesignTimeService;
    private final TaskDesignTimeService taskDesignTimeService;
    private final BillDefiDesignTimeService billDefiDesignTimeService;

    public DefinitionController() {
        this.applicationDesignTimeService = DesignTimeServiceManager.applicationDesignTimeService();
        this.taskDesignTimeService = DesignTimeServiceManager.taskDesignTimeService();
        this.billDefiDesignTimeService = DesignTimeServiceManager.billDefiDesignTimeService();
    }

    @GetMapping
    public ResponseEntity<Collection<AppDefinitionResponse>> getApps() throws Exception {
        String result = "";
        try {
            List<cn.myapps.common.model.application.Application> apps =
                    this.applicationDesignTimeService.list(null, null);

            Collection<AppDefinitionResponse> appDefinitionResponses =
                    apps.stream().map(ii -> AppDefinitionResponse.create(ii.getId(), ii.getName())).collect(Collectors.toList());
            result = "执行完毕";
            return ResponseEntity.ok(appDefinitionResponses);
        } catch (Exception ex) {
            result = ExceptionUtils.getStackMessage(ex);
            throw ex;
        } finally {
            System.err.println(String.format("获取应用列表/apps:结果=%s;", result));
        }
    }

    @GetMapping("/{appId}/tasks")
    public ResponseEntity<Collection<TaskDefinitionResponse>> getTasks(@PathVariable String appId) throws Exception {
        DataPackage<Task> data = taskDesignTimeService.queryByNameOrDescript(appId, "", 1, Integer.MAX_VALUE);

        Collection<TaskDefinitionResponse> taskResponses =
                data.getDatas().stream().map(ii ->
                        TaskDefinitionResponse.create(ii.getApplicationid(), ii.getId(), ii.getName(), ii.getTaskScript(),
                                ii.getRunningTime(), ii.getModifyTime(),
                                ii.getExecutedCount(),
                                ii.getFrequency())
                ).collect(Collectors.toList());

        return ResponseEntity.ok(taskResponses);
    }

    @GetMapping("/{appId}/flows")
    public ResponseEntity<Collection<FlowDefinitionResponse>> getFlows(@PathVariable String appId) throws Exception {
        Collection<BillDefiVO> allFlows = this.billDefiDesignTimeService.list(null, null);

        Collection<FlowDefinitionResponse> flowDefinitionResponses = allFlows.stream()
                .filter(ii -> ii.getApplicationid().equalsIgnoreCase(appId))
                .map(ii ->
                        FlowDefinitionResponse.create(ii.getApplicationid(),
                                ii.getId(), ii.getName(), ii.getSubject(),
                                ii.getFlow()))
                .collect(Collectors.toList());

        return ok(flowDefinitionResponses);
    }

    @PutMapping("/{appId}/flows/{id}")
    public ResponseEntity putFlow(@PathVariable String appId, @PathVariable String id, @RequestBody FlowDefinitionRequest request) throws Exception {
        Optional<BillDefiVO> billDefiVOOptional =
                this.billDefiDesignTimeService.list(null, null).stream()
                        .filter(ii -> ii.getApplicationid().equalsIgnoreCase(appId) && ii.getId().equalsIgnoreCase(id))
                        .findFirst();

        if (!billDefiVOOptional.isPresent()) {
            return notFound(String.format("找不到流程(%s)", id));
        }

        BillDefiVO billDefiVO = billDefiVOOptional.get();
        billDefiVO.setFlow(request.getFlow());
        billDefiVO.setName(request.getName());
        billDefiVO.setSubject(request.getSubject());
        this.billDefiDesignTimeService.update(billDefiVO);

        return ok("更新完毕");
    }
}
