package cokr.xit.fims.cmmn.service.bean;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import cokr.xit.base.code.CommonCode;
import cokr.xit.base.code.service.CodeQuery;
import cokr.xit.base.code.service.bean.CodeBean;
import cokr.xit.base.security.Authority;
import cokr.xit.base.security.SecuredUserInfo;
import cokr.xit.fims.FimsConf;
import cokr.xit.fims.base.service.bean.OgdpBean;
import cokr.xit.fims.cmmn.CmmnQuery;
import cokr.xit.fims.cmmn.dao.StngMapper;
import cokr.xit.fims.mngt.service.bean.TaskBean;
import cokr.xit.foundation.UserInfo;
import cokr.xit.foundation.component.AbstractBean;
import cokr.xit.foundation.data.DataObject;

@Component("stngBean")
public class StngBean extends AbstractBean {
	@Resource(name = "codeBean")
	private CodeBean codeBean;
	@Resource(name = "ogdpBean")
	private OgdpBean ogdpBean;
	@Resource(name = "stngMapper")
	private StngMapper stngMapper;
	@Resource(name = "taskBean")
	private TaskBean taskBean;

	/**현재 사용자와 관련된 설정 정보를 조회한다.
	 * @param type 설정 유형
	 * @return
	 */
	public DataObject getStng(String type) {
		if (type.equals("user")) {
			return stngMapper.selectUserStng(currentUser().getId());
		} else if (type.equals("dept")){
			UserInfo userInfo = currentUser();
			if (userInfo.getInstitute().equals("ADMIN00")) {
				return new DataObject();
			}
			ogdpBean.initUserInfo(userInfo);
			return stngMapper.selectDeptStng((String)userInfo.getInfo().get("deptCd"));
		} else if (type.equals("sgg")){
			UserInfo userInfo = currentUser();
			if (userInfo.getInstitute().equals("ADMIN00")) {
				return new DataObject();
			}
			ogdpBean.initUserInfo(userInfo);
			return stngMapper.selectSggStng((String)userInfo.getInfo().get("sggCd"));
		} else {
			return null;
		}
	}

	/**교부 계좌번호를 변경한다.
	 * @param dtbnBankNm 교부 은행명, dtbnActno 교부 계좌번호
	 * @return 저장여부
	 */
	public boolean updateDtbnActno(String dtbnBankNm, String dtbnActno) {
		Map<String, String> params = new HashMap<String, String>();
		UserInfo userInfo = currentUser();
		ogdpBean.initUserInfo(userInfo);
		params.put("mdfr", userInfo.getId());
		params.put("deptCd", (String)userInfo.getInfo().get("deptCd"));
		params.put("dtbnBankNm", dtbnBankNm);
		params.put("dtbnActno", dtbnActno);

		return stngMapper.updateDtbnActno(params) == 1;
	}

	/** userInfo에 사용가능업무, 기본업무를 설정한다.
	 * @param userInfo 사용자정보
	 * @return
	 */
	public void initUserInfo(SecuredUserInfo userInfo) {
		boolean isAdmin = userInfo.isAdmin();

		List<String>
			taskList = codeBean.getCodeList((new CodeQuery()).setGroupIDs("FIM054")).stream() //모든 업무
				.map(item -> item.string("CODE"))
				.toList(),
			taskListForServer = FimsConf.get().getTasks(), //서버에서 사용가능한 업무
			availableTaskList = new ArrayList<String>();   //사용자별 사용가능한 업무

		if ("ADMIN00".equals(userInfo.getInstitute())) { //1.최고관리자
			availableTaskList = taskList;
		} else {
			Map<String, Object> info = userInfo.getInfo();
			if (info == null || isEmpty(info.get("sggCd"))) {
				ogdpBean.initUserInfo(userInfo);
			}

			//사용자의 시군구에서 사용가능한 업무
			List<String> taskListForSgg = taskBean.getTasks((new CmmnQuery()).setSggCd((String)userInfo.getInfo().get("sggCd")).setUseYn("Y"))
					.stream()
					.map(item -> item.string("TASK_SE_CD")).toList();

			if (isAdmin) { //2.시스템관리자
				availableTaskList.addAll(taskListForSgg);
				availableTaskList.addAll(taskListForServer);
			} else {
				List<String> forServerAndSgg = new ArrayList<String>();
				for(String forServer : taskListForServer) {
					for(String forSgg : taskListForSgg) {
						if (forServer.equals(forSgg)) {
							forServerAndSgg.add(forSgg);
						}
					}
				}

				if (userInfo.hasAuthorities("ROLE_TASK_ADMIN")) { //3.업무관리자
					availableTaskList = forServerAndSgg;
				} else { //4.업무사용자,일반사용자
					List<Authority> authorities = userInfo.getAuthorities();
					if (!isEmpty(authorities)) {
						for(String task : forServerAndSgg) {
							for(Authority authority : authorities) {
								String authId = authority.getId();
								if (authId.contains(task)) {
									availableTaskList.add(task);
								}
							}
						}
					}
				}
			}
		}

		availableTaskList = availableTaskList.stream().distinct().toList(); //사용가능한 업무 목록 중복 제거
		userInfo.getInfo().put("taskForUser", availableTaskList); //계정별 사용가능 업무

		//계정별 기본업무
		if (availableTaskList.size() == 1) {
			userInfo.getInfo().put("defaultTask", availableTaskList.get(0));
			return;
		}

		DataObject defaultTaskInfo = stngMapper.selectDefaultTask(userInfo.getId());
		String defaultTask = defaultTaskInfo == null ? "" : blankIfEmpty(defaultTaskInfo.string("TASK_SE_CD"));
		userInfo.getInfo().put("defaultTask", !availableTaskList.contains(defaultTask) ? "" : defaultTask);
	}

	/** 사용자의 기본업무 설정을 저장한다.
	 * @param taskSeCd 업무구분코드
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean saveDefaultTask(String taskSeCd) {
		DataObject info = stngMapper.selectDefaultTask(currentUser().getId());

		Map<String, String> params = new HashMap<String,String>();
		params.put("userId", currentUser().getId());
		params.put("taskSeCd", taskSeCd);

		int affected = 0;
		if (info == null) {
			params.put("rgtr", currentUser().getId());
			affected = stngMapper.insertDefaultTask(params);
		} else {
			params.put("mdfr", currentUser().getId());
			params.put("taskMtchgId",info.string("TASK_MTCHG_ID"));
			affected = stngMapper.updateDefaultTask(params);
		}

		return affected == 1;
	}

	/** 업무구분코드 목록 중에서 현재 로그인한 사용자의 시군구에서 사용하는 업무구분코드 목록만 반환한다.
	 * @param taskSectionCodes 업무구분코드 목록
	 * @return 현재 로그인한 사용자의 시군구에서 사용하는 업무구분코드 목록
	 */
	public List<CommonCode> filterTaskSectionCodeForSgg(List<CommonCode> taskSectionCodes) {
		if ("ADMIN00".equals(currentUser().getInstitute())) {
			return taskSectionCodes;
		} else {
			SecuredUserInfo userInfo = currentUser();
			Map<String, Object> info = userInfo.getInfo();
			if (info == null || isEmpty(info.get("sggCd")))
				ogdpBean.initUserInfo(userInfo);

			List<String> taskSeCdListForSgg = taskBean.getTasks((new CmmnQuery()).setSggCd((String)userInfo.getInfo().get("sggCd")).setUseYn("Y")).stream()
				.map(item -> item.string("TASK_SE_CD"))
				.toList();

			return taskSectionCodes.stream()
				.filter(item -> taskSeCdListForSgg.contains(item.getCode()))
				.toList();
		}
	}
}