package com.kospo.talk.service.impl;

import com.kospo.talk.model.SmUser;
import com.kospo.talk.model.User;
import com.kospo.talk.payload.UserDto;
import com.kospo.talk.repository.SmUserRepository;
import com.kospo.talk.repository.UserRepository;
import com.kospo.talk.service.UserService;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
    private final UserRepository userRepository;
    private final SmUserRepository smUserRepository;

    @Override
    public UserDetails loadUserByUsername(String sabun) throws UsernameNotFoundException {
        return userRepository.findBySabun(sabun);
    }

    @Override
    @Transactional
    public UserDto findByUserid(String sabun) {
        User user = userRepository.findBySabun(sabun);
        UserDto sendUser = UserDto.builder()
                .gradeCd(user.getGradeCd())
                .gradeNm(user.getGradeNm())
                .ofcePhn(user.getOfcePhn())
                .mblPhn(user.getMblPhn())
                .deptCd(user.getDeptCd())
                .deptNm(user.getDept().getDeptNm())
                .formalNm(user.getDept().getFormalName())
                .ptsnNm(user.getPtsnNm())
                .state(user.getState())
                .roles(user.getRoles())
                .name(user.getName())
                .onlineYn(user.isOnlineYn())
                .sabun(user.getSabun()).build();
        return sendUser;
    }

    @Transactional
    @Override
    public UserDto findSmByUserid(String sabun) {
        UserDto sendUser = null;
        try {
            User user = userRepository.findSmBySabun(sabun);
            List<SmUser> smWorks = smUserRepository.findByIdSabun(sabun);
            sendUser = UserDto.builder()
                    .gradeCd(user.getGradeCd())
                    .gradeNm(user.getGradeNm())
                    .ofcePhn(user.getOfcePhn())
                    .mblPhn(user.getMblPhn())
                    .deptCd(user.getDeptCd())
                    .deptNm(user.getDept().getDeptNm())
                    .formalNm(user.getDept().getFormalName())
                    .ptsnNm(user.getPtsnNm())
                    .state(user.getState())
                    .roles(user.getRoles())
                    .name(user.getName())
                    .stress(user.getStress())
                    .onlineYn(user.isOnlineYn())
                    .works(smWorks.stream().map((sm) -> UserDto.SmWork.builder()
                            .workNm(sm.getWorkNm())
                            .workId(sm.getId().getWorkId()).build()
                    ).toList())
                    .sabun(user.getSabun()).build();
        } catch(NullPointerException e) {
        }

        return sendUser;
    }

    @Transactional
    @Override
    public UserDto findClientByUserid(String sabun) {
        UserDto sendUser = null;
        try {
            User user = userRepository.findClientBySabun(sabun);
            sendUser = UserDto.builder()
                    .gradeCd(user.getGradeCd())
                    .gradeNm(user.getGradeNm())
                    .ofcePhn(user.getOfcePhn())
                    .mblPhn(user.getMblPhn())
                    .deptCd(user.getDeptCd())
                    .deptNm(user.getDept().getDeptNm())
                    .formalNm(user.getDept().getFormalName())
                    .ptsnNm(user.getPtsnNm())
                    .state(user.getState())
                    .roles(user.getRoles())
                    .name(user.getName())
                    .onlineYn(user.isOnlineYn())
                    .sabun(user.getSabun()).build();
        } catch(NullPointerException e) {
        }
        return sendUser;
    }

    @Override
    public void save(User user) {
        User serverUser = userRepository.findBySabun(user.getSabun());
        serverUser.setOnlineYn(user.isOnlineYn());
        userRepository.save(serverUser);
    }

    @Override
    public List<User> findAllSD() {
        return userRepository.findAllSD();
    }

    @Override
    public List<User> findSM(String workId) {
        return userRepository.findSM(workId);
    }
    
    @Override
    public User findByWorkIdAndSabun(String workId, String sabun) {
        return userRepository.findByWorkIdAndSabun(workId, sabun);
    }

    @Override
    public void allOffline() {
        userRepository.allOffline();
    }
}

