package de.avatic.lcc.controller.configuration;

import de.avatic.lcc.dto.configuration.material.update.MaterialUpdateDTO;
import de.avatic.lcc.dto.configuration.material.view.MaterialDetailDTO;
import de.avatic.lcc.dto.generic.MaterialDTO;
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
import de.avatic.lcc.service.access.MaterialService;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Size;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/materials")
@Validated
public class MaterialController {


    private final MaterialService materialService;

    @Autowired
    public MaterialController(MaterialService materialService) {
        this.materialService = materialService;
    }

    /**
     * List all materials with pagination support.
     *
     * @param limit  Maximum number of items to return (default: 20)
     * @param page   Page number for pagination (default: 0)
     * @param filter Optional search filter (default: empty string)
     * @return A list of material summaries. Pagination details are returned in response headers:
     * X-Total-Count (total elements), X-Page-Count (total pages), and X-Current-Page (current page).
     */
    @GetMapping("/")
    @PreAuthorize("hasAnyRole('SUPER', 'CALCULATION', 'BASIC', 'FREIGHT', 'PACKAGING', 'MATERIAL')")
    public ResponseEntity<List<MaterialDTO>> listMaterials(
            @RequestParam(defaultValue = "true") String excludeDeprecated,
            @RequestParam(defaultValue = "20") @Min(1) int limit,
            @RequestParam(defaultValue = "1") @Min(1) int page,
            @RequestParam(required = false) Optional<String> filter) {

        SearchQueryResult<MaterialDTO> materials = materialService.listMaterial(filter, page, limit, Boolean.parseBoolean(excludeDeprecated));

        return ResponseEntity.ok()
                .header("X-Total-Count", String.valueOf(materials.getTotalElements()))
                .header("X-Page-Count", String.valueOf(materials.getTotalPages()))
                .header("X-Current-Page", String.valueOf(page))
                .body(materials.toList());
    }

    /**
     * Get detailed information about a specific material.
     *
     * @param id Material ID
     * @return Detailed information about the material
     * @throws RuntimeException if the material with the given ID is not found.
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAnyRole('SUPER', 'CALCULATION', 'BASIC', 'FREIGHT', 'PACKAGING', 'MATERIAL')")
    public ResponseEntity<MaterialDetailDTO> getMaterialDetails(@PathVariable Integer id) {
        return ResponseEntity.ok(materialService.getMaterial(id));
    }

    @PutMapping({"/", ""})
    @PreAuthorize("hasRole('MATERIAL')")
    public ResponseEntity<Void> updateMaterial(List<@Size(max = 100, min = 1) MaterialUpdateDTO> materials) {
        materialService.updateMaterial(materials);
        return ResponseEntity.ok().build();
    }
}