package at.procon.eventhub.processing.eventprocessing.module;

import at.procon.eventhub.processing.dto.UnifiedRuntimeProcessingApiRequest;
import at.procon.eventhub.processing.eventprocessing.plan.RuntimeProcessingModuleDescriptorDto;
import at.procon.eventhub.processing.model.UnifiedRuntimeEventBundle;
import at.procon.eventhub.processing.service.UnifiedRuntimeEventAssemblyService;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import org.springframework.stereotype.Component;

@Component
public class RuntimeEventAssemblyModule implements RuntimeProcessingModule {

    private final UnifiedRuntimeEventAssemblyService eventAssemblyService;

    public RuntimeEventAssemblyModule(UnifiedRuntimeEventAssemblyService eventAssemblyService) {
        this.eventAssemblyService = eventAssemblyService;
    }

    @Override
    public String moduleKey() {
        return DriverWorkingTimeModuleKeys.RUNTIME_EVENT_ASSEMBLY;
    }

    @Override
    public RuntimeProcessingModuleDescriptorDto descriptor() {
        return new RuntimeProcessingModuleDescriptorDto(
                moduleKey(),
                "Runtime event assembly",
                "Loads and merges canonical runtime events from the selected source scope before plan-specific processing.",
                "JAVA",
                Set.of("UnifiedRuntimeEventBundle")
        );
    }

    @Override
    public RuntimeProcessingModuleResult execute(RuntimeProcessingModuleContext context) {
        UnifiedRuntimeProcessingApiRequest scopeRequest = scopeRequest(context);
        UnifiedRuntimeEventBundle bundle = eventAssemblyService.assembleDriverScopedEvents(scopeRequest.toRuntimeRequest());
        Map<String, Object> metadata = new LinkedHashMap<>();
        metadata.put("driverSeedEventCount", bundle.driverSeedEvents().size());
        metadata.put("expandedVehicleEventCount", bundle.expandedVehicleEvents().size());
        metadata.put("mergedEventCount", bundle.mergedEvents().size());
        metadata.put("discoveredVehicleCount", bundle.discoveredVehicles().size());
        return new RuntimeProcessingModuleResult(
                moduleKey(),
                RuntimeProcessingModuleStatus.SUCCESS,
                bundle,
                metadata,
                bundle.notes()
        );
    }

    private UnifiedRuntimeProcessingApiRequest scopeRequest(RuntimeProcessingModuleContext context) {
        Object value = context.attributes().get("runtimeScopeApiRequest");
        if (value instanceof UnifiedRuntimeProcessingApiRequest request) {
            return request;
        }
        return context.request().sourceSelection();
    }
}
