package com.eactive.testmaster.user.controller;

import com.eactive.testmaster.common.util.SecurityUtil;
import com.eactive.testmaster.user.dto.StaffPasswordChangeRequestDTO;
import com.eactive.testmaster.user.dto.UserRegisterDTO;
import com.eactive.testmaster.user.dto.UserSearch;
import com.eactive.testmaster.user.dto.UserUpdateDTO;
import com.eactive.testmaster.user.entity.StaffUser;
import com.eactive.testmaster.user.mapper.StaffUserMapper;
import com.eactive.testmaster.user.service.StaffUserService;
import java.util.List;
import javax.validation.Valid;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
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;

@RestController
@RequestMapping("/api/users")
public class UserRestController {

    private final StaffUserService staffUserService;
    private final StaffUserMapper staffUserMapper;

    public UserRestController(StaffUserService staffUserService, StaffUserMapper staffUserMapper) {
        this.staffUserService = staffUserService;
        this.staffUserMapper = staffUserMapper;
    }

    @GetMapping
    @Secured("ROLE_MANAGE_USER")
    public ResponseEntity<Page<StaffUser>> listUsers(
        @ModelAttribute UserSearch userSearch,
        @RequestParam(defaultValue = "0") int page,
        @RequestParam(defaultValue = "10") int size
    ) {
        Pageable pageable = PageRequest.of(page, size);
        Page<StaffUser> users = staffUserService.findAll(userSearch.buildSpecification(), pageable);
        return ResponseEntity.ok(users);
    }

    @GetMapping("/{userId}")
    @Secured("ROLE_MANAGE_USER")
    public ResponseEntity<StaffUser> getUser(@PathVariable String userId) {
        StaffUser user = staffUserService.findById(userId);
        return ResponseEntity.ok(user);
    }

    @PostMapping
    @Secured("ROLE_MANAGE_USER")
    public ResponseEntity<StaffUser> createUser(@RequestBody @Valid UserRegisterDTO userDTO) {
        StaffUser newUser = staffUserMapper.map(userDTO);
        StaffUser created = staffUserService.create(newUser);
        return ResponseEntity.ok(created);
    }

    @PostMapping("/update/{userId}")
    @Secured("ROLE_MANAGE_USER")
    public ResponseEntity<StaffUser> updateUser(
        @PathVariable String userId,
        @RequestBody @Valid UserUpdateDTO userDTO
    ) {
        StaffUser updatedUser = staffUserMapper.map(userDTO);
        StaffUser result = staffUserService.update(userId, updatedUser);
        return ResponseEntity.ok(result);
    }

    @PostMapping("/delete")
    @Secured("ROLE_MANAGE_USER")
    public ResponseEntity<Void> deleteUsers(@RequestBody List<String> userIds) {
        String currentUserId = SecurityUtil.getCurrentUserEsntlId();
        userIds.stream()
            .filter(id -> !currentUserId.equals(id)) // Exclude current user from deletion
            .forEach(staffUserService::deleteById);
        return ResponseEntity.ok().build();
    }

    @PostMapping("/reset-password/{userId}/")
    @Secured("ROLE_MANAGE_USER")
    public ResponseEntity<Void> resetPassword(
        @PathVariable String userId,
        @RequestBody @Valid StaffPasswordChangeRequestDTO passwordDTO
    ) {
        staffUserService.updatePassword(userId, passwordDTO.getNewPassword());
        return ResponseEntity.ok().build();
    }
}
