package incheon.uis.ums.service.impl;

import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import incheon.ags.ias.comCd.vo.ComCdVO;
import incheon.com.cmm.context.RequestContext;
import incheon.com.security.util.SecurityUtil;
import incheon.com.security.vo.LoginVO;
import incheon.com.security.vo.UserRoleVO;
import incheon.uis.ums.mapper.UisComCdMapper;
import incheon.uis.ums.mapper.UisTaskLyrMapper;
import incheon.uis.ums.service.UisAccessService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor
public class UisAccessServiceImpl implements UisAccessService{

    private final UisComCdMapper uisComCdMapper;
    private final UisTaskLyrMapper uisTaskLyrMapper;
    private static final String DATA_PREFIX = "PERM_DATA_";
    private static final String FUNC_PREFIX = "PERM_FUNC_";
    private static final String ROLE_SUPER_ADMIN = "ROLE_SUPER_ADMIN";
    private static final String ROLE_UIS_ADMIN = "ROLE_UIS_ADMIN";
    private static final String FUNC_EDIT = "EDIT";
    private static final String FUNC_EXPORT = "EXPORT";
    private static final String UIS_SYS_CD = "UIS"; //UIS 도시기반시설 관리시스템

    @Value("${uis.editable.categories:urf,ugf,usf,uef}")
    private List<String> uisEditableCategories;
    
    @Override
    public List<ComCdVO> getAccessibleRootGroupList() {
        return uisComCdMapper.getUisRootComCdList().stream()
                 .filter(cd -> hasAuthrtAccessByGroupCd(cd.getCd()))
                 .collect(Collectors.toList());
    }

    @Override
    public boolean hasAuthrtAccessByGroupCd(String groupCd) {
        if(groupCd == null) return false;
        if(SecurityUtil.hasRole("UIS", "ROLE_SUPER_ADMIN")) return true;  //슈퍼어드민
        return SecurityUtil.hasPermission("UIS", DATA_PREFIX + groupCd.toUpperCase(Locale.ROOT));
        /* 2025-12-16 Jae-ryong Lee : SecurityUtil 기준으로 변경함
        final LoginVO loginVO = RequestContext.getCurrentUser();
        if (loginVO == null) return false;
        if (isSuperAdmin(loginVO)) return true;
        return loginVO.hasAuthrt(UIS_SYS_CD, DATA_PREFIX + groupCd.toUpperCase(Locale.ROOT));
         */
    }

    @Override
    public boolean hasAuthrtAccessByTypeId(String typeId) {
        if(typeId == null) return false;
        return hasAuthrtAccessByGroupCd(getGroupCdByTypeId(typeId));
    }

    @Override
    public boolean hasExportAccess() {
        return hasFuncAccess(FUNC_EXPORT);
    }

    @Override
    public boolean hasEditAccess() {
        return hasFuncAccess(FUNC_EDIT);
    }

    @Override
    public boolean hasEditAccessByTypeId(String typeId) {
        final LoginVO loginVO = RequestContext.getCurrentUser();
        if (loginVO == null) return false;
        if (isSuperAdmin(loginVO)) return true;
        //권한체크(카테고리 + 수정 권한)
        return hasAuthrtAccessByTypeId(typeId) && hasEditAccess();
    }

    // 기능 권한 체크
    private boolean hasFuncAccess(String funcType) {
        final LoginVO loginVO = RequestContext.getCurrentUser();
        if (loginVO == null) return false;
        if (isSuperAdmin(loginVO)) return true;
        return loginVO.hasAuthrt(UIS_SYS_CD, FUNC_PREFIX + funcType);
    }

    
    @Override
    public boolean hasEditAbleByTypeId(String typeId) {
        if(typeId == null) return false;
        return uisEditableCategories.contains(getGroupCdByTypeId(typeId));
    }

    //대장/시설물 상관 없이 테이블의 groupCd 추출
    private String getGroupCdByTypeId(String typeId) {
        String categoryCd = null;
        int prefixIndex  = typeId.indexOf(":");
        if(prefixIndex == -1) {
            //시설물인 경우
            categoryCd =  uisTaskLyrMapper.getLyrGroupCdByTableNm(typeId);
        }else {
            //대장인 경우
            categoryCd = typeId.substring(0,typeId.indexOf(":"));
        }
        return categoryCd;
    }

    //통합 관리자(SUPER_ADMIN) 여부 확인
    @Override
    public boolean isSuperAdmin(LoginVO loginVO) {
        if(loginVO == null) return false;
        boolean isSuperAdmin = false;
        List<UserRoleVO> roles = loginVO.getUserRoles();
        for(UserRoleVO role : roles) {
           if(ROLE_SUPER_ADMIN.equals(role.getRoleCd())) {
               isSuperAdmin = true;
           }
        }
        return isSuperAdmin;
    }

    //UIS 도시기반시설 관리시스템 관리자(ROLE_UIS_ADMIN) 여부 확인
    @Override
    public boolean isUisAdmin(LoginVO loginVO) {
        if(loginVO == null) return false;
        boolean isUisAdmin = false;
        List<UserRoleVO> roles = loginVO.getUserRoles();
        for(UserRoleVO role : roles) {
           if(ROLE_UIS_ADMIN.equals(role.getRoleCd())) {
        	   isUisAdmin = true;
           }
        }
        return isUisAdmin;
    }
}
