package com.example.kafka.controller;

import com.example.kafka.entity.Department;
import com.example.kafka.entity.User;
import com.example.kafka.entity.UserResponse;
import com.example.kafka.service.DepartmentServiceImpl;
import com.example.kafka.service.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("v1/department")
public class DepartmentController {
    @Autowired
    private DepartmentServiceImpl departmentService;

    @Autowired
    private UserServiceImpl userService;

    /**
     * Create user
     * @param department The user
     * @return The mono of User
     */
    @PostMapping("/create")
    @ResponseStatus(HttpStatus.ACCEPTED)
    public Mono<Department> createDepartment(@RequestBody Department department){
        return departmentService.createDepartment(department);
    }

    /**
     * Display all users data
     * @return The Flux of user
     */
    @GetMapping("/all")
    public Flux<Department> getAllDepartments(){
        return departmentService.getAllDepartment();
    }

    /**
     * Fetch particular user by user id
     * @param departmentId The userId
     * @return ResponseEntity of user
     */
    @GetMapping("/{departmentId}")
    public Mono<ResponseEntity<Department>> getDepartmentById(@PathVariable String departmentId){
        Mono<Department> department = departmentService.findById(departmentId);
        return department.map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.notFound().build());
    }

    /**
     * Update the user data
     * @param departmentID The userId
     * @param department The user data
     * @return ResponseEntity of user
     */
    @PutMapping("/{departmentID}")
    public Mono<ResponseEntity<Department>> updateDepartmentById(@PathVariable String departmentID, @RequestBody Department department){
        return departmentService.updateDepartment(departmentID,department)
                .map(ResponseEntity::ok)
                .defaultIfEmpty(ResponseEntity.badRequest().build());
    }

    @GetMapping("/fetchAll/{departmentId}")
    public Mono<UserResponse> getMonoDepartmentAndUsersById(@PathVariable String departmentId){
        Mono<Department> department = departmentService.findById(departmentId);
        return department.flatMap(d-> userService.fetchUserByDepartmentName(d.getName()).collectList().map(users->{
            UserResponse userResponse = new UserResponse();
            userResponse.setUserList(users);
            return userResponse;
        }));
    }

    @GetMapping("/fetchAll")
    public Flux<UserResponse> getFluxDepartmentAndUsersById(@RequestParam(value = "departmentId") String departmentId){
        Mono<Department> department = departmentService.findById(departmentId);
        return department.flatMapMany(d-> userService.fetchUserByDepartmentName(d.getName()).map(user -> {
            UserResponse userResponse = new UserResponse();
            userResponse.setUser(user);
            return userResponse;
        }));
    }

}


