package at.procon.eventhub.yellowfox.service;

import at.procon.eventhub.dto.EventSourceDto;
import at.procon.eventhub.importing.AbstractImportExecutionService;
import at.procon.eventhub.importing.ImportPlanDto;
import at.procon.eventhub.importing.ImportPlanItemDto;
import at.procon.eventhub.importing.ImportRunResultDto;
import at.procon.eventhub.importing.ImportTimeChunkDto;
import at.procon.eventhub.importing.persistence.ImportCursorRepository;
import at.procon.eventhub.importing.persistence.ImportRunRepository;
import at.procon.eventhub.persistence.DataPackageRepository;
import at.procon.eventhub.persistence.EventSourceRepository;
import at.procon.eventhub.yellowfox.dto.YellowFoxD8ExtractionBatchResultDto;
import at.procon.eventhub.yellowfox.dto.YellowFoxD8ImportRequest;
import at.procon.eventhub.yellowfox.dto.YellowFoxD8ImportRunResultDto;
import java.util.Map;
import java.util.UUID;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class YellowFoxD8ImportExecutionService
        extends AbstractImportExecutionService<YellowFoxD8ImportRequest, YellowFoxD8ExtractionBatchResultDto> {

    private final YellowFoxD8ImportPlanService planService;
    private final YellowFoxMasterDataRefreshService masterDataRefreshService;
    private final YellowFoxD8ExtractionBatchExecutor extractionBatchExecutor;

    public YellowFoxD8ImportExecutionService(
            YellowFoxD8ImportPlanService planService,
            EventSourceRepository eventSourceRepository,
            ImportRunRepository importRunRepository,
            DataPackageRepository dataPackageRepository,
            ImportCursorRepository importCursorRepository,
            YellowFoxMasterDataRefreshService masterDataRefreshService,
            YellowFoxD8ExtractionBatchExecutor extractionBatchExecutor
    ) {
        super(eventSourceRepository, importRunRepository, dataPackageRepository, importCursorRepository);
        this.planService = planService;
        this.masterDataRefreshService = masterDataRefreshService;
        this.extractionBatchExecutor = extractionBatchExecutor;
    }

    @Transactional
    public YellowFoxD8ImportRunResultDto startImport(YellowFoxD8ImportRequest request) {
        return toYellowFoxResult(createImportRun(request, false));
    }

    public YellowFoxD8ImportRunResultDto startAndExecuteImport(YellowFoxD8ImportRequest request) {
        return toYellowFoxResult(createImportRun(request, true));
    }

    @Override
    protected ImportPlanDto createPlan(YellowFoxD8ImportRequest request) {
        return planService.createPlan(request);
    }

    @Override
    protected YellowFoxD8ExtractionBatchResultDto executeBatch(
            UUID importRunId,
            UUID packageId,
            int eventSourceId,
            YellowFoxD8ImportRequest request,
            ImportPlanItemDto planItem,
            ImportTimeChunkDto chunk
    ) {
        return extractionBatchExecutor.execute(importRunId, packageId, eventSourceId, request, planItem, chunk);
    }

    @Override
    protected void beforeExecute(YellowFoxD8ImportRequest request) {
        masterDataRefreshService.refreshIfRequested(request);
    }

    @Override
    protected EventSourceDto eventSourceForItem(EventSourceDto base, ImportPlanItemDto item) {
        return new EventSourceDto(
                "YELLOWFOX",
                item.sourceKind(),
                "YELLOWFOX_D8",
                base.sourceInstanceKey(),
                base.tenantProviderSettingKey(),
                base.externalFleetKey()
        );
    }

    @Override
    protected Map<String, Object> importRunMetadata(YellowFoxD8ImportRequest request, boolean executeImmediately) {
        return Map.of(
                "note", executeImmediately
                        ? "Created YellowFox D8 import run and executing planned extraction packages."
                        : "Created YellowFox D8 import run and planned extraction packages.",
                "packageModel", "EventHub data packages are YellowFox D8 extraction batches; source rows are idempotent by EVENTID+UTC.",
                "executeImmediately", executeImmediately,
                "officialD8Semantics", "eventtype 0/1 card slot DRIVER/CO_DRIVER; eventtype 2/3 activity slot DRIVER/CO_DRIVER; ignition is a state column."
        );
    }

    @Override
    protected String providerPackagePrefix() {
        return "YELLOWFOX_D8";
    }

    @Override
    protected Map<String, Object> packageMetadata(
            YellowFoxD8ImportRequest request,
            ImportPlanItemDto item,
            ImportTimeChunkDto chunk,
            UUID importRunId
    ) {
        Map<String, Object> metadata = super.packageMetadata(request, item, chunk, importRunId);
        metadata.put("cursor", "SOURCE_ROW_WATERMARK using utc + eventid");
        metadata.put("slotPolicy", "eventtype 0/2 = DRIVER, eventtype 1/3 = CO_DRIVER");
        metadata.put("ignitionPolicy", "Store ignition state on every D8 detail; emit separate ignition event only on state change.");
        return metadata;
    }

    private YellowFoxD8ImportRunResultDto toYellowFoxResult(ImportRunResultDto result) {
        return new YellowFoxD8ImportRunResultDto(
                result.importRunId(),
                result.status(),
                result.plannedPackageCount(),
                result.plan(),
                result.plannedPackageIds()
        );
    }
}
