package de.votian.services.controller;

import de.votian.services.dto.DispositionJobRowDto;
import de.votian.services.dto.DispositionStationDto;
import de.votian.services.dto.DispositionVehicleRowDto;
import de.votian.services.dto.UserSessionDto;
import de.votian.services.security.AccessControlService;
import de.votian.services.service.DispositionService;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDate;
import java.util.List;

@RestController
@RequestMapping("/api/disposition")
public class DispositionController {

    private final DispositionService dispositionService;
    private final AccessControlService accessControlService;

    public DispositionController(DispositionService dispositionService,
                                 AccessControlService accessControlService) {
        this.dispositionService = dispositionService;
        this.accessControlService = accessControlService;
    }

    @GetMapping("/jobs")
    public ResponseEntity<List<DispositionJobRowDto>> getJobs(
            @RequestParam Long hqId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate day,
            Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canViewDisposition(user) || !accessControlService.canAccessHeadquarters(user, hqId)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        return ResponseEntity.ok(dispositionService.findJobsForDay(hqId, day));
    }

    @GetMapping("/vehicles")
    public ResponseEntity<List<DispositionVehicleRowDto>> getVehicles(
            @RequestParam Long hqId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate day,
            Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canViewDisposition(user) || !accessControlService.canAccessHeadquarters(user, hqId)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        return ResponseEntity.ok(dispositionService.findVehiclesForDay(hqId, day));
    }

    @GetMapping("/stations")
    public ResponseEntity<List<DispositionStationDto>> getStations(
            @RequestParam Long hqId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate day,
            Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canViewDisposition(user) || !accessControlService.canAccessHeadquarters(user, hqId)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        return ResponseEntity.ok(dispositionService.findStationsForDay(hqId, day));
    }

    @PutMapping("/jobs/{jobId}/assignment")
    public ResponseEntity<DispositionJobRowDto> assignVehicle(
            @PathVariable Long jobId,
            @RequestParam Long hqId,
            @RequestBody AssignmentRequest request,
            Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canManageDisposition(user) || !accessControlService.canAccessHeadquarters(user, hqId)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        return ResponseEntity.ok(dispositionService.assignVehicle(
                hqId,
                jobId,
                request != null ? request.courierId : null,
                request != null ? request.courierVehicleId : null
        ));
    }

    @DeleteMapping("/jobs/{jobId}/assignment")
    public ResponseEntity<Void> clearVehicleAssignment(
            @PathVariable Long jobId,
            @RequestParam Long hqId,
            Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canManageDisposition(user) || !accessControlService.canAccessHeadquarters(user, hqId)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        dispositionService.clearVehicleAssignment(hqId, jobId);
        return ResponseEntity.ok().build();
    }

    public static class AssignmentRequest {
        public Long courierId;
        public Long courierVehicleId;
    }
}
