package incheon.ags.ias.menu.service.impl;

import incheon.ags.ias.menu.mapper.MenuMapper;
import incheon.ags.ias.menu.service.MenuService;
import incheon.ags.ias.menu.vo.MenuSearchVO;
import incheon.ags.ias.menu.vo.MenuVO;
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 java.util.List;
import java.util.Map;

@Slf4j
@Service("menuService")
@RequiredArgsConstructor
public class MenuServiceImpl extends EgovAbstractServiceImpl implements MenuService {
    private final MenuMapper menuMapper;

    @Override
    public List<Map<String, Object>> selectMenuList(MenuSearchVO menuVO) throws Exception {
        log.debug("메뉴 목록 조회 요청 - 검색조건: {}", menuVO);
        List<Map<String, Object>> result = menuMapper.selectMenuList(menuVO);
        log.debug("메뉴 목록 조회 완료 - 조회건수: {}", result.size());
        return result;
    }

    @Override
    public List<Map<String, Object>> selectMenuListFromSysCd(String sysCd) throws Exception {
        log.debug("시스템코드별 메뉴 목록 조회 요청 - sysCd: {}", sysCd);
        return menuMapper.selectMenuListFromSysCd(sysCd);
    }

    @Override
    public List<Map<String, Object>> selectSysList() throws Exception {
        log.debug("시스템 목록 조회 요청");
        return menuMapper.selectSysInfoList();
    }

    @Override
    public int selectMenuListCnt(MenuSearchVO menuSearchVO) throws Exception {
        log.debug("메뉴 목록 총 개수 조회 요청");
        return menuMapper.selectMenuListCnt(menuSearchVO);
    }

    @Override
    public List<Map<String, Object>> selectSubmenuList(MenuVO menuVO) throws Exception {
        log.debug("하위 메뉴 목록 조회 요청 - 상위메뉴코드: {}", menuVO.getUpMenuCd());
        return menuMapper.selectSubmenuList(menuVO);
    }

    @Override
    public MenuVO selectMenuDetail(MenuVO menuVO) throws  Exception {
        log.debug("메뉴 상세 조회 요청 - 메뉴코드: {}", menuVO.getMenuCd());
        MenuVO result = menuMapper.selectMenuDetail(menuVO);
        if (result == null) {
            log.warn("메뉴 상세 조회 실패 - 메뉴를 찾을 수 없음: {}", menuVO.getMenuCd());
        }
        return result;
    }

    @Override
    @Transactional
    public int insertMenu(MenuVO menuVO) throws Exception {
        log.info("메뉴 등록 요청 - 메뉴코드: {}, 메뉴명: {}", menuVO.getMenuCd(), menuVO.getMenuNm());

        if (menuVO == null || menuVO.getMenuCd() == null) {
            log.error("메뉴 등록 실패 - 필수 파라미터 누락");
            throw new IllegalArgumentException("메뉴 정보가 올바르지 않습니다.");
        }

        // 사용자가 입력한 메뉴 코드를 그대로 사용 (수동 입력)
        int result = menuMapper.insertMenu(menuVO);

        if (result > 0) {
            log.info("메뉴 등록 성공 - 메뉴코드: {}", menuVO.getMenuCd());
        } else {
            log.error("메뉴 등록 실패 - 메뉴코드: {}", menuVO.getMenuCd());
        }

        return result;
    }

    @Override
    @Transactional
    public int updateMenu(MenuVO menuVO) throws Exception {
        log.info("메뉴 수정 요청 - 메뉴코드: {}", menuVO.getMenuCd());

        if (menuVO == null || menuVO.getMenuCd() == null) {
            log.error("메뉴 수정 실패 - 필수 파라미터 누락");
            throw new IllegalArgumentException("메뉴 정보가 올바르지 않습니다.");
        }

        int result = menuMapper.updateMenu(menuVO);

        if (result > 0) {
            log.info("메뉴 수정 성공 - 메뉴코드: {}", menuVO.getMenuCd());
        } else {
            log.warn("메뉴 수정 실패 - 메뉴를 찾을 수 없음: {}", menuVO.getMenuCd());
        }

        return result;
    }

    @Override
    @Transactional
    public int deleteMenu(MenuVO menuVO) throws Exception {
        log.info("메뉴 삭제 요청 - 메뉴코드: {}", menuVO.getMenuCd());

        if (menuVO == null || menuVO.getMenuCd() == null) {
            log.error("메뉴 삭제 실패 - 필수 파라미터 누락");
            throw new IllegalArgumentException("메뉴 코드가 올바르지 않습니다.");
        }

        int result = menuMapper.deleteMenu(menuVO);

        if (result > 0) {
            log.info("메뉴 삭제 성공 - 메뉴코드: {}", menuVO.getMenuCd());
        } else {
            log.warn("메뉴 삭제 실패 - 메뉴를 찾을 수 없음: {}", menuVO.getMenuCd());
        }

        return result;
    }

}