package at.procon.eventhub.esperpoc.api;

import at.procon.eventhub.esperpoc.dto.EsperActivityMergeMode;
import at.procon.eventhub.esperpoc.dto.EsperDtiEnrichmentRequest;
import at.procon.eventhub.esperpoc.dto.EsperDtiEnrichmentResultDto;
import at.procon.eventhub.esperpoc.dto.EsperOperatingPeriodEngineMode;
import at.procon.eventhub.esperpoc.dto.EsperOperatingPeriodRequest;
import at.procon.eventhub.esperpoc.dto.EsperOperatingPeriodResultDto;
import at.procon.eventhub.esperpoc.dto.EsperPocRequest;
import at.procon.eventhub.esperpoc.dto.EsperPocResultDto;
import at.procon.eventhub.esperpoc.dto.EsperShiftResolutionMode;
import at.procon.eventhub.esperpoc.dto.EsperSourceSelectionMode;
import at.procon.eventhub.esperpoc.dto.EsperUnknownTreatmentMode;
import at.procon.eventhub.esperpoc.service.EsperDtiEnrichmentService;
import at.procon.eventhub.esperpoc.service.EsperOperatingPeriodEvaluationService;
import at.procon.eventhub.esperpoc.service.EsperPocDriverCardActivityService;
import java.time.OffsetDateTime;
import java.util.UUID;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/eventhub/esper-poc")
public class EsperPocController {

    private final EsperPocDriverCardActivityService service;
    private final EsperOperatingPeriodEvaluationService operatingPeriodEvaluationService;
    private final EsperDtiEnrichmentService dtiEnrichmentService;

    public EsperPocController(
            EsperPocDriverCardActivityService service,
            EsperOperatingPeriodEvaluationService operatingPeriodEvaluationService,
            EsperDtiEnrichmentService dtiEnrichmentService
    ) {
        this.service = service;
        this.operatingPeriodEvaluationService = operatingPeriodEvaluationService;
        this.dtiEnrichmentService = dtiEnrichmentService;
    }

    @GetMapping("/tachograph/driver-card-activities")
    public ResponseEntity<EsperPocResultDto> evaluateDriverCardActivities(
            @RequestParam String tenantKey,
            @RequestParam UUID driverEntityId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime occurredFrom,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime occurredTo,
            @RequestParam(defaultValue = "24") Integer guardHours,
            @RequestParam(defaultValue = "3") Integer significantDrivingMinutes,
            @RequestParam(defaultValue = "60") Integer mergeGapSeconds,
            @RequestParam(defaultValue = "7") Integer operatingPeriodSplitRestHours,
            @RequestParam(defaultValue = "420") Integer shiftEndMarkPeriodMinutes,
            @RequestParam(defaultValue = "5") Integer absenceBeginEndMinActivityMinutes,
            @RequestParam(required = false) EsperActivityMergeMode activityMergeMode,
            @RequestParam(required = false) EsperShiftResolutionMode shiftResolutionMode
    ) {
        EsperPocRequest request = new EsperPocRequest(
                tenantKey,
                driverEntityId,
                occurredFrom,
                occurredTo,
                guardHours,
                significantDrivingMinutes,
                mergeGapSeconds,
                operatingPeriodSplitRestHours,
                shiftEndMarkPeriodMinutes,
                absenceBeginEndMinActivityMinutes,
                activityMergeMode,
                shiftResolutionMode
        );
        return ResponseEntity.ok(service.evaluate(request));
    }

    @GetMapping("/tachograph/operating-period-evaluation")
    public ResponseEntity<EsperOperatingPeriodResultDto> evaluateOperatingPeriods(
            @RequestParam String tenantKey,
            @RequestParam UUID driverId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime occurredFrom,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime occurredTo,
            @RequestParam(defaultValue = "24") Integer guardHours,
            @RequestParam(required = false) Integer operatingSplitIdleHours,
            @RequestParam(required = false) Integer significantDrivingMinutes,
            @RequestParam(required = false) Integer mergeGapSeconds,
            @RequestParam(required = false) Integer gapDetectionToleranceSeconds,
            @RequestParam(required = false) EsperSourceSelectionMode sourceSelectionMode,
            @RequestParam(required = false) EsperUnknownTreatmentMode unknownTreatmentMode,
            @RequestParam(required = false) EsperOperatingPeriodEngineMode engineMode
    ) {
        EsperOperatingPeriodRequest request = new EsperOperatingPeriodRequest(
                tenantKey,
                driverId,
                occurredFrom,
                occurredTo,
                guardHours,
                operatingSplitIdleHours,
                significantDrivingMinutes,
                mergeGapSeconds,
                gapDetectionToleranceSeconds,
                sourceSelectionMode,
                unknownTreatmentMode,
                engineMode
        );
        return ResponseEntity.ok(operatingPeriodEvaluationService.evaluate(request));
    }

    @GetMapping("/tachograph/dti-enrichment")
    public ResponseEntity<EsperDtiEnrichmentResultDto> evaluateDtiEnrichment(
            @RequestParam String tenantKey,
            @RequestParam UUID driverId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime occurredFrom,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime occurredTo,
            @RequestParam(defaultValue = "24") Integer guardHours,
            @RequestParam(required = false) Integer operatingSplitIdleHours,
            @RequestParam(required = false) Integer significantDrivingMinutes,
            @RequestParam(required = false) Integer mergeGapSeconds,
            @RequestParam(required = false) Integer gapDetectionToleranceSeconds,
            @RequestParam(required = false) EsperSourceSelectionMode sourceSelectionMode,
            @RequestParam(required = false) EsperUnknownTreatmentMode unknownTreatmentMode,
            @RequestParam(required = false) EsperOperatingPeriodEngineMode engineMode,
            @RequestParam(required = false) Integer vehicleEvidenceLookbackHours,
            @RequestParam(required = false) Integer geoSearchWindowMinutes,
            @RequestParam(required = false) Integer vicinityWindowMinutes
    ) {
        EsperDtiEnrichmentRequest request = new EsperDtiEnrichmentRequest(
                tenantKey,
                driverId,
                occurredFrom,
                occurredTo,
                guardHours,
                operatingSplitIdleHours,
                significantDrivingMinutes,
                mergeGapSeconds,
                gapDetectionToleranceSeconds,
                sourceSelectionMode,
                unknownTreatmentMode,
                engineMode,
                vehicleEvidenceLookbackHours,
                geoSearchWindowMinutes,
                vicinityWindowMinutes
        );
        return ResponseEntity.ok(dtiEnrichmentService.evaluate(request));
    }
}
