package de.votian.services.controller;

import de.votian.services.dto.UserSessionDto;
import de.votian.services.dto.WarehouseArticleOptionDto;
import de.votian.services.dto.WarehouseBootstrapDto;
import de.votian.services.dto.WarehouseInventoryRowDto;
import de.votian.services.dto.WarehouseJournalEntryDto;
import de.votian.services.dto.WarehouseMoveRequest;
import de.votian.services.dto.WarehouseSerialItemDto;
import de.votian.services.dto.WarehouseStockNodeDto;
import de.votian.services.security.AccessControlService;
import de.votian.services.service.WarehouseService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
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/warehouse")
public class WarehouseController {

    private final WarehouseService warehouseService;
    private final AccessControlService accessControlService;

    public WarehouseController(WarehouseService warehouseService, AccessControlService accessControlService) {
        this.warehouseService = warehouseService;
        this.accessControlService = accessControlService;
    }

    @GetMapping("/bootstrap")
    public ResponseEntity<WarehouseBootstrapDto> bootstrap(Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canViewWarehouse(user)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        return ResponseEntity.ok(warehouseService.loadBootstrap(user));
    }

    @GetMapping("/stocks")
    public ResponseEntity<List<WarehouseStockNodeDto>> stocks(@RequestParam Long rootStockId,
                                                              Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canViewWarehouse(user)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        return ResponseEntity.ok(warehouseService.loadStocks(user, rootStockId));
    }

    @GetMapping("/articles")
    public ResponseEntity<List<WarehouseArticleOptionDto>> articles(@RequestParam(required = false) Long rootStockId,
                                                                    Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canViewWarehouse(user)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        return ResponseEntity.ok(warehouseService.loadArticleOptions(user, rootStockId));
    }

    @GetMapping("/inventory")
    public ResponseEntity<List<WarehouseInventoryRowDto>> inventory(@RequestParam Long stockId,
                                                                    @RequestParam(defaultValue = "true") boolean includeSubstocks,
                                                                    @RequestParam(required = false) String search,
                                                                    Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canViewWarehouse(user)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        return ResponseEntity.ok(warehouseService.loadInventory(user, stockId, includeSubstocks, search));
    }

    @GetMapping("/serials")
    public ResponseEntity<List<WarehouseSerialItemDto>> serials(@RequestParam Long stockId,
                                                                @RequestParam(defaultValue = "true") boolean includeSubstocks,
                                                                @RequestParam Long articleId,
                                                                @RequestParam(required = false) String search,
                                                                Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canViewWarehouse(user)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        return ResponseEntity.ok(warehouseService.loadSerialItems(user, stockId, includeSubstocks, articleId, search));
    }

    @GetMapping("/journal")
    public ResponseEntity<List<WarehouseJournalEntryDto>> journal(@RequestParam Long rootStockId,
                                                                  @RequestParam(required = false) Long stockFromId,
                                                                  @RequestParam(required = false) Long stockToId,
                                                                  @RequestParam(required = false) Long articleId,
                                                                  @RequestParam(required = false) LocalDate from,
                                                                  @RequestParam(required = false) LocalDate to,
                                                                  @RequestParam(required = false) String search,
                                                                  Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canViewWarehouse(user)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        return ResponseEntity.ok(warehouseService.loadJournal(user, rootStockId, stockFromId, stockToId, articleId, from, to, search));
    }

    @PostMapping("/moves")
    public ResponseEntity<Void> move(@RequestBody WarehouseMoveRequest request, Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canViewWarehouse(user)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        warehouseService.moveArticle(user, request);
        return ResponseEntity.ok().build();
    }
}
