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

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

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import cokr.xit.base.user.DepartmentQuery;
import cokr.xit.base.user.SigunguQuery;
import cokr.xit.base.user.dao.UserMapper;
import cokr.xit.base.user.service.bean.DepartmentBean;
import cokr.xit.base.user.service.bean.SigunguBean;
import cokr.xit.fims.base.FimsDepartment;
import cokr.xit.fims.base.FimsSigungu;
import cokr.xit.fims.base.OgdpQuery;
import cokr.xit.fims.base.dao.OgdpMapper;
import cokr.xit.foundation.UserInfo;
import cokr.xit.foundation.component.AbstractBean;
import cokr.xit.foundation.data.DataObject;

@Component("ogdpBean")
public class OgdpBean extends AbstractBean {
	@Resource(name="sigunguBean")
	private SigunguBean sigunguBean;
	@Resource(name="departmentBean")
	private DepartmentBean departmentBean;
	@Resource(name="ogdpMapper")
	private OgdpMapper ogdpMapper;
	@Resource(name="userMapper")
	private UserMapper userMapper;

	public Object selectAllOgdpList() {
		List<DataObject> ogdpList = new ArrayList<>();
		List<DataObject> sggs = sigunguBean.getSigunguList(new SigunguQuery());

		for (DataObject sgg : sggs) {
			DataObject noDept = sgg.clone()
				.set("DEPT_CD", "EMPTY00")
				.set("DEPT_NM", "(부서 없음)");
			ogdpList.add(noDept);

			List<DataObject> depts = departmentBean.getDepartmentList(new DepartmentQuery().setSggID(sgg.string("SGG_CD")));
			for (DataObject dept : depts)
				ogdpList.add(dept.clone());
		}

		ogdpList.add(new DataObject()
			.set("SGG_CD", "ADMIN")
			.set("SGG_NM", "관리자 시군구")
			.set("INST_CD", "ADMIN00")
			.set("INST_NM", "관리자 기관")
			.set("DEPT_CD", "ADMIN00")
			.set("DEPT_NM", "관리자 부서")
		);

		ogdpOutput(ogdpList);
		return ogdpList;
	}

	public List<DataObject> selectAbleOgdpList(boolean anonymous, String sggCd) {
		List<DataObject> ogdpList = new ArrayList<>();
		SigunguQuery sggQuery = new SigunguQuery();
		if (anonymous) {
			sggQuery.setSggIDs(sggCd);
		} else if (!currentUser().getInstitute().equals("ADMIN00")){
			sggQuery.setSggIDs(currentUser().getOrgID());
		}
		List<DataObject> sggs = sigunguBean.getSigunguList(sggQuery);
		for (DataObject sgg : sggs) {
			DataObject noDept = sgg.clone()
				.set("DEPT_CD", "EMPTY00")
				.set("DEPT_NM", "(부서 없음)");
			ogdpList.add(noDept);

			List<DataObject> depts = departmentBean.getDepartmentList(new DepartmentQuery().setSggID(sgg.string("SGG_CD")));
			for (DataObject dept : depts) {
				DataObject ogdp = sgg.clone()
					.set("DEPT_CD", dept.string("DEPT_CD"))
					.set("DEPT_NM", dept.string("DEPT_NM"));
				ogdpList.add(ogdp);
			}
		}

		if (!anonymous && "ADMIN00".equals(currentUser().getInstitute())) {
			ogdpList.add(new DataObject()
				.set("SGG_CD", "ADMIN")
				.set("SGG_NM", "관리자 시군구")
				.set("INST_CD", "ADMIN00")
				.set("INST_NM", "관리자 기관")
				.set("DEPT_CD", "ADMIN00")
				.set("DEPT_NM", "관리자 부서")
			);
		}

		ogdpOutput(ogdpList);
		return ogdpList;
	}

	private void ogdpOutput(List<DataObject> list) {
		list.forEach(one ->
			one.set("OGDP_CD", one.get("SGG_CD")+"/"+one.get("INST_CD") + ":" + one.get("DEPT_CD"))
			   .set("OGDP_NM", one.get("SGG_NM") + " / " + one.get("INST_NM") + " : " + one.get("DEPT_NM"))
		);
	}

	public int countUser(String sggCd) {
		return ogdpMapper.countUser(sggCd);
	}

	/**userInfo 객체에 해당 사용자가 소속된 시군구,기관,부서 정보를 저장한다.
	 * @param userInfo 사용자 정보
	 * @return
	 */
	public void initUserInfo(UserInfo userInfo) {
		DataObject ogdpInfo = userMapper.getUserInfo(userInfo.getId());

		boolean empty = ogdpInfo == null;
		Map<String, Object> infoMap = userInfo.getInfo();

		infoMap.put("sggCd", !empty ? ogdpInfo.string("SGG_CD") : "");
		infoMap.put("sggNm", !empty ? ogdpInfo.string("SGG_NM") : "");
		infoMap.put("instCd", !empty ? ogdpInfo.string("INST_CD") : "");
		infoMap.put("instNm", !empty ? ogdpInfo.string("INST_NM") : "");
		infoMap.put("deptCd", !empty ? ogdpInfo.string("DEPT_CD") : "");
		infoMap.put("deptNm", !empty ? ogdpInfo.string("DEPT_NM") : "");

		userInfo.setInfo(infoMap);
	}

	/**시군구 정보를 수정한다.
	 * @param sgg 시군구
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean updateSggStng(FimsSigungu sgg) {
		return ogdpMapper.updateSggStng(sgg);
	}

	/**지정한 조건에 따라 시군구 객체를 반환한다.
	 * @param req 시군구 조회 조건
	 * @return 시군구 객체
	 */
	public DataObject getSggStngInfo(OgdpQuery req) {
		return ogdpMapper.selectSggStngInfo(req);
	}

	public List<DataObject> getDeptStngList(OgdpQuery query) {
		// 기본 정렬
		if (query.getOrderBy() == null) {
			if (query.getFetchSize() > 0) {
				query.setOrderBy("QBODY.DEPT_CD DESC");
			} else {
				query.setOrderBy("D.DEPT_CD DESC");
			}
		}
		return ogdpMapper.selectDeptStngList(query);
	}

	public DataObject getDeptStngInfo(OgdpQuery query) {
		return ogdpMapper.selectDeptStngInfo(query);
	}

	public boolean updateDeptStng(FimsDepartment dept) {
		return dept != null
			&& ogdpMapper.updateDeptStng(new DataObject()
			.set("currentUser", currentUser())
			.set("dept", dept)
		) == 1;
	}
}