package de.avatic.lcc.controller.users;


import de.avatic.lcc.dto.users.UserContainerDTO;
import de.avatic.lcc.dto.users.UserDTO;
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
import de.avatic.lcc.service.users.UserService;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
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.Optional;

/**
 * REST Controller for managing user-related operations.
 * This controller provides endpoints for listing users and updating user details.
 */
@RestController
@RequestMapping("/api/users")
@Validated
public class UserController {


    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    /**
     * Retrieves a paginated list of users.
     *
     * @param limit The maximum number of users to return, with a default value of 20.
     * @param page  The page number of the users to retrieve, with a default value of 0.
     * @return A ResponseEntity containing the list of users, along with pagination headers.
     */
    @GetMapping({"/", ""})
    @PreAuthorize("hasRole('RIGHT-MANAGEMENT')")
    public ResponseEntity<UserContainerDTO> listUsers(
            @RequestParam(defaultValue = "20") @Min(1) int limit,
            @RequestParam(defaultValue = "1") @Min(1) int page) {

        SearchQueryResult<UserDTO> users = userService.listUsers(page, limit);

        var container = new UserContainerDTO();
        container.setUsers( users.toList());

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



    @PostMapping({"/{workdayId}/groups/{group}/", "/{workdayId}/groups/{group}"})
    @PreAuthorize("hasRole('RIGHT-MANAGEMENT')")
    public ResponseEntity<Void> appendGroups(@PathVariable String workdayId, @PathVariable String group) {

        userService.appendGroups(workdayId, group);
        return ResponseEntity.ok().build();
    }

    @DeleteMapping({"/{workdayId}/groups/{group}/", "/{workdayId}/groups/{group}"})
    @PreAuthorize("hasRole('RIGHT-MANAGEMENT')")
    public ResponseEntity<Void> deleteGroups(@PathVariable String workdayId, @PathVariable String group) {

        userService.deleteGroups(workdayId, group);
        return ResponseEntity.ok().build();
    }

    /**
     * Retrieves a single user by its workday id.
     *
     * @param workdayId The workday id of the user to retrieve.
     * @return A ResponseEntity containing the user, along with pagination headers.
     */
    @GetMapping({"/{workdayId}/", "/{workdayId}"})
    @PreAuthorize("hasRole('RIGHT-MANAGEMENT')")
    public ResponseEntity<Optional<UserDTO>> getUser(@PathVariable String workdayId) {

        Optional<UserDTO> users = userService.getUser(workdayId);

        return ResponseEntity.ok()
                .body(users);
    }



    /**
     * Updates the details of an existing user or creates a new one if it does not exist.
     * Users are identified by its workday id. If a group from the group membership does not exist
     * it is simply ignored.
     *
     * @param user A UserDTO object containing the updated user details.
     * @return A ResponseEntity indicating the operation was successful.
     */
    @PutMapping({"/", ""})
    @PreAuthorize("hasRole('RIGHT-MANAGEMENT')")
    public ResponseEntity<Void> updateUser(@Valid @RequestBody UserDTO user) {
        userService.updateUser(user);
        return ResponseEntity.ok().build();
    }
}
