package go.kr.project.mypage.service.impl;

import egovframework.constant.SessionConstants;
import egovframework.exception.MessageException;
import egovframework.util.EgovFileScrty;
import go.kr.project.login.model.LoginUserVO;
import go.kr.project.login.model.SessionVO;
import go.kr.project.mypage.service.MypageService;
import go.kr.project.system.user.mapper.UserMapper;
import go.kr.project.system.user.model.SystemUserVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * packageName    : go.kr.project.mypage.service.impl
 * fileName       : MypageServiceImpl
 * author         : 시스템 관리자
 * date           : 2025-05-20
 * description    : 마이페이지 관련 서비스 구현 클래스
 * ===========================================================
 * DATE              AUTHOR             NOTE
 * -----------------------------------------------------------
 * 2025-05-20        시스템 관리자       최초 생성
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MypageServiceImpl extends EgovAbstractServiceImpl implements MypageService {

    private final UserMapper userMapper;

    /**
     * 현재 로그인한 사용자 정보 조회
     *
     * @param request HTTP 요청 객체
     * @return 사용자 정보
     */
    @Override
    public SystemUserVO getUserInfo(HttpServletRequest request) {
        // 세션에서 사용자 정보 가져오기
        HttpSession session = request.getSession(false);
        SessionVO sessionVO = (SessionVO) session.getAttribute(SessionConstants.SESSION_KEY);
        LoginUserVO loginUser = sessionVO.getUser();

        // 사용자 정보 조회
        return userMapper.selectUser(loginUser.getUserId());
    }

    /**
     * 사용자 정보 수정
     * @param user 사용자 정보
     * @param request HTTP 요청 객체
     * @return 수정 성공 여부
     * @throws Exception 예외 발생 시
     */
    @Override
    @Transactional
    public boolean updateUserInfo(SystemUserVO user, HttpServletRequest request) {
        // 세션에서 사용자 정보 가져오기
        HttpSession session = request.getSession(false);
        SessionVO sessionVO = (SessionVO) session.getAttribute(SessionConstants.SESSION_KEY);
        LoginUserVO loginUser = sessionVO.getUser();

        // 현재 로그인한 사용자의 ID로 설정
        user.setUserId(loginUser.getUserId());
        user.setMdfr(loginUser.getUserId());

        // 사용자 정보 수정
        int result = userMapper.updateUser(user);

        // 세션 정보 업데이트
        if (result > 0) {
            // 수정된 사용자 정보 조회
            SystemUserVO updatedUser = userMapper.selectUser(loginUser.getUserId());

            // 세션의 사용자 정보 업데이트
            loginUser.setUserNm(updatedUser.getUserNm());
            loginUser.setEmpNo(updatedUser.getEmpNo());
            loginUser.setGender(updatedUser.getGender());
            loginUser.setZip(updatedUser.getZip());
            loginUser.setAddr(updatedUser.getAddr());
            loginUser.setDaddr(updatedUser.getDaddr());
            loginUser.setAreaNo(updatedUser.getAreaNo());
            loginUser.setEmlAddr(updatedUser.getEmlAddr());
            loginUser.setFxno(updatedUser.getFxno());
            loginUser.setTelno(updatedUser.getTelno());
            loginUser.setMblTelno(updatedUser.getMblTelno());
            loginUser.setBrdt(updatedUser.getBrdt());

            sessionVO.setUser(loginUser);
            session.setAttribute(SessionConstants.SESSION_KEY, sessionVO);

            return true;
        }

        return false;
    }

    /**
     * 비밀번호 확인
     * @param user 사용자 정보 (userId, currentPasswd 필요)
     * @return 비밀번호 일치 여부
     * @throws Exception 예외 발생 시
     */
    @Override
    public boolean checkPassword(SystemUserVO user) {
        // 비밀번호 암호화
        String encryptedPassword;
        try {
            encryptedPassword = EgovFileScrty.encryptPassword(user.getCurrentPasswd(), user.getUserId());
        } catch (Exception e) {
            throw new RuntimeException("비밀번호 암호화 중 오류가 발생했습니다.", e);
        }

        // 암호화된 비밀번호로 설정
        user.setPasswd(encryptedPassword);

        // 비밀번호 확인
        int result = userMapper.checkPassword(user);

        return result > 0;
    }

    /**
     * 비밀번호 변경
     * @param user 사용자 정보 (userId, currentPasswd, newPasswd, confirmPasswd 필요)
     * @param request HTTP 요청 객체
     * @return 변경 성공 여부
     * @throws Exception 예외 발생 시
     */
    @Override
    @Transactional
    public boolean updatePassword(SystemUserVO user, HttpServletRequest request) {
        // 세션에서 사용자 정보 가져오기
        HttpSession session = request.getSession(false);
        SessionVO sessionVO = (SessionVO) session.getAttribute(SessionConstants.SESSION_KEY);
        LoginUserVO loginUser = sessionVO.getUser();

        // 현재 로그인한 사용자의 ID로 설정
        user.setUserId(loginUser.getUserId());

        // 현재 비밀번호 확인
        if (!checkPassword(user)) {
            throw new MessageException("현재 비밀번호가 일치하지 않습니다.");
        }

        // 새 비밀번호와 확인 비밀번호 일치 여부 확인
        if (!user.getNewPasswd().equals(user.getConfirmPasswd())) {
            throw new MessageException("새 비밀번호와 확인 비밀번호가 일치하지 않습니다.");
        }

        // 새 비밀번호 암호화
        String encryptedPassword;
        try {
            encryptedPassword = EgovFileScrty.encryptPassword(user.getNewPasswd(), user.getUserId());
        } catch (Exception e) {
            throw new RuntimeException("새 비밀번호 암호화 중 오류가 발생했습니다.", e);
        }

        // 암호화된 비밀번호로 설정
        user.setPasswd(encryptedPassword);
        user.setPasswdInitYn("N");

        // 비밀번호 변경
        int result = userMapper.updatePassword(user);

        // 세션 정보 업데이트
        if (result > 0) {
            // 세션의 사용자 정보 업데이트
            loginUser.setPasswd(encryptedPassword);
            loginUser.setPasswdInitYn("N");
            sessionVO.setUser(loginUser);
            session.setAttribute(SessionConstants.SESSION_KEY, sessionVO);

            return true;
        }

        return false;
    }
}
