package com.ruoyi.interfaces.workflow.executor;

import com.ruoyi.common.utils.JsonUtils;
import com.ruoyi.interfaces.domain.MdModelStep;
import com.ruoyi.interfaces.domain.MdModelStepExecution;
import com.ruoyi.interfaces.service.MdModelStepExecutionService;
import com.ruoyi.interfaces.workflow.ExecutionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.Map;

/**
 * @author LinQiLong
 * @date 2025/7/17 10:08
 */
@Slf4j
@Component
public class DbStepExecutor implements StepExecutor {

    @Autowired
    private MdModelStepExecutionService stepExecutionService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public MdModelStep.StepType getSupportedStepType() {
        return MdModelStep.StepType.DB;
    }

    @Override
    public MdModelStepExecution execute(MdModelStep step, ExecutionContext context) {
        MdModelStepExecution stepExecution = new MdModelStepExecution();
        stepExecution.setExecutionId(context.getWorkflowId());
        stepExecution.setStepId(step.getId());
        stepExecution.setStepName(step.getName());
        stepExecution.setStepType(MdModelStep.StepType.API);
        stepExecution.markStart();
        stepExecutionService.saveOrUpdate(stepExecution);

        Map<String, Object> config = (Map<String, Object>) JsonUtils.jsonToPojo(step.getConfig(), Map.class);

        // 1. 准备SQL
        String sql = context.renderTemplate(config.get("sql").toString());

        // 2. 执行SQL
        try {
            if (isQuery(sql)) {
                Map<String, Object> jdbcResult = jdbcTemplate.queryForMap(sql);
                stepExecution.markSuccess(jdbcResult);
            } else {
                int affectedRows = jdbcTemplate.update(sql);
                Map<String, Object> jdbcResult = Collections.singletonMap("affectedRows", affectedRows);
                stepExecution.markSuccess(jdbcResult);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            stepExecution.markFailed(e.getMessage());
        }

        return stepExecution;
    }

    private boolean isQuery(String sql) {
        return sql.trim().toLowerCase().startsWith("select");
    }
}
