package com.eactive.eai.rms.common.acl.user;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import com.eactive.eai.rms.common.acl.user.mapper.UserBizUIMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.eactive.eai.data.entity.onl.unifbwk.UnifBwkTp;
import com.eactive.eai.rms.common.acl.user.ui.AdminLoginVo;
import com.eactive.eai.rms.common.acl.user.ui.UserBizUI;
import com.eactive.eai.rms.common.base.BaseService;
import com.eactive.eai.rms.common.util.CommonConstants;
import com.eactive.eai.rms.data.entity.onl.bzwkdstcd.UserBusiness;
import com.eactive.eai.rms.data.entity.onl.bzwkdstcd.UserBusinessId;
import com.eactive.eai.rms.data.entity.onl.bzwkdstcd.UserBusinessService;
import com.eactive.eai.rms.data.entity.onl.unifbwk.UnifBwkTpService;

@Service
@Transactional
public class BizManService extends BaseService {
	
	private static final String ADMIN_ROLE = "admin";
    private static final String DEFAULT_SAVE_TYPE = "R";

	@Autowired
	private BizDao dao;
	
	@Autowired
	private UnifBwkTpService unifBwkTpService;

	@Autowired
	private UserBusinessService userBusinessService;

	@Autowired
	private UserBizUIMapper userBizUIMapper;
	
	@Autowired
	private UserManService userManService;

	public List<UserBizUI> selectUserBizList(UserBizUI requestUserBizUI) {
		Iterable<UnifBwkTp> unifBwkTps = unifBwkTpService.findAllwithSearch(requestUserBizUI.getSearchBzwkName());
		List<UnifBwkTp> unifBwkTpList = new ArrayList<>();
		unifBwkTps.forEach(unifBwkTpList::add);
		
		return unifBwkTpList.stream()
									.map(mapToUserBizUi(requestUserBizUI))
									.filter(predicate(requestUserBizUI.getTargetGridYn()))
									.collect(Collectors.toList());
	}

	private Predicate<UserBizUI> predicate(String targetGridYn) {
		return userBizUI -> {
			if ("Y".equalsIgnoreCase(targetGridYn)) {
				return "true".equals(userBizUI.getChk());
			} else {
				return "false".equalsIgnoreCase(userBizUI.getChk());
			}
		};
	}

	private Function<UnifBwkTp, UserBizUI> mapToUserBizUi(UserBizUI ui) {
		return unifBwkTp -> {
			Optional<UserBusiness> userBusinessOptional = 
					userBusinessService.findById(new UserBusinessId(ui.getUserId(), unifBwkTp.getEaibzwkdstcd()));

			UserBizUI userBizUI = userBizUIMapper.toVo(unifBwkTp);
			userBizUI.setUserId(ui.getUserId());
			userBizUI.setTargetGridYn(ui.getTargetGridYn());

			if (userBusinessOptional.isPresent()) {
				userBizUI.setChk("true");
				userBizUI.setSaveType(userBusinessOptional.get().getSaveType());
				
			} else {
				userBizUI.setChk("false");
			}

			return userBizUI;
		};
	}

	public void transactionUserBiz(String userId, List<UserBizUI> userBizUIs, AdminLoginVo adminLoginVo) {
		
		List<UserBusiness> userBusinesses = userBizUIs.stream()
				.filter(ui -> "true".equals(ui.getChk()))
				.map(ui -> {
					ui.setUserId(userId);
					UserBusiness userBusiness = userBizUIMapper.toEntity(ui);
					UserBusinessId id = new UserBusinessId(userId, ui.getBizCode());
					userBusiness.setId(id);
					return userBusiness;
				}).collect(Collectors.toList());
		
		userBusinessService.deleteOrSave(userId, userBusinesses);
		
		String userBusinessServiceLists = userBusinesses.stream()
				.map(e -> e.getId().getEaiBzwkDstcd())
				.collect(Collectors.joining(","));
		
		userManService.insertUserAthrRoleChgHistory(userId, CommonConstants.CHANGE_TYPE_ATHR, 
				userBusinessServiceLists, adminLoginVo.getLoginId(), adminLoginVo.getLoginIp());
	}

	public List<Map<String, Object>> selectBizList() {
		return unifBwkTpService.findAll().stream()
				.map(e -> {
					Map<String, Object> map = new HashMap<>();
					map.put("BIZCODE", e.getEaibzwkdstcd());
					map.put("BIZNAME", e.getBzwkdsticname());
					map.put("BIZDESC", e.getBzwkdsticdesc());
					return map;
				}).collect(Collectors.toList());
	}

	public void insertUserBiz(UserBizUI userBizUI, String saveType) {
		UserBusiness userBusiness = userBizUIMapper.toEntity(userBizUI);
		userBusiness.setSaveType(saveType);
		userBusinessService.save(userBusiness);	
	}

	public String selectGroupCoCdByEAIBzwkDstCd(String eaiBzwkDstCd) {
		return unifBwkTpService.getById(eaiBzwkDstCd).getGroupcocd();
	}

	/*
	 * 사용자 의 계정 및 서비스에 해당하는 업무코드 리스트를 리턴한다.
	 */
	public List<HashMap<String, Object>> selectUserBizCodes(String userId) {
		HashMap<String, Object> map = new HashMap<>();
		map.put("userId", userId);
		return dao.selectUserBizCodes(map);
	}
	
	/*
	 *  업무코드 추가 시 Admin 계정 권한 추가
	 */
	public void transactionAdminBiz(String bzwkDstCd) {
		
		List<Map<String, Object>> adminUserList = new ArrayList<>();
		
		try {
			// 모니터링 TSEAIRM02,04 admin 계정 USERID 배열 만들기
			adminUserList = userManService.selectAdminRoleUser(ADMIN_ROLE);
		} catch (Exception e) {
			logger.error("Error retrieving admin user list: ", e);
			return;
		}
		
		for (Map<String, Object> userMap : adminUserList) {
			
			UserBizUI userBizUI = new UserBizUI();
			userBizUI.setUserId(String.valueOf(userMap.get("USERID")));
			userBizUI.setSearchBzwkName("");
			userBizUI.setTargetGridYn("N");
			userBizUI.setBizCode(bzwkDstCd);

			try {
					insertUserBiz(userBizUI, DEFAULT_SAVE_TYPE);
			} catch (Exception e) {
					logger.warn("admin role TSEAIRM06 bizCode insert failed", e);
			}			 					
		}		
	}
	    
}
