package com.avitam.bankloanapplication.web.controllers;

import com.avitam.bankloanapplication.core.service.CoreService;
import com.avitam.bankloanapplication.core.service.UserService;
import com.avitam.bankloanapplication.model.dto.CustomerDto;
import com.avitam.bankloanapplication.model.dto.SearchDto;
import com.avitam.bankloanapplication.model.dto.UserDto;
import com.avitam.bankloanapplication.model.dto.UserWsDto;
import com.avitam.bankloanapplication.model.entity.User;
import com.avitam.bankloanapplication.repository.CustomerRepository;
import com.avitam.bankloanapplication.repository.RoleRepository;
import com.avitam.bankloanapplication.repository.UserRepository;
import org.apache.commons.collections4.CollectionUtils;
import org.modelmapper.ModelMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
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.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/admin/user")
public class AdminController extends BaseController {

    public static final String ADMIN_USER = "/admin/user";
    Logger logger = LoggerFactory.getLogger(AdminController.class);
    @Autowired
    private CoreService coreService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    private CustomerRepository customerRepository;
    @Autowired
    private ModelMapper modelMapper;

    @PostMapping
    @ResponseBody
    public UserWsDto getAllUsers(@RequestBody UserWsDto userWsDto) {
        Pageable pageable = getPageable(userWsDto.getPage(), userWsDto.getSizePerPage(), userWsDto.getSortDirection(), userWsDto.getSortField());
        UserDto userDto = CollectionUtils.isNotEmpty(userWsDto.getUserDtoList()) ? userWsDto.getUserDtoList().get(0) : new UserDto();
        User user = modelMapper.map(userDto, User.class);
        Page<User> page = isSearchActive(user) != null ? userRepository.findAll(Example.of(user), pageable) : userRepository.findAll(pageable);
        Type listType = new org.modelmapper.TypeToken<List<UserDto>>() {
        }.getType();
        userWsDto.setUserDtoList(modelMapper.map(page.getContent(), listType));
        userWsDto.setBaseUrl(ADMIN_USER);
        userWsDto.setTotalPages(page.getTotalPages());
        userWsDto.setTotalRecords(page.getTotalElements());
        return userWsDto;
    }

    @GetMapping("/get")
    @ResponseBody
    public UserWsDto getUser(@RequestBody UserWsDto request) {
        UserWsDto userWsDto = new UserWsDto();
        List<User> users = new ArrayList<>();
        for (UserDto userDto : request.getUserDtoList()) {
            users.add(userRepository.findByRecordId(userDto.getRecordId()));
        }
        Type listType = new org.modelmapper.TypeToken<List<CustomerDto>>() {
        }.getType();
        userWsDto.setUserDtoList(modelMapper.map(users, listType));
        userWsDto.setBaseUrl(ADMIN_USER);

        return userWsDto;
    }

    /*@PostMapping("/getedit")
    @ResponseBody
    public CustomerWsDto editLoanApplication(@RequestBody CustomerWsDto request) {
        CustomerWsDto customerWsDto = new CustomerWsDto();
        List<Customer> customers=new ArrayList<>();
        for(CustomerDto customerDto:request.getCustomerDtoList()) {
            customers.add(customerRepository.findByRecordId(customerDto.getRecordId()));
        }
        Type listType = new org.modelmapper.TypeToken<List<CustomerDto>>() {}.getType();
        customerWsDto.setCustomerDtoList(modelMapper.map(customers,listType));
        customerWsDto.setBaseUrl(ADMIN_USER);
        return customerWsDto;
    }*/

    @PostMapping("/getedit")
    @ResponseBody
    public UserWsDto editUser(@RequestBody UserWsDto request) {
        UserWsDto userWsDto = new UserWsDto();
        List<User> users = new ArrayList<>();
        for (UserDto userDto : request.getUserDtoList()) {
            users.add(userRepository.findByRecordId(userDto.getRecordId()));
        }
        Type listType = new org.modelmapper.TypeToken<List<UserDto>>() {
        }.getType();
        userWsDto.setUserDtoList(modelMapper.map(users, listType));
        userWsDto.setBaseUrl(ADMIN_USER);
        return userWsDto;
    }


    @PostMapping("/edit")
    @ResponseBody
    public UserDto save(@RequestBody UserDto request) {
        return userService.save(request);
        //return request;
    }

    @PostMapping("/delete")
    @ResponseBody
    public UserWsDto deleteUser(@RequestBody UserWsDto userWsDto) {

        for (UserDto userDto : userWsDto.getUserDtoList()) {
            userRepository.deleteByRecordId(userDto.getRecordId());
        }
        userWsDto.setBaseUrl(ADMIN_USER);
        userWsDto.setMessage("Data Deleted Successfully");
        return userWsDto;
    }


    @PostMapping("/getAdminProfile")
    @ResponseBody
    public UserDto getUser(@RequestBody UserDto userDto) {
        User user = userRepository.findByEmail(userDto.getEmail());
        if (user == null) {
            throw new RuntimeException("User not found with email: " + userDto.getEmail());
        }
        UserDto userDto1 = modelMapper.map(user, UserDto.class);
        return userDto1;
    }


    @PostMapping("/setNotificationIdForAdmin")
    public ResponseEntity<?> setNotificationIdForAdmin(@RequestParam String userId, @RequestParam String notificationId) {
        User user = userRepository.findByRecordId(userId);
        if (user == null) {
            return ResponseEntity.notFound().build();
        }
        user.setNotificationId(notificationId);
        userRepository.save(user);
        return ResponseEntity.ok("Notification ID saved successfully");
    }


    @GetMapping("/getAdvanceSearch")
    @ResponseBody
    public List<SearchDto> getSearchAttributes() {
        return getGroupedParentAndChildAttributes(new User());
    }


}
